diff -Nru qt5-declarative-0.1~git20120402/debian/changelog qt5-declarative-0.1~git20120423/debian/changelog --- qt5-declarative-0.1~git20120402/debian/changelog 2012-04-02 12:51:58.000000000 +0000 +++ qt5-declarative-0.1~git20120423/debian/changelog 2012-04-23 12:15:32.000000000 +0000 @@ -1,3 +1,9 @@ +qt5-declarative (0.1~git20120423) oneiric; urgency=low + + * git snapshot 20120423 + + -- Kate Alhola Mon, 23 Apr 2012 15:15:32 +0300 + qt5-declarative (0.1~git20120402-1) oneiric; urgency=low * new git snapshot diff -Nru qt5-declarative-0.1~git20120402/debian/libqt5-declarative-dev.install qt5-declarative-0.1~git20120423/debian/libqt5-declarative-dev.install --- qt5-declarative-0.1~git20120402/debian/libqt5-declarative-dev.install 2012-04-02 12:20:10.000000000 +0000 +++ qt5-declarative-0.1~git20120423/debian/libqt5-declarative-dev.install 2012-04-23 14:42:33.000000000 +0000 @@ -11,6 +11,8 @@ opt/qt5/lib/libQtQml.prl opt/qt5/lib/libQtQuick.prl opt/qt5/lib/libQtQuick.la +opt/qt5/lib/libQtQuickParticles.prl +opt/qt5/lib/libQtQuickParticles.la opt/qt5/lib/libQtQuickTest.la opt/qt5/lib/libQtQuickTest.prl opt/qt5/lib/libQtQuickTest.so diff -Nru qt5-declarative-0.1~git20120402/debian/libqt5-declarative.install qt5-declarative-0.1~git20120423/debian/libqt5-declarative.install --- qt5-declarative-0.1~git20120402/debian/libqt5-declarative.install 2012-04-02 12:20:10.000000000 +0000 +++ qt5-declarative-0.1~git20120423/debian/libqt5-declarative.install 2012-04-24 07:29:58.000000000 +0000 @@ -1,7 +1,7 @@ opt/qt5/lib/libQtQml.so opt/qt5/lib/libQtQml.so.* #opt/qt5/plugins/qmltooling/libqmldbg*.so -opt/qt5/imports/Qt/labs/folderlistmodel +#opt/qt5/imports/Qt/labs/folderlistmodel #opt/qt5/imports/Qt/labs/shaders #opt/qt5/imports/Qt/labs/gestures #opt/qt5/imports/Qt/labs/particles diff -Nru qt5-declarative-0.1~git20120402/debian/libqt5-quick.install qt5-declarative-0.1~git20120423/debian/libqt5-quick.install --- qt5-declarative-0.1~git20120402/debian/libqt5-quick.install 2012-04-02 12:20:10.000000000 +0000 +++ qt5-declarative-0.1~git20120423/debian/libqt5-quick.install 2012-04-24 07:29:56.000000000 +0000 @@ -1,4 +1,7 @@ opt/qt5/lib/libQtQuick.so opt/qt5/lib/libQtQuick.so.* +opt/qt5/lib/libQtQuickParticles.so +opt/qt5/lib/libQtQuickParticles.so.* opt/qt5/imports/QtQuick opt/qt5/imports/QtQuick.2 +opt/qt5/imports/Qt/labs/folderlistmodel \ No newline at end of file diff -Nru qt5-declarative-0.1~git20120402/doc/src/external-resources.qdoc qt5-declarative-0.1~git20120423/doc/src/external-resources.qdoc --- qt5-declarative-0.1~git20120402/doc/src/external-resources.qdoc 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/doc/src/external-resources.qdoc 1970-01-01 00:00:00.000000000 +0000 @@ -1,32 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:FDL$ -** GNU Free Documentation License -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms -** and conditions contained in a signed written agreement between you -** and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \externalpage http://www.ecma-international.org/publications/standards/Ecma-262.htm - \title ECMA-262 -*/ - Binary files /tmp/39TcBOrOwX/qt5-declarative-0.1~git20120402/doc/src/images/gridview-layout-lefttoright-ltr-btt.png and /tmp/4OL5ZoauBZ/qt5-declarative-0.1~git20120423/doc/src/images/gridview-layout-lefttoright-ltr-btt.png differ Binary files /tmp/39TcBOrOwX/qt5-declarative-0.1~git20120402/doc/src/images/gridview-layout-lefttoright-ltr-ttb.png and /tmp/4OL5ZoauBZ/qt5-declarative-0.1~git20120423/doc/src/images/gridview-layout-lefttoright-ltr-ttb.png differ Binary files /tmp/39TcBOrOwX/qt5-declarative-0.1~git20120402/doc/src/images/gridview-layout-lefttoright-rtl-btt.png and /tmp/4OL5ZoauBZ/qt5-declarative-0.1~git20120423/doc/src/images/gridview-layout-lefttoright-rtl-btt.png differ Binary files /tmp/39TcBOrOwX/qt5-declarative-0.1~git20120402/doc/src/images/gridview-layout-lefttoright-rtl-ttb.png and /tmp/4OL5ZoauBZ/qt5-declarative-0.1~git20120423/doc/src/images/gridview-layout-lefttoright-rtl-ttb.png differ Binary files /tmp/39TcBOrOwX/qt5-declarative-0.1~git20120402/doc/src/images/gridview-layout-toptobottom-ltr-btt.png and /tmp/4OL5ZoauBZ/qt5-declarative-0.1~git20120423/doc/src/images/gridview-layout-toptobottom-ltr-btt.png differ Binary files /tmp/39TcBOrOwX/qt5-declarative-0.1~git20120402/doc/src/images/gridview-layout-toptobottom-ltr-ttb.png and /tmp/4OL5ZoauBZ/qt5-declarative-0.1~git20120423/doc/src/images/gridview-layout-toptobottom-ltr-ttb.png differ Binary files /tmp/39TcBOrOwX/qt5-declarative-0.1~git20120402/doc/src/images/gridview-layout-toptobottom-rtl-btt.png and /tmp/4OL5ZoauBZ/qt5-declarative-0.1~git20120423/doc/src/images/gridview-layout-toptobottom-rtl-btt.png differ Binary files /tmp/39TcBOrOwX/qt5-declarative-0.1~git20120402/doc/src/images/gridview-layout-toptobottom-rtl-ttb.png and /tmp/4OL5ZoauBZ/qt5-declarative-0.1~git20120423/doc/src/images/gridview-layout-toptobottom-rtl-ttb.png differ Binary files /tmp/39TcBOrOwX/qt5-declarative-0.1~git20120402/doc/src/images/listview-layout-bottomtotop.png and /tmp/4OL5ZoauBZ/qt5-declarative-0.1~git20120423/doc/src/images/listview-layout-bottomtotop.png differ Binary files /tmp/39TcBOrOwX/qt5-declarative-0.1~git20120402/doc/src/images/listview-layout-lefttoright.png and /tmp/4OL5ZoauBZ/qt5-declarative-0.1~git20120423/doc/src/images/listview-layout-lefttoright.png differ Binary files /tmp/39TcBOrOwX/qt5-declarative-0.1~git20120402/doc/src/images/listview-layout-righttoleft.png and /tmp/4OL5ZoauBZ/qt5-declarative-0.1~git20120423/doc/src/images/listview-layout-righttoleft.png differ Binary files /tmp/39TcBOrOwX/qt5-declarative-0.1~git20120402/doc/src/images/listview-layout-toptobottom.png and /tmp/4OL5ZoauBZ/qt5-declarative-0.1~git20120423/doc/src/images/listview-layout-toptobottom.png differ diff -Nru qt5-declarative-0.1~git20120402/doc/src/qml/external-resources.qdoc qt5-declarative-0.1~git20120423/doc/src/qml/external-resources.qdoc --- qt5-declarative-0.1~git20120402/doc/src/qml/external-resources.qdoc 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/doc/src/qml/external-resources.qdoc 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,35 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** GNU Free Documentation License +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms +** and conditions contained in a signed written agreement between you +** and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \externalpage http://www.ecma-international.org/publications/standards/Ecma-262.htm + \title ECMA-262 + + \externalpage http://www.w3schools.com/jsref/default.asp + \title W3Schools JavaScript Reference +*/ + diff -Nru qt5-declarative-0.1~git20120402/doc/src/qml/hostenvironment.qdoc qt5-declarative-0.1~git20120423/doc/src/qml/hostenvironment.qdoc --- qt5-declarative-0.1~git20120402/doc/src/qml/hostenvironment.qdoc 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/doc/src/qml/hostenvironment.qdoc 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** GNU Free Documentation License +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms +** and conditions contained in a signed written agreement between you +** and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! +\page qmlhostenvironment.html +\title QML JavaScript Host Environment + +QML provides a JavaScript host environment tailored to writing QML applications. +This environment is different from the host environment provided by a browser +or a server-side JavaScript environment such as Node.js. For example, QML does +not provide a \c window object or \c{DOM API} as commonly found in a browser environment. + +\section1 Common Base + +Like a browser or server-side JavaScript environment, the QML runtime implements the +\l{ECMA-262}{ECMAScript Language Specification} standard. This provides access to +all of the built-in types and functions defined by the standard, such as Object, Array, and Math. +The QML runtime implements the 5th edition of the standard, which is the same edition commonly +implemented by browsers. + +The standard ECMAScript built-ins are not explicitly documented in the QML documentation. For more +information on their use, please refer to the ECMA-262 5th edition standard or one of the many online +JavaScript reference and tutorial sites, such as the \l{W3Schools JavaScript Reference} (JavaScript Objects +Reference section). Many sites focus on JavaScript in the browser, so in some cases you may need to double +check the specification to determine whether a given function or object is part of standard ECMAScript or +specific to the browser environment. In the case of the W3Schools link above, the \c{JavaScript Objects +Reference} section generally covers the standard, while the \c{Browser Objects Reference} and \c{HTML DOM +Objects Reference} sections are browser specific (and thus not applicable to QML). + +\section1 Host Objects and Functions + +The QML JavaScript host environment implements the following host objects and functions: + +\list +\li The \l{QmlGlobalQtObject}{Qt object}: This object is specific to QML, and provides helper methods + and properties specific to the QML environment. +\li qsTr(), qsTranslate(), qsTrId(), QT_TR_NOOP(), QT_TRANSLATE_NOOP(), and QT_TRID_NOOP() functions: + These functions are specific to QML, and provide \l{Translation}{translation capabilities} to the QML environment. +\li gc() function: This function is specific to QML, and provides a way to manually trigger garbage collection. +\li print() function: This function is specific to QML, and provides a simple way to output information to the console. +\li The \l{Console API}{console object}: This object implements a subset of the \l{http://getfirebug.com/wiki/index.php/Console_API}{FireBug Console API}. +\li \l{XMLHttpRequest}, DOMException: These objects implement a subset of the \l{http://www.w3.org/TR/XMLHttpRequest/}{W3C XMLHttpRequest specification}. +\endlist + +See \l{QML Global Object} for more details on these host objects and functions. + +\section1 Native Object Modification + +QML makes the following modifications to native objects: + +\list +\li An arg() function is added to the String prototype. +\li Locale-aware coversion functions are added to the \l{Date} and \l{Number} prototypes. +\endlist + +\section1 Restrictions + +QML implements the following restrictions for JavaScript code: + +\list +\li JavaScript code cannot modify the global object. +\li Global code is run in a reduced scope. +\li The value of \c this is undefined in QML in the majority of contexts. +\endlist + +See \l {QML JavaScript Restrictions} for more details on these restrictions. + +*/ diff -Nru qt5-declarative-0.1~git20120402/doc/src/qml/qmlengine.qdoc qt5-declarative-0.1~git20120423/doc/src/qml/qmlengine.qdoc --- qt5-declarative-0.1~git20120402/doc/src/qml/qmlengine.qdoc 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/doc/src/qml/qmlengine.qdoc 2012-04-23 11:32:40.000000000 +0000 @@ -467,9 +467,13 @@ \section1 JavaScript Runtime - The runtime implements the \l{ECMA-262}{ECMAScript Language Specification} standard. - The reserved words, conditionals, variables, and object behaviors follow - after the standard. + The runtime implements the \l{ECMA-262}{ECMAScript Language Specification} standard, + 5th edition. The reserved words, conditionals, variables, and object behaviors + follow after the standard. + + The \l{QML JavaScript Host Environment} article has information about the + JavaScript host environment provided by QML, which is different than the + browser host environment many are familiar with. The \l{JavaScript Code} article has information about placing JavaScript code within QML code. diff -Nru qt5-declarative-0.1~git20120402/doc/src/qml/qmli18n.qdoc qt5-declarative-0.1~git20120423/doc/src/qml/qmli18n.qdoc --- qt5-declarative-0.1~git20120402/doc/src/qml/qmli18n.qdoc 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/doc/src/qml/qmli18n.qdoc 2012-04-23 11:32:40.000000000 +0000 @@ -33,8 +33,8 @@ \section1 Translation -Strings in QML can be marked for translation using the qsTr(), qsTranslate(), -QT_TR_NOOP(), and QT_TRANSLATE_NOOP() functions. +Strings in QML can be marked for translation using the qsTr(), qsTranslate(), qsTrId(), +QT_TR_NOOP(), QT_TRANSLATE_NOOP(), and QT_TRID_NOOP() functions. For example: \qml diff -Nru qt5-declarative-0.1~git20120402/doc/src/qml/qmltypes.qdoc qt5-declarative-0.1~git20120423/doc/src/qml/qmltypes.qdoc --- qt5-declarative-0.1~git20120402/doc/src/qml/qmltypes.qdoc 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/doc/src/qml/qmltypes.qdoc 2012-04-23 11:32:40.000000000 +0000 @@ -70,6 +70,8 @@ Alternatively, these functions provide a way for other types of C++ types to be visible in the QML context. \list + \li \l qmlRegisterModuleApi() is suited for registering either a QJSValue + or QObject module API (shared instance) into a namespace \li \l qmlRegisterUncreatableType() is suited for attached properties and enum types. \li \l qmlRegisterTypeNotAvailable() is for diff -Nru qt5-declarative-0.1~git20120402/doc/src/qml/qtdeclarative.qdoc qt5-declarative-0.1~git20120423/doc/src/qml/qtdeclarative.qdoc --- qt5-declarative-0.1~git20120402/doc/src/qml/qtdeclarative.qdoc 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/doc/src/qml/qtdeclarative.qdoc 1970-01-01 00:00:00.000000000 +0000 @@ -1,371 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:FDL$ -** GNU Free Documentation License -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms -** and conditions contained in a signed written agreement between you -** and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \module QtQml - \title Qt Qml Module - \ingroup modules - - \brief The Qt Qml module provides a declarative framework - for building highly dynamic, custom user interfaces. - - To include the definitions of the module's classes, use the - following directive: - - \code - #include - \endcode - - To link against the module, add this line to your \l qmake \c - .pro file: - - \code - QT += qml - \endcode - - For more information on the Qt Qml module (including the visual - elements which are implemented on top of the Qt Qml module) see the - \l{Qt Quick} documentation. -*/ - - -/*! - \macro QML_DECLARE_TYPE() - \relates QQmlEngine - - Equivalent to \c Q_DECLARE_METATYPE(TYPE *) and \c Q_DECLARE_METATYPE(QQmlListProperty) - - #include to use this macro. -*/ - -/*! - \macro QML_DECLARE_TYPEINFO(Type,Flags) - \relates QQmlEngine - - Declares additional properties of the given \a Type as described by the - specified \a Flags. - - Current the only supported type info is \c QML_HAS_ATTACHED_PROPERTIES which - declares that the \a Type supports \l {Attached Properties}. - - #include to use this macro. -*/ - - -/*! - \fn int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName) - \relates QQmlEngine - - This template function registers the C++ type in the QML system with - the name \a qmlName, in the library imported from \a uri having the - version number composed from \a versionMajor and \a versionMinor. - - Returns the QML type id. - - There are two forms of this template function: - - \code - template - int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName); - - template - int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName); - \endcode - - The former is the standard form which registers the type \e T as a new type. - The latter allows a particular revision of a class to be registered in - a specified version (see \l {QML Type Versioning}). - - - For example, this registers a C++ class \c MySliderItem as a QML type - named \c Slider for version 1.0 of a \l{QML Modules}{module} called - "com.mycompany.qmlcomponents": - - \code - #include - - ... - - qmlRegisterType("com.mycompany.qmlcomponents", 1, 0, "Slider"); - \endcode - - Once this is registered, the type can be used in QML by importing the - specified module name and version number: - - \qml - import com.mycompany.qmlcomponents 1.0 - - Slider { - // ... - } - \endqml - - Note that it's perfectly reasonable for a library to register types to older versions - than the actual version of the library. Indeed, it is normal for the new library to allow - QML written to previous versions to continue to work, even if more advanced versions of - some of its types are available. -*/ - -/*! - \fn int qmlRegisterRevision(const char *uri, int versionMajor, int versionMinor) - \relates QQmlEngine - - This template function registers the specified revision of a C++ type in the QML system with - the library imported from \a uri having the version number composed - from \a versionMajor and \a versionMinor. - - Returns the QML type id. - - \code - template - int qmlRegisterRevision(const char *uri, int versionMajor, int versionMinor); - \endcode - - This function is typically used to register the revision of a base class to - use for the specified module version (see \l {QML Type Versioning}). -*/ - -/*! - \fn int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& message) - \relates QQmlEngine - - This template function registers the C++ type in the QML system with - the name \a qmlName, in the library imported from \a uri having the - version number composed from \a versionMajor and \a versionMinor. - - While the type has a name and a type, it cannot be created, and the - given error \a message will result if creation is attempted. - - This is useful where the type is only intended for providing attached properties or enum values. - - Returns the QML type id. - - #include to use this function. - - \sa qmlRegisterTypeNotAvailable() -*/ - -/*! - \fn int qmlRegisterTypeNotAvailable(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& message) - \relates QQmlEngine - - This function registers a type in the QML system with the name \a qmlName, in the library imported from \a uri having the - version number composed from \a versionMajor and \a versionMinor, but any attempt to instantiate the type - will produce the given error \a message. - - Normally, the types exported by a module should be fixed. However, if a C++ type is not available, you should - at least "reserve" the QML type name, and give the user of your module a meaningful error message. - - Returns the QML type id. - - Example: - - \code - #ifdef NO_GAMES_ALLOWED - qmlRegisterTypeNotAvailable("MinehuntCore", 0, 1, "Game", "Get back to work, slacker!"); - #else - qmlRegisterType("MinehuntCore", 0, 1, "Game"); - #endif - \endcode - - This will cause any QML which uses this module and attempts to use the type to produce an error message: - \code - fun.qml: Get back to work, slacker! - Game { - ^ - \endcode - - Without this, a generic "Game is not a type" message would be given. - - #include to use this function. - - \sa qmlRegisterUncreatableType() -*/ - -/*! - \fn int qmlRegisterType() - \relates QQmlEngine - \overload - - This template function registers the C++ type in the QML - system. Instances of this type cannot be created from the QML - system. - - #include to use this function. - - Returns the QML type id. -*/ - -/*! - \fn int qmlRegisterInterface(const char *typeName) - \relates QQmlEngine - - This template function registers the C++ type in the QML system - under the name \a typeName. - - #include to use this function. - - Returns the QML type id. -*/ - -/*! - \fn int qmlRegisterModuleApi(const char *uri, int versionMajor, int versionMinor, QJSValue (*callback)(QQmlEngine *, QJSEngine *)) - \relates QQmlEngine - - This function may be used to register a module API provider \a callback in a particular \a uri - with a version specified in \a versionMajor and \a versionMinor. - - Installing a module API into a uri allows developers to provide arbitrary functionality - (methods and properties) in a namespace that doesn't necessarily contain elements. - - A module API may be either a QObject or a QJSValue. Only one module API provider - may be registered into any given namespace (combination of \a uri, \a versionMajor and \a versionMinor). - This function should be used to register a module API provider function which returns a QJSValue as a module API. - - \b{NOTE:} QJSValue module API properties will \b{not} trigger binding re-evaluation if changed. - - Usage: - \code - // first, define the module API provider function (callback). - static QJSValue *example_qjsvalue_module_api_provider(QQmlEngine *engine, QJSEngine *scriptEngine) - { - Q_UNUSED(engine) - - static int seedValue = 5; - QJSValue example = scriptEngine->newObject(); - example.setProperty("someProperty", seedValue++); - return example; - } - - // second, register the module API provider with QML by calling this function in an initialization function. - ... - qmlRegisterModuleApi("Qt.example.qjsvalueApi", 1, 0, example_qjsvalue_module_api_provider); - ... - \endcode - - In order to use the registered module API in QML, you must import the module API. - \qml - import QtQuick 2.0 - import Qt.example.qjsvalueApi 1.0 as ExampleApi - Item { - id: root - property int someValue: ExampleApi.someProperty - } - \endqml - */ - -/*! - \internal - \fn int qmlRegisterModuleApi(const char *uri, int versionMajor, int versionMinor, QObject *(*callback)(QQmlEngine *, QJSEngine *)) - \deprecated - - Any uses of a module API in a binding where that module API was registered with this - function instead of the template version will result in suboptimal binding generation. - */ - -/*! - \fn template int qmlRegisterModuleApi(const char *uri, int versionMajor, int versionMinor, QObject *(*callback)(QQmlEngine *, QJSEngine *)) - \relates QQmlEngine - - This function may be used to register a module API provider \a callback in a particular \a uri - with a version specified in \a versionMajor and \a versionMinor. - - Installing a module API into a uri allows developers to provide arbitrary functionality - (methods and properties) in a namespace that doesn't necessarily contain elements. - - A module API may be either a QObject or a QJSValue. Only one module API provider - may be registered into any given namespace (combination of \a uri, \a versionMajor and \a versionMinor). - This function should be used to register a module API provider function which returns a QObject - of the given type T as a module API. - - A QObject module API must be imported with a qualifier, and that qualifier may be used as - the target in a \l Connections element or otherwise used as any other element id would. - One exception to this is that a QObject module API property may not be aliased (because the - module API qualifier does not identify an object within the same component as any other item). - - \b{NOTE:} A QObject module API instance returned from a module API provider is owned by the QML - engine. For this reason, the module API provider function should \b{not} be implemented as a - singleton factory. - - Usage: - \code - // first, define your QObject which provides the functionality. - class ModuleApiExample : public QObject - { - Q_OBJECT - Q_PROPERTY (int someProperty READ someProperty WRITE setSomeProperty NOTIFY somePropertyChanged) - - public: - ModuleApiExample(QObject* parent = 0) - : QObject(parent), m_someProperty(0) - { - } - - ~ModuleApiExample() {} - - Q_INVOKABLE int doSomething() { setSomeProperty(5); return m_someProperty; } - - int someProperty() const { return m_someProperty; } - void setSomeProperty(int val) { m_someProperty = val; emit somePropertyChanged(val); } - - signals: - void somePropertyChanged(int newValue); - - private: - int m_someProperty; - }; - - // second, define the module API provider function (callback). - static QObject *example_qobject_module_api_provider(QQmlEngine *engine, QJSEngine *scriptEngine) - { - Q_UNUSED(engine) - Q_UNUSED(scriptEngine) - - ModuleApiExample *example = new ModuleApiExample(); - return example; - } - - // third, register the module API provider with QML by calling this function in an initialization function. - ... - qmlRegisterModuleApi("Qt.example.qobjectApi", 1, 0, example_qobject_module_api_provider); - ... - \endcode - - In order to use the registered module API in QML, you must import the module API. - \qml - import QtQuick 2.0 - import Qt.example.qobjectApi 1.0 as ExampleApi - Item { - id: root - property int someValue: ExampleApi.someProperty - - Component.onCompleted: { - someValue = ExampleApi.doSomething() - } - } - \endqml - */ diff -Nru qt5-declarative-0.1~git20120402/doc/src/qml/qtqml.qdoc qt5-declarative-0.1~git20120423/doc/src/qml/qtqml.qdoc --- qt5-declarative-0.1~git20120402/doc/src/qml/qtqml.qdoc 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/doc/src/qml/qtqml.qdoc 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,371 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** GNU Free Documentation License +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms +** and conditions contained in a signed written agreement between you +** and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \module QtQml + \title Qt QML Module + \ingroup modules + + \brief The Qt QML module provides a declarative framework + for building highly dynamic, custom user interfaces. + + To include the definitions of the module's classes, use the + following directive: + + \code + #include + \endcode + + To link against the module, add this line to your \l qmake \c + .pro file: + + \code + QT += qml + \endcode + + For more information on the Qt QML module (including the visual + elements which are implemented on top of the Qt QML module) see the + \l{Qt Quick} documentation. +*/ + + +/*! + \macro QML_DECLARE_TYPE() + \relates QQmlEngine + + Equivalent to \c Q_DECLARE_METATYPE(TYPE *) and \c Q_DECLARE_METATYPE(QQmlListProperty) + + #include to use this macro. +*/ + +/*! + \macro QML_DECLARE_TYPEINFO(Type,Flags) + \relates QQmlEngine + + Declares additional properties of the given \a Type as described by the + specified \a Flags. + + Current the only supported type info is \c QML_HAS_ATTACHED_PROPERTIES which + declares that the \a Type supports \l {Attached Properties}. + + #include to use this macro. +*/ + + +/*! + \fn int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName) + \relates QQmlEngine + + This template function registers the C++ type in the QML system with + the name \a qmlName, in the library imported from \a uri having the + version number composed from \a versionMajor and \a versionMinor. + + Returns the QML type id. + + There are two forms of this template function: + + \code + template + int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName); + + template + int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName); + \endcode + + The former is the standard form which registers the type \e T as a new type. + The latter allows a particular revision of a class to be registered in + a specified version (see \l {QML Type Versioning}). + + + For example, this registers a C++ class \c MySliderItem as a QML type + named \c Slider for version 1.0 of a \l{QML Modules}{module} called + "com.mycompany.qmlcomponents": + + \code + #include + + ... + + qmlRegisterType("com.mycompany.qmlcomponents", 1, 0, "Slider"); + \endcode + + Once this is registered, the type can be used in QML by importing the + specified module name and version number: + + \qml + import com.mycompany.qmlcomponents 1.0 + + Slider { + // ... + } + \endqml + + Note that it's perfectly reasonable for a library to register types to older versions + than the actual version of the library. Indeed, it is normal for the new library to allow + QML written to previous versions to continue to work, even if more advanced versions of + some of its types are available. +*/ + +/*! + \fn int qmlRegisterRevision(const char *uri, int versionMajor, int versionMinor) + \relates QQmlEngine + + This template function registers the specified revision of a C++ type in the QML system with + the library imported from \a uri having the version number composed + from \a versionMajor and \a versionMinor. + + Returns the QML type id. + + \code + template + int qmlRegisterRevision(const char *uri, int versionMajor, int versionMinor); + \endcode + + This function is typically used to register the revision of a base class to + use for the specified module version (see \l {QML Type Versioning}). +*/ + +/*! + \fn int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& message) + \relates QQmlEngine + + This template function registers the C++ type in the QML system with + the name \a qmlName, in the library imported from \a uri having the + version number composed from \a versionMajor and \a versionMinor. + + While the type has a name and a type, it cannot be created, and the + given error \a message will result if creation is attempted. + + This is useful where the type is only intended for providing attached properties or enum values. + + Returns the QML type id. + + #include to use this function. + + \sa qmlRegisterTypeNotAvailable() +*/ + +/*! + \fn int qmlRegisterTypeNotAvailable(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& message) + \relates QQmlEngine + + This function registers a type in the QML system with the name \a qmlName, in the library imported from \a uri having the + version number composed from \a versionMajor and \a versionMinor, but any attempt to instantiate the type + will produce the given error \a message. + + Normally, the types exported by a module should be fixed. However, if a C++ type is not available, you should + at least "reserve" the QML type name, and give the user of your module a meaningful error message. + + Returns the QML type id. + + Example: + + \code + #ifdef NO_GAMES_ALLOWED + qmlRegisterTypeNotAvailable("MinehuntCore", 0, 1, "Game", "Get back to work, slacker!"); + #else + qmlRegisterType("MinehuntCore", 0, 1, "Game"); + #endif + \endcode + + This will cause any QML which uses this module and attempts to use the type to produce an error message: + \code + fun.qml: Get back to work, slacker! + Game { + ^ + \endcode + + Without this, a generic "Game is not a type" message would be given. + + #include to use this function. + + \sa qmlRegisterUncreatableType() +*/ + +/*! + \fn int qmlRegisterType() + \relates QQmlEngine + \overload + + This template function registers the C++ type in the QML + system. Instances of this type cannot be created from the QML + system. + + #include to use this function. + + Returns the QML type id. +*/ + +/*! + \fn int qmlRegisterInterface(const char *typeName) + \relates QQmlEngine + + This template function registers the C++ type in the QML system + under the name \a typeName. + + #include to use this function. + + Returns the QML type id. +*/ + +/*! + \fn int qmlRegisterModuleApi(const char *uri, int versionMajor, int versionMinor, QJSValue (*callback)(QQmlEngine *, QJSEngine *)) + \relates QQmlEngine + + This function may be used to register a module API provider \a callback in a particular \a uri + with a version specified in \a versionMajor and \a versionMinor. + + Installing a module API into a uri allows developers to provide arbitrary functionality + (methods and properties) in a namespace that doesn't necessarily contain elements. + + A module API may be either a QObject or a QJSValue. Only one module API provider + may be registered into any given namespace (combination of \a uri, \a versionMajor and \a versionMinor). + This function should be used to register a module API provider function which returns a QJSValue as a module API. + + \b{NOTE:} QJSValue module API properties will \b{not} trigger binding re-evaluation if changed. + + Usage: + \code + // first, define the module API provider function (callback). + static QJSValue *example_qjsvalue_module_api_provider(QQmlEngine *engine, QJSEngine *scriptEngine) + { + Q_UNUSED(engine) + + static int seedValue = 5; + QJSValue example = scriptEngine->newObject(); + example.setProperty("someProperty", seedValue++); + return example; + } + + // second, register the module API provider with QML by calling this function in an initialization function. + ... + qmlRegisterModuleApi("Qt.example.qjsvalueApi", 1, 0, example_qjsvalue_module_api_provider); + ... + \endcode + + In order to use the registered module API in QML, you must import the module API. + \qml + import QtQuick 2.0 + import Qt.example.qjsvalueApi 1.0 as ExampleApi + Item { + id: root + property int someValue: ExampleApi.someProperty + } + \endqml + */ + +/*! + \internal + \fn int qmlRegisterModuleApi(const char *uri, int versionMajor, int versionMinor, QObject *(*callback)(QQmlEngine *, QJSEngine *)) + \deprecated + + Any uses of a module API in a binding where that module API was registered with this + function instead of the template version will result in suboptimal binding generation. + */ + +/*! + \fn template int qmlRegisterModuleApi(const char *uri, int versionMajor, int versionMinor, QObject *(*callback)(QQmlEngine *, QJSEngine *)) + \relates QQmlEngine + + This function may be used to register a module API provider \a callback in a particular \a uri + with a version specified in \a versionMajor and \a versionMinor. + + Installing a module API into a uri allows developers to provide arbitrary functionality + (methods and properties) in a namespace that doesn't necessarily contain elements. + + A module API may be either a QObject or a QJSValue. Only one module API provider + may be registered into any given namespace (combination of \a uri, \a versionMajor and \a versionMinor). + This function should be used to register a module API provider function which returns a QObject + of the given type T as a module API. + + A QObject module API must be imported with a qualifier, and that qualifier may be used as + the target in a \l Connections element or otherwise used as any other element id would. + One exception to this is that a QObject module API property may not be aliased (because the + module API qualifier does not identify an object within the same component as any other item). + + \b{NOTE:} A QObject module API instance returned from a module API provider is owned by the QML + engine. For this reason, the module API provider function should \b{not} be implemented as a + singleton factory. + + Usage: + \code + // first, define your QObject which provides the functionality. + class ModuleApiExample : public QObject + { + Q_OBJECT + Q_PROPERTY (int someProperty READ someProperty WRITE setSomeProperty NOTIFY somePropertyChanged) + + public: + ModuleApiExample(QObject* parent = 0) + : QObject(parent), m_someProperty(0) + { + } + + ~ModuleApiExample() {} + + Q_INVOKABLE int doSomething() { setSomeProperty(5); return m_someProperty; } + + int someProperty() const { return m_someProperty; } + void setSomeProperty(int val) { m_someProperty = val; emit somePropertyChanged(val); } + + signals: + void somePropertyChanged(int newValue); + + private: + int m_someProperty; + }; + + // second, define the module API provider function (callback). + static QObject *example_qobject_module_api_provider(QQmlEngine *engine, QJSEngine *scriptEngine) + { + Q_UNUSED(engine) + Q_UNUSED(scriptEngine) + + ModuleApiExample *example = new ModuleApiExample(); + return example; + } + + // third, register the module API provider with QML by calling this function in an initialization function. + ... + qmlRegisterModuleApi("Qt.example.qobjectApi", 1, 0, example_qobject_module_api_provider); + ... + \endcode + + In order to use the registered module API in QML, you must import the module API. + \qml + import QtQuick 2.0 + import Qt.example.qobjectApi 1.0 as ExampleApi + Item { + id: root + property int someValue: ExampleApi.someProperty + + Component.onCompleted: { + someValue = ExampleApi.doSomething() + } + } + \endqml + */ diff -Nru qt5-declarative-0.1~git20120402/doc/src/qtdeclarative.qdoc qt5-declarative-0.1~git20120423/doc/src/qtdeclarative.qdoc --- qt5-declarative-0.1~git20120402/doc/src/qtdeclarative.qdoc 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/doc/src/qtdeclarative.qdoc 1970-01-01 00:00:00.000000000 +0000 @@ -1,180 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:FDL$ -** GNU Free Documentation License -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms -** and conditions contained in a signed written agreement between you -** and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! -\title Qt Quick -\page qtquick-reference.html -\inqmlmodule QtQuick 2 -\ingroup qt-gui-concepts -\ingroup overviews - -\brief Qt Quick provides a declarative framework for building highly -dynamic applications. - -For App Developers and Designers, who want to deliver apps with amazing user -experience, Qt provides the QML language, the Qt Quick Elements, and tools in Qt -Creator that make it faster than ever to transform your brilliant idea into a -winning App across mobile, embedded, and desktop platforms. - -\target qtquick-overviews -\div {class="threecolumn_area"} - \div {class="heading"} - QML Topics - \enddiv - QML is a declarative language for creating flexible and reusable - components. The QML runtime powers QML based applications. The runtime - includes a QML engine, JavaScript engine, and mechanism to bind to the Qt - Framework. - - \div {class=" threecolumn_piece"} - \div {class="heading"} - QML Essentials - \enddiv - \list - \li \l{QML Components}{Components} - \li \l{Properties and Property Binding in QML}{Properties and Property Binding} - \li \l{JavaScript Expressions in QML}{JavaScript Code} - \li \l{QML Signal and Handler Event System}{Signal and Handler Event System} - \li \l{QML Modules}{Modules} - \endlist - \list - \li \l{What's New in Qt Quick 2}{What's New in Qt Quick} - \endlist - \enddiv - \div {class="threecolumn_piece"} - \div {class="heading"} - QML Engine - \enddiv - \list - \li \l{The QML Engine} - \li \l{QML Global Object} - \li \l{Dynamic Object Management in QML}{Dynamic Object Management} - \li \l{QML Performance}{Performance} - \endlist - \enddiv - \div {class=" threecolumn_piece"} - \div {class="heading"} - Reference - \enddiv - \list - \li \l{QML Syntax} - \li \l{QML Basic Types}{Data Types} - \li \l{QML Coding Conventions}{Coding Conventions} - \li \l{QML Security}{Security Model} - \li \l{QML Scope}{Scope Model} - \li \l{QML Documents}{Documents} - \endlist - \enddiv - \div {class="threecolumn_piece"} - \div {class="heading"} - QML Bindings with Qt C++ - \enddiv - \list - \li \l{Creating QML Types} - \li \l{QML Plugins} - \li \l{Exposing C++ Models} - \li \l{Integrating QML Code with Existing Qt UI Code}{Qt Gui Porting Information} - \endlist - \enddiv - \div {class=" threecolumn_piece"} - \div {class="heading"} - Tools - \enddiv - \list - \li \l{QML Internationalization}{Internationalization} - \li \l{QtQuickTest Reference Documentation} - \li \l{Debugging QML} - \endlist - \enddiv -\enddiv -\div {class="threecolumn_area"} - \div {class="heading"} - Qt Quick Elements - \enddiv - Qt Quick Elements features graphical elements, user input system, - animation system, and data visualization through models and delegates. - \div {class="threecolumn_piece"} - \div {class="heading"} - Graphics and Special Effects - \enddiv - \list - \li \l{Qt Quick Basic Elements}{Basic Elements} - \li \l{Painting with Canvas API} - \li \l{Using the Qt Quick Particle System}{Particle Effects} - \li \l{Shader Effects in QML}{Shader Effects} - \endlist - \enddiv - \div {class="threecolumn_piece"} - \div {class="heading"} - Anchoring and Layouts - \enddiv - \list - \li \l{Component Layouts} - \li \l{Layouts with Anchors} - \li \l{QML Right-to-left User Interfaces}{Right-to-left User Interfaces} - \endlist - \enddiv - \div {class="threecolumn_piece"} - \div {class="heading"} - Mouse and Keyboard Input - \enddiv - \list - \li \l{QML Mouse Events}{Mouse Events} - \li \l{QML Text Handling and Validators}{Text Handling and Validators} - \li \l{Keyboard Focus in QML}{Keyboard Focus} - \endlist - \enddiv - \div {class="threecolumn_piece"} - \div {class="heading"} - States and Transitions - \enddiv - \list - \li \l{QML States}{States} - \li \l{QML Animation and Transitions}{Animation and Transitions} - \endlist - \enddiv - \div {class="threecolumn_piece"} - \div {class="heading"} - Data with Models and Views - \enddiv - \list - \li \l{QML Models and Views}{Models and Views} - \endlist - \enddiv - \div {class="threecolumn_piece"} - \div {class="heading"} - Data Storage and Resources - \enddiv - \list - \li \l{QML Local Storage}{SQL Local Storage} - \li \l{Resource Loading and Network Transparency in QML}{Resources and Network Transparency} - \endlist - \enddiv -\enddiv - -*/ - diff -Nru qt5-declarative-0.1~git20120402/doc/src/qtquick2/qtdeclarative.qdoc qt5-declarative-0.1~git20120423/doc/src/qtquick2/qtdeclarative.qdoc --- qt5-declarative-0.1~git20120402/doc/src/qtquick2/qtdeclarative.qdoc 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/doc/src/qtquick2/qtdeclarative.qdoc 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,180 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** GNU Free Documentation License +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms +** and conditions contained in a signed written agreement between you +** and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! +\title Qt Quick +\page qtquick-reference.html +\inqmlmodule QtQuick 2 +\ingroup qt-gui-concepts +\ingroup overviews + +\brief Qt Quick provides a declarative framework for building highly +dynamic applications. + +For App Developers and Designers, who want to deliver apps with amazing user +experience, Qt provides the QML language, the Qt Quick Elements, and tools in Qt +Creator that make it faster than ever to transform your brilliant idea into a +winning App across mobile, embedded, and desktop platforms. + +\target qtquick-overviews +\div {class="threecolumn_area"} + \div {class="heading"} + QML Topics + \enddiv + QML is a declarative language for creating flexible and reusable + components. The QML runtime powers QML based applications. The runtime + includes a QML engine, JavaScript engine, and mechanism to bind to the Qt + Framework. + + \div {class=" threecolumn_piece"} + \div {class="heading"} + QML Essentials + \enddiv + \list + \li \l{QML Components}{Components} + \li \l{Properties and Property Binding in QML}{Properties and Property Binding} + \li \l{JavaScript Expressions in QML}{JavaScript Code} + \li \l{QML Signal and Handler Event System}{Signal and Handler Event System} + \li \l{QML Modules}{Modules} + \endlist + \list + \li \l{What's New in Qt Quick 2}{What's New in Qt Quick} + \endlist + \enddiv + \div {class="threecolumn_piece"} + \div {class="heading"} + QML Engine + \enddiv + \list + \li \l{The QML Engine} + \li \l{QML Global Object} + \li \l{Dynamic Object Management in QML}{Dynamic Object Management} + \li \l{QML Performance}{Performance} + \endlist + \enddiv + \div {class=" threecolumn_piece"} + \div {class="heading"} + Reference + \enddiv + \list + \li \l{QML Syntax} + \li \l{QML Basic Types}{Data Types} + \li \l{QML Coding Conventions}{Coding Conventions} + \li \l{QML Security}{Security Model} + \li \l{QML Scope}{Scope Model} + \li \l{QML Documents}{Documents} + \endlist + \enddiv + \div {class="threecolumn_piece"} + \div {class="heading"} + QML Bindings with Qt C++ + \enddiv + \list + \li \l{Creating QML Types} + \li \l{QML Plugins} + \li \l{Exposing C++ Models} + \li \l{Integrating QML Code with Existing Qt UI Code}{Qt Gui Porting Information} + \endlist + \enddiv + \div {class=" threecolumn_piece"} + \div {class="heading"} + Tools + \enddiv + \list + \li \l{QML Internationalization}{Internationalization} + \li \l{QtQuickTest Reference Documentation} + \li \l{Debugging QML} + \endlist + \enddiv +\enddiv +\div {class="threecolumn_area"} + \div {class="heading"} + Qt Quick Elements + \enddiv + Qt Quick Elements features graphical elements, user input system, + animation system, and data visualization through models and delegates. + \div {class="threecolumn_piece"} + \div {class="heading"} + Graphics and Special Effects + \enddiv + \list + \li \l{Qt Quick Basic Elements}{Basic Elements} + \li \l{Painting with Canvas API} + \li \l{Using the Qt Quick Particle System}{Particle Effects} + \li \l{Shader Effects in QML}{Shader Effects} + \endlist + \enddiv + \div {class="threecolumn_piece"} + \div {class="heading"} + Anchoring and Layouts + \enddiv + \list + \li \l{Component Layouts} + \li \l{Layouts with Anchors} + \li \l{QML Right-to-left User Interfaces}{Right-to-left User Interfaces} + \endlist + \enddiv + \div {class="threecolumn_piece"} + \div {class="heading"} + Mouse and Keyboard Input + \enddiv + \list + \li \l{QML Mouse Events}{Mouse Events} + \li \l{QML Text Handling and Validators}{Text Handling and Validators} + \li \l{Keyboard Focus in QML}{Keyboard Focus} + \endlist + \enddiv + \div {class="threecolumn_piece"} + \div {class="heading"} + States and Transitions + \enddiv + \list + \li \l{QML States}{States} + \li \l{QML Animation and Transitions}{Animation and Transitions} + \endlist + \enddiv + \div {class="threecolumn_piece"} + \div {class="heading"} + Data with Models and Views + \enddiv + \list + \li \l{QML Models and Views}{Models and Views} + \endlist + \enddiv + \div {class="threecolumn_piece"} + \div {class="heading"} + Data Storage and Resources + \enddiv + \list + \li \l{QML Local Storage}{SQL Local Storage} + \li \l{Resource Loading and Network Transparency in QML}{Resources and Network Transparency} + \endlist + \enddiv +\enddiv + +*/ + diff -Nru qt5-declarative-0.1~git20120402/doc/src/qtquick2/qtquick.qdoc qt5-declarative-0.1~git20120423/doc/src/qtquick2/qtquick.qdoc --- qt5-declarative-0.1~git20120402/doc/src/qtquick2/qtquick.qdoc 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/doc/src/qtquick2/qtquick.qdoc 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,52 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** GNU Free Documentation License +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms +** and conditions contained in a signed written agreement between you +** and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \module QtQuick + \title Qt Quick Module + \ingroup modules + + \brief The Qt Quick module provides classes for embedding Qt Quick + in Qt/C++ applications. + + To include the definitions of the module's classes, use the + following directive: + + \code + #include + \endcode + + To link against the module, add this line to your \l qmake \c + .pro file: + + \code + QT += quick + \endcode + + For more information on the Qt Quick module, see the + \l{Qt Quick} documentation. +*/ diff -Nru qt5-declarative-0.1~git20120402/doc/src/qtquick2/whatsnew.qdoc qt5-declarative-0.1~git20120423/doc/src/qtquick2/whatsnew.qdoc --- qt5-declarative-0.1~git20120402/doc/src/qtquick2/whatsnew.qdoc 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/doc/src/qtquick2/whatsnew.qdoc 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,167 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** GNU Free Documentation License +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms +** and conditions contained in a signed written agreement between you +** and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! +\title What's New in Qt Quick 2 +\page qtquick2-whatsnew.html +\inqmlmodule QtQuick 2 + +\section1 Qt 5.0.0 includes QtQuick 2.0 + +QtQuick 2.0 is a major update. + +\section2 SceneGraph renderer + +QtQuick 2 is based on an OpenGL scenegraph. The following +classes replace their equivalents in QtQuick 1: + +\list +\li QQuickView +\li QQuickCanvas +\li QQuickItem +\li QQuickPaintedItem +\endlist + +\section2 QML Engine/Language Improvements + +JS engine changed to V8. For most QML users this should not make a visible difference beyond performance improvements, however a lot of undefined behavior semantics may have changed as well. As always, it is recommended not to rely on undefined behavior. + +Parser and compiler optimizations. + +New binding optimizer. + +ValueType improvements: + - QColor is now a value type. The red, green, blue and alpha channels can be accessed via "r", "g", "b" and "a" properties + - Improved support for QVector4D, now constructible in QML via Qt.vector4d() + +Arbitrary functionality may be provided in a namespace through a Module API. See \l{qmlRegisterModuleApi()} for more information. + +JavaScript (.js) files may now import QML modules and other JavaScript files. See \l{Importing One JavaScript File From Another} for more information. + +A new property type "var" has been added which obsoletes the old "variant" property type. +Properties of the "var" type may hold JavaScript references. See \l{QML Basic Types} for more information. + +QML properties of type \c var and \c variant can now hold pixmaps. See \l{Scarce Resources in JavaScript} for more information + +QQmlExpression can now be directly (and more efficiently) constructed from a +QQmlScriptString. + +Support for certain sequence types (QList, QList, QList, QList, QList and QStringList) has been improved. +QObjects can define Q_PROPERTYs of these types which can be accessed transparently from JavaScript. See the section on +sequences in \l{Extending QML Functionalities using C++} for more information. + +\section2 Canvas Item + +The new \l Canvas item provides a HTML5 canvas like API, with some enhancements: +1) Supports 2 render targets: Canvas.Image and Canvas.FramebufferObject +2) Supports background thread rendering +3) Supports tiled canvas rendering + +The Canvas item supports most of the HTML5 context2d APIs, the API details please look at the canvas item documentation. + + +\section2 Particle System + +The \l{QtQuick.Particles 2}{QtQuick.Particles} module contains elements that can be composed to form 2D particle system. + + +\section2 Element API/Behavior Changes + +New \l SpriteImage element renders animated sprites and can transition between animations. +It uses the \l Sprite element to represent each animation. + +MouseArea now propagates clicked, doubleClicked and pressAndHold differently to pressed. +These will now be propagated to the highest-stacking-order enabled MouseArea which has a handler for them. +You can still ignore these events in the handler to let them pass through. +This behavior is triggered with the new property propagateComposedEvents. + +The Binding element can now be used as a value source, and will also restore any previously +set binding when its \e when clause becomes false. + +Flickable: added dragging, draggingHorizontally and draggingVerically properties. +Added topMargin, bottomMargin, leftMargin, rightMargin, xOrigin, yOrigin properties. + +Image has two new properties: horizontalAlignment and verticalAlignment. It also has a new value for +fillMode (Image.Pad) that does not transform the image. +Setting Image sourceSize.width and sourceSize.height will now fit the image to the size, maintaining aspect. + +Grid now has rowSpacing and columnSpacing properties. Spacing properties on positioners are now real numbers instead +of integers. + +Positioner (Row, Column, Grid, Flow) improvements: +\list +\li Transitions used for \c add and \c move now have improved features: they can access a ViewTransition attached property (see the ViewTransition documentation for examples) and can now animate arbitrary item properties (instead of being restricted to animating an item's position). +\li Items in a positioner now have attached properties that can be used to determine a subitem's location: Positioner.index, Positioner.isFirstItem, Positioner.isLastItem. +\endlist + +Loader improvements: + - "active" property added to Loader, to allow delaying instantiation of a Loader element's item property + - "setSource(JSObject)" method added to Loader to allow initial property values to be specified (similar to Component.createObject()) + - now only emits the \c sourceChanged signal when the source is changed and the +\c sourceComponentChanged signal when the sourceComponent is changed. It used to emit both signals when one of the properties was changed. + +Text improvements: + - a \c onLineLaidOut handler is called for every line during the layout process. This gives the opportunity to position and resize a line as it is being laid out. + - a \c doLayout method was added to trigger the layout from Javascript. + - now automatically switch to StyledText instead of RichText if textFormat is set to AutoText. + +TextEdit: + - the default value of the textFormat property is now PlainText instead of AutoText. + +TextInput has new wrapMode and verticalAlignment properties, and the positionAt function now takes +a y parameter. + +PathView now has a \c currentItem property + +ListView and GridView: + - Can now apply specified transitions whenever items are added, removed or moved in a view. + See the documentation for ViewTransition and ListView.add, ListView.addDisplaced, + GridView.add, GridView.addDisplaced etc. for details. + - These now have headerItem and footerItem properties (the instantiated header and footer items). + - In RightToLeft layout the preferredHighlightBegin/End are now also reversed. + +ListView section.labelPositioning property added to allow keeping the current section label +at the start and/or next section label at the end of the view. + +A new property type ("var") has been introduced which obsoletes "variant" properties in QML. +Properties of this type are equivalent to regular JavaScript variables. See the documentation +on \l{QML Basic Types} for more information about "var" properties. + +New elements have been added for contructing paths: PathArc, PathCurve, PathSvg. + +\section2 QtQuick 1 is now a separate library and module + +Writing C++ applications using QtQuick 1 specific API, i.e. QDeclarativeView or QDeclarativeItem +requires adding the "quick1" module to the .pro file, e.g. QT += quick1 + +QDeclarativeView and QDeclarativeItem headers are now in the QtQuick 1 module, i.e. +#include +#include + +\sa {What's New in Qt Quick 1}{What's New in Qt Quick 1} + +*/ diff -Nru qt5-declarative-0.1~git20120402/doc/src/quick/qtquick.qdoc qt5-declarative-0.1~git20120423/doc/src/quick/qtquick.qdoc --- qt5-declarative-0.1~git20120402/doc/src/quick/qtquick.qdoc 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/doc/src/quick/qtquick.qdoc 1970-01-01 00:00:00.000000000 +0000 @@ -1,52 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:FDL$ -** GNU Free Documentation License -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms -** and conditions contained in a signed written agreement between you -** and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \module QtQuick - \title Qt Quick Module - \ingroup modules - - \brief The Qt Quick module provides classes for embedding Qt Quick - in Qt/C++ applications. - - To include the definitions of the module's classes, use the - following directive: - - \code - #include - \endcode - - To link against the module, add this line to your \l qmake \c - .pro file: - - \code - QT += quick - \endcode - - For more information on the Qt Quick module, see the - \l{Qt Quick} documentation. -*/ diff -Nru qt5-declarative-0.1~git20120402/doc/src/whatsnew.qdoc qt5-declarative-0.1~git20120423/doc/src/whatsnew.qdoc --- qt5-declarative-0.1~git20120402/doc/src/whatsnew.qdoc 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/doc/src/whatsnew.qdoc 1970-01-01 00:00:00.000000000 +0000 @@ -1,167 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:FDL$ -** GNU Free Documentation License -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms -** and conditions contained in a signed written agreement between you -** and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! -\title What's New in Qt Quick 2 -\page qtquick2-whatsnew.html -\inqmlmodule QtQuick 2 - -\section1 Qt 5.0.0 includes QtQuick 2.0 - -QtQuick 2.0 is a major update. - -\section2 SceneGraph renderer - -QtQuick 2 is based on an OpenGL scenegraph. The following -classes replace their equivalents in QtQuick 1: - -\list -\li QQuickView -\li QQuickCanvas -\li QQuickItem -\li QQuickPaintedItem -\endlist - -\section2 QML Engine/Language Improvements - -JS engine changed to V8. For most QML users this should not make a visible difference beyond performance improvements, however a lot of undefined behavior semantics may have changed as well. As always, it is recommended not to rely on undefined behavior. - -Parser and compiler optimizations. - -New binding optimizer. - -ValueType improvements: - - QColor is now a value type. The red, green, blue and alpha channels can be accessed via "r", "g", "b" and "a" properties - - Improved support for QVector4D, now constructible in QML via Qt.vector4d() - -Arbitrary functionality may be provided in a namespace through a Module API. See \l{qmlRegisterModuleApi()} for more information. - -JavaScript (.js) files may now import QML modules and other JavaScript files. See \l{Importing One JavaScript File From Another} for more information. - -A new property type "var" has been added which obsoletes the old "variant" property type. -Properties of the "var" type may hold JavaScript references. See \l{QML Basic Types} for more information. - -QML properties of type \c var and \c variant can now hold pixmaps. See \l{Scarce Resources in JavaScript} for more information - -QQmlExpression can now be directly (and more efficiently) constructed from a -QQmlScriptString. - -Support for certain sequence types (QList, QList, QList, QList, QList and QStringList) has been improved. -QObjects can define Q_PROPERTYs of these types which can be accessed transparently from JavaScript. See the section on -sequences in \l{Extending QML Functionalities using C++} for more information. - -\section2 Canvas Item - -The new \l Canvas item provides a HTML5 canvas like API, with some enhancements: -1) Supports 2 render targets: Canvas.Image and Canvas.FramebufferObject -2) Supports background thread rendering -3) Supports tiled canvas rendering - -The Canvas item supports most of the HTML5 context2d APIs, the API details please look at the canvas item documentation. - - -\section2 Particle System - -The \l{QtQuick.Particles 2}{QtQuick.Particles} module contains elements that can be composed to form 2D particle system. - - -\section2 Element API/Behavior Changes - -New \l SpriteImage element renders animated sprites and can transition between animations. -It uses the \l Sprite element to represent each animation. - -MouseArea now propagates clicked, doubleClicked and pressAndHold differently to pressed. -These will now be propagated to the highest-stacking-order enabled MouseArea which has a handler for them. -You can still ignore these events in the handler to let them pass through. -This behavior is triggered with the new property propagateComposedEvents. - -The Binding element can now be used as a value source, and will also restore any previously -set binding when its \e when clause becomes false. - -Flickable: added dragging, draggingHorizontally and draggingVerically properties. -Added topMargin, bottomMargin, leftMargin, rightMargin, xOrigin, yOrigin properties. - -Image has two new properties: horizontalAlignment and verticalAlignment. It also has a new value for -fillMode (Image.Pad) that does not transform the image. -Setting Image sourceSize.width and sourceSize.height will now fit the image to the size, maintaining aspect. - -Grid now has rowSpacing and columnSpacing properties. Spacing properties on positioners are now real numbers instead -of integers. - -Positioner (Row, Column, Grid, Flow) improvements: -\list -\li Transitions used for \c add and \c move now have improved features: they can access a ViewTransition attached property (see the ViewTransition documentation for examples) and can now animate arbitrary item properties (instead of being restricted to animating an item's position). -\li Items in a positioner now have attached properties that can be used to determine a subitem's location: Positioner.index, Positioner.isFirstItem, Positioner.isLastItem. -\endlist - -Loader improvements: - - "active" property added to Loader, to allow delaying instantiation of a Loader element's item property - - "setSource(JSObject)" method added to Loader to allow initial property values to be specified (similar to Component.createObject()) - - now only emits the \c sourceChanged signal when the source is changed and the -\c sourceComponentChanged signal when the sourceComponent is changed. It used to emit both signals when one of the properties was changed. - -Text improvements: - - a \c onLineLaidOut handler is called for every line during the layout process. This gives the opportunity to position and resize a line as it is being laid out. - - a \c doLayout method was added to trigger the layout from Javascript. - - now automatically switch to StyledText instead of RichText if textFormat is set to AutoText. - -TextEdit: - - the default value of the textFormat property is now PlainText instead of AutoText. - -TextInput has new wrapMode and verticalAlignment properties, and the positionAt function now takes -a y parameter. - -PathView now has a \c currentItem property - -ListView and GridView: - - Can now apply specified transitions whenever items are added, removed or moved in a view. - See the documentation for ViewTransition and ListView.add, ListView.addDisplaced, - GridView.add, GridView.addDisplaced etc. for details. - - These now have headerItem and footerItem properties (the instantiated header and footer items). - - In RightToLeft layout the preferredHighlightBegin/End are now also reversed. - -ListView section.labelPositioning property added to allow keeping the current section label -at the start and/or next section label at the end of the view. - -A new property type ("var") has been introduced which obsoletes "variant" properties in QML. -Properties of this type are equivalent to regular JavaScript variables. See the documentation -on \l{QML Basic Types} for more information about "var" properties. - -New elements have been added for contructing paths: PathArc, PathCurve, PathSvg. - -\section2 QtQuick 1 is now a separate library and module - -Writing C++ applications using QtQuick 1 specific API, i.e. QDeclarativeView or QDeclarativeItem -requires adding the "quick1" module to the .pro file, e.g. QT += quick1 - -QDeclarativeView and QDeclarativeItem headers are now in the QtQuick 1 module, i.e. -#include -#include - -\sa {What's New in Qt Quick 1}{What's New in Qt Quick 1} - -*/ diff -Nru qt5-declarative-0.1~git20120402/.git/config qt5-declarative-0.1~git20120423/.git/config --- qt5-declarative-0.1~git20120402/.git/config 2012-04-02 10:53:09.000000000 +0000 +++ qt5-declarative-0.1~git20120423/.git/config 2012-04-23 11:32:41.000000000 +0000 @@ -10,7 +10,7 @@ remote = origin merge = refs/heads/master [commit] - template = /home1/kate/qt5/qt5-20120402/qtdeclarative/../.commit-template + template = /home1/kate/qt5/qt5-20120423/qtdeclarative/../.commit-template [remote "gerrit"] url = ssh://codereview.qt-project.org/qt/qtdeclarative fetch = +refs/heads/*:refs/remotes/gerrit/* diff -Nru qt5-declarative-0.1~git20120402/.git/FETCH_HEAD qt5-declarative-0.1~git20120423/.git/FETCH_HEAD --- qt5-declarative-0.1~git20120402/.git/FETCH_HEAD 2012-04-02 10:53:09.000000000 +0000 +++ qt5-declarative-0.1~git20120423/.git/FETCH_HEAD 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -368a3a736c8dbe945cd820b78523191522351494 git://gitorious.org/qt/qtdeclarative diff -Nru qt5-declarative-0.1~git20120402/.git/HEAD qt5-declarative-0.1~git20120423/.git/HEAD --- qt5-declarative-0.1~git20120402/.git/HEAD 2012-04-02 11:02:55.000000000 +0000 +++ qt5-declarative-0.1~git20120423/.git/HEAD 2012-04-23 11:44:59.000000000 +0000 @@ -1 +1 @@ -5bb0180645ce55c28eb8b923bee61c74de3b9c0e +0d52c081a1650dc6a3a9b02c7fa5345c94ca6597 Binary files /tmp/39TcBOrOwX/qt5-declarative-0.1~git20120402/.git/index and /tmp/4OL5ZoauBZ/qt5-declarative-0.1~git20120423/.git/index differ diff -Nru qt5-declarative-0.1~git20120402/.git/logs/HEAD qt5-declarative-0.1~git20120423/.git/logs/HEAD --- qt5-declarative-0.1~git20120402/.git/logs/HEAD 2012-04-02 11:02:55.000000000 +0000 +++ qt5-declarative-0.1~git20120423/.git/logs/HEAD 2012-04-23 11:44:59.000000000 +0000 @@ -1,2 +1,2 @@ -0000000000000000000000000000000000000000 368a3a736c8dbe945cd820b78523191522351494 Kate Alhola 1333363507 +0300 clone: from git://gitorious.org/qt/qtdeclarative.git -368a3a736c8dbe945cd820b78523191522351494 5bb0180645ce55c28eb8b923bee61c74de3b9c0e Kate Alhola 1333364575 +0300 checkout: moving from master to 5bb0180645ce55c28eb8b923bee61c74de3b9c0e +0000000000000000000000000000000000000000 6fe0263b25475199808fc5633fbcacc06162af2a Kate Alhola 1335180760 +0300 clone: from git://gitorious.org/qt/qtdeclarative.git +6fe0263b25475199808fc5633fbcacc06162af2a 0d52c081a1650dc6a3a9b02c7fa5345c94ca6597 Kate Alhola 1335181499 +0300 checkout: moving from master to 0d52c081a1650dc6a3a9b02c7fa5345c94ca6597 diff -Nru qt5-declarative-0.1~git20120402/.git/logs/refs/heads/master qt5-declarative-0.1~git20120423/.git/logs/refs/heads/master --- qt5-declarative-0.1~git20120402/.git/logs/refs/heads/master 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/.git/logs/refs/heads/master 2012-04-23 11:32:40.000000000 +0000 @@ -1 +1 @@ -0000000000000000000000000000000000000000 368a3a736c8dbe945cd820b78523191522351494 Kate Alhola 1333363507 +0300 clone: from git://gitorious.org/qt/qtdeclarative.git +0000000000000000000000000000000000000000 6fe0263b25475199808fc5633fbcacc06162af2a Kate Alhola 1335180760 +0300 clone: from git://gitorious.org/qt/qtdeclarative.git Binary files /tmp/39TcBOrOwX/qt5-declarative-0.1~git20120402/.git/objects/pack/pack-07a551aa2e754418a4ba41715caee768ed98e594.idx and /tmp/4OL5ZoauBZ/qt5-declarative-0.1~git20120423/.git/objects/pack/pack-07a551aa2e754418a4ba41715caee768ed98e594.idx differ Binary files /tmp/39TcBOrOwX/qt5-declarative-0.1~git20120402/.git/objects/pack/pack-07a551aa2e754418a4ba41715caee768ed98e594.pack and /tmp/4OL5ZoauBZ/qt5-declarative-0.1~git20120423/.git/objects/pack/pack-07a551aa2e754418a4ba41715caee768ed98e594.pack differ Binary files /tmp/39TcBOrOwX/qt5-declarative-0.1~git20120402/.git/objects/pack/pack-1ad9f4fb7514d2eb929298f52a8e9d4b95e68cb5.idx and /tmp/4OL5ZoauBZ/qt5-declarative-0.1~git20120423/.git/objects/pack/pack-1ad9f4fb7514d2eb929298f52a8e9d4b95e68cb5.idx differ Binary files /tmp/39TcBOrOwX/qt5-declarative-0.1~git20120402/.git/objects/pack/pack-1ad9f4fb7514d2eb929298f52a8e9d4b95e68cb5.pack and /tmp/4OL5ZoauBZ/qt5-declarative-0.1~git20120423/.git/objects/pack/pack-1ad9f4fb7514d2eb929298f52a8e9d4b95e68cb5.pack differ diff -Nru qt5-declarative-0.1~git20120402/.git/packed-refs qt5-declarative-0.1~git20120423/.git/packed-refs --- qt5-declarative-0.1~git20120402/.git/packed-refs 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/.git/packed-refs 2012-04-23 11:32:40.000000000 +0000 @@ -1,8 +1,10 @@ # pack-refs with: peeled +8b042ac6b5fcc201f19051feb40672b2608f054e refs/tags/qt-v5.0.0-alpha1 +^ec7deb3d123bb44b5d57590615a60ed48b1d2860 f017b9fbcdb31ad5b175024bc0469cc2cac3a8a8 refs/remotes/origin/visuallistmodel f02ce5b8e9f306d066b3a8edb240199444adaa43 refs/remotes/origin/textng 5677ad061ac8adb0c9a99e634e24bf1e51e45e16 refs/remotes/origin/statemachine -368a3a736c8dbe945cd820b78523191522351494 refs/remotes/origin/master -16e29f30e3483568a36dba7b37520ea1645d9a2e refs/remotes/origin/buildsystem -24fb8dc27eddfdd62bd2c3a6e863cbf433762cd6 refs/remotes/origin/api_changes +6fe0263b25475199808fc5633fbcacc06162af2a refs/remotes/origin/master +2e6718f219fcd8c272f3638f2cf135cf5c425824 refs/remotes/origin/buildsystem +e5f45d9b57bb0542ec47e5a8a4e57388b6d59d35 refs/remotes/origin/api_changes c3601a8db91bc777ea859d6a796dfab6a218675e refs/remotes/origin/animation-refactor diff -Nru qt5-declarative-0.1~git20120402/.git/refs/heads/master qt5-declarative-0.1~git20120423/.git/refs/heads/master --- qt5-declarative-0.1~git20120402/.git/refs/heads/master 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/.git/refs/heads/master 2012-04-23 11:32:40.000000000 +0000 @@ -1 +1 @@ -368a3a736c8dbe945cd820b78523191522351494 +6fe0263b25475199808fc5633fbcacc06162af2a Binary files /tmp/39TcBOrOwX/qt5-declarative-0.1~git20120402/imports/Qt/labs/folderlistmodel/libqmlfolderlistmodelplugin.so and /tmp/4OL5ZoauBZ/qt5-declarative-0.1~git20120423/imports/Qt/labs/folderlistmodel/libqmlfolderlistmodelplugin.so differ Binary files /tmp/39TcBOrOwX/qt5-declarative-0.1~git20120402/imports/QtQuick/LocalStorage/libqmllocalstorageplugin.so and /tmp/4OL5ZoauBZ/qt5-declarative-0.1~git20120423/imports/QtQuick/LocalStorage/libqmllocalstorageplugin.so differ Binary files /tmp/39TcBOrOwX/qt5-declarative-0.1~git20120402/imports/QtQuick/Particles.2/libparticlesplugin.so and /tmp/4OL5ZoauBZ/qt5-declarative-0.1~git20120423/imports/QtQuick/Particles.2/libparticlesplugin.so differ diff -Nru qt5-declarative-0.1~git20120402/imports/QtQuick/Particles.2/qmldir qt5-declarative-0.1~git20120423/imports/QtQuick/Particles.2/qmldir --- qt5-declarative-0.1~git20120402/imports/QtQuick/Particles.2/qmldir 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/imports/QtQuick/Particles.2/qmldir 2012-04-23 14:34:08.000000000 +0000 @@ -0,0 +1 @@ +plugin particlesplugin Binary files /tmp/39TcBOrOwX/qt5-declarative-0.1~git20120402/imports/QtQuick/Window.2/libwindowplugin.so and /tmp/4OL5ZoauBZ/qt5-declarative-0.1~git20120423/imports/QtQuick/Window.2/libwindowplugin.so differ diff -Nru qt5-declarative-0.1~git20120402/imports/QtQuick/Window.2/qmldir qt5-declarative-0.1~git20120423/imports/QtQuick/Window.2/qmldir --- qt5-declarative-0.1~git20120402/imports/QtQuick/Window.2/qmldir 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/imports/QtQuick/Window.2/qmldir 2012-04-23 14:34:09.000000000 +0000 @@ -0,0 +1 @@ +plugin windowplugin Binary files /tmp/39TcBOrOwX/qt5-declarative-0.1~git20120402/imports/QtQuick/XmlListModel/libqmlxmllistmodelplugin.so and /tmp/4OL5ZoauBZ/qt5-declarative-0.1~git20120423/imports/QtQuick/XmlListModel/libqmlxmllistmodelplugin.so differ diff -Nru qt5-declarative-0.1~git20120402/imports/QtQuick/XmlListModel/qmldir qt5-declarative-0.1~git20120423/imports/QtQuick/XmlListModel/qmldir --- qt5-declarative-0.1~git20120402/imports/QtQuick/XmlListModel/qmldir 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/imports/QtQuick/XmlListModel/qmldir 2012-04-23 14:34:23.000000000 +0000 @@ -0,0 +1 @@ +plugin qmlxmllistmodelplugin \ No newline at end of file Binary files /tmp/39TcBOrOwX/qt5-declarative-0.1~git20120402/imports/QtQuick.2/libqtquick2plugin.so and /tmp/4OL5ZoauBZ/qt5-declarative-0.1~git20120423/imports/QtQuick.2/libqtquick2plugin.so differ Binary files /tmp/39TcBOrOwX/qt5-declarative-0.1~git20120402/imports/QtTest/libqmltestplugin.so and /tmp/4OL5ZoauBZ/qt5-declarative-0.1~git20120423/imports/QtTest/libqmltestplugin.so differ diff -Nru qt5-declarative-0.1~git20120402/imports/QtTest/TestCase.qml qt5-declarative-0.1~git20120423/imports/QtTest/TestCase.qml --- qt5-declarative-0.1~git20120402/imports/QtTest/TestCase.qml 2012-04-02 12:48:12.000000000 +0000 +++ qt5-declarative-0.1~git20120423/imports/QtTest/TestCase.qml 2012-04-23 14:34:20.000000000 +0000 @@ -607,6 +607,10 @@ functionsToRun.splice(index, 1) } qtest_results.functionName = prop + + if (!(datafunc in testCase)) + datafunc = "init_data"; + if (datafunc in testCase) { if (qtest_runInternal(datafunc)) { var table = qtest_testCaseResult @@ -624,9 +628,13 @@ qtest_runFunction(prop, row) qtest_results.dataTag = "" } - if (!haveData) - qtest_results.warn("no data supplied for " + prop + "() by " + datafunc + "()" - , util.callerFile(), util.callerLine()); + if (!haveData) { + if (datafunc === "init_data") + qtest_runFunction(prop, null, isBenchmark) + else + qtest_results.warn("no data supplied for " + prop + "() by " + datafunc + "()" + , util.callerFile(), util.callerLine()); + } qtest_results.clearTestTable() } } else if (isBenchmark) { diff -Nru qt5-declarative-0.1~git20120402/include/QtDeclarative/headers.pri qt5-declarative-0.1~git20120423/include/QtDeclarative/headers.pri --- qt5-declarative-0.1~git20120402/include/QtDeclarative/headers.pri 2012-04-02 12:32:18.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtDeclarative/headers.pri 2012-04-23 14:20:07.000000000 +0000 @@ -1,3 +1,3 @@ -SYNCQT.HEADER_FILES = qtdeclarativeversion.h ../../include/QtDeclarative/qdeclarativeerror.h ../../include/QtDeclarative/QDeclarativeContext ../../include/QtDeclarative/qdeclarativecontext.h ../../include/QtDeclarative/qdeclarativeprivate.h ../../include/QtDeclarative/QDeclarativeListProperty ../../include/QtDeclarative/QDeclarativeIncubationController ../../include/QtDeclarative/QJSValueList ../../include/QtDeclarative/QDeclarativeDebuggingEnabler ../../include/QtDeclarative/qdeclarativeextensionplugin.h ../../include/QtDeclarative/QDeclarativeNetworkAccessManagerFactory ../../include/QtDeclarative/QDeclarativePropertyMap ../../include/QtDeclarative/qdeclarativeincubator.h ../../include/QtDeclarative/QDeclarativeError ../../include/QtDeclarative/QDeclarativeIncubator ../../include/QtDeclarative/qdeclarativelist.h ../../include/QtDeclarative/qdeclarativeparserstatus.h ../../include/QtDeclarative/qjsvalue.h ../../include/QtDeclarative/QDeclarativeProperties ../../include/QtDeclarative/qjsengine.h ../../include/QtDeclarative/qdeclarativenetworkaccessmanagerfactory.h ../../include/QtDeclarative/qdeclarativepropertyvaluesource.h ../../include/QtDeclarative/qdeclarativeexpression.h ../../include/QtDeclarative/QDeclarativeInfo ../../include/QtDeclarative/QtDeclarative ../../include/QtDeclarative/QDeclarativeScriptString ../../include/QtDeclarative/qdeclarativeinfo.h ../../include/QtDeclarative/QDeclarativeComponent ../../include/QtDeclarative/qdeclarativeextensioninterface.h ../../include/QtDeclarative/qdeclarative.h ../../include/QtDeclarative/QDeclarativeParserStatus ../../include/QtDeclarative/QDeclarativeExpression ../../include/QtDeclarative/qdeclarativedebug.h ../../include/QtDeclarative/qdeclarativescriptstring.h ../../include/QtDeclarative/QDeclarativeExtensionInterface ../../include/QtDeclarative/QDeclarativeProperty ../../include/QtDeclarative/QDeclarativeExtensionPlugin ../../include/QtDeclarative/QDeclarativePropertyValueSource ../../include/QtDeclarative/qdeclarativecomponent.h ../../include/QtDeclarative/QDeclarativeAttachedPropertiesFunc ../../include/QtDeclarative/QDeclarativeListReference ../../include/QtDeclarative/qjsvalueiterator.h ../../include/QtDeclarative/qdeclarativeimageprovider.h ../../include/QtDeclarative/QDeclarativeEngine ../../include/QtDeclarative/qdeclarativeproperty.h ../../include/QtDeclarative/qdeclarativeengine.h ../../include/QtDeclarative/QDeclarativeImageProvider ../../include/QtDeclarative/QDeclarativeTypesExtensionInterface ../../include/QtDeclarative/QJSValueIterator ../../include/QtDeclarative/QDeclarativeTextureFactory ../../include/QtDeclarative/QDeclarativeTypeInfo ../../include/QtDeclarative/qdeclarativepropertymap.h ../../include/QtDeclarative/QJSEngine ../../include/QtDeclarative/QJSValue ../../include/QtDeclarative/QtDeclarative +SYNCQT.HEADER_FILES = qtdeclarativeversion.h ../../include/QtDeclarative/QtDeclarative SYNCQT.HEADER_CLASSES = ../../include/QtDeclarative/QtDeclarativeVersion -SYNCQT.PRIVATE_HEADER_FILES = ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativebinding_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qv8profiler_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qv4instruction_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qv8worker_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qrecyclepool_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qv8domerrors_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qv8bindings_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativerewrite_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativeinstruction_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativedirparser_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativedebughelper_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativecontext_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativescriptstring_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativenotifier_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativejsastvisitor_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativevmemetaobject_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativeinspectorservice_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativedebugserverconnection_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qv8sequencewrapper_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativetrace_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativepropertycache_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativelistmodel_p_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qv8variantwrapper_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativescript_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativelocale_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qv8stringwrapper_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativeimport_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qscriptisolate_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qpodvector_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qscriptoriginalglobalobject_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativetypenamecache_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qlistmodelinterface_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativenullablevalue_p_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qv8sqlerrors_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qscriptshareddata_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativejsparser_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativetypenotavailable_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qintrusivelist_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativebuiltinfunctions_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qjsconverter_impl_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qv4compiler_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qparallelanimationgroupjob_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativepool_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativepropertyvalueinterceptor_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qv8variantresource_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativestringconverters_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qpacketprotocol_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativeproperty_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativeguard_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativecustomparser_p_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qv8debug_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativedebugclient_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativejsengine_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativemetatype_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativeincubator_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativecomponentattached_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qv8listwrapper_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qv8_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativedebugservice_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativerefcount_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qscripttools_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qv8engine_impl_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativeexpression_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qv8debugservice_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativejsmemorypool_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativelist_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qv4program_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qjsvalue_impl_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativeenginedebugservice_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativejsastfwd_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qv8sequencewrapper_p_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativeproxymetaobject_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativeenginedebug_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativetypeloader_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qv8valuetypewrapper_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativeengine_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativebinding_p_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qjsvalue_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativecomponent_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qrecursionwatcher_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativecompiler_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativedebugservice_p_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativejsast_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativedebugserver_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qv8profilerservice_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativeopenmetaobject_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qpauseanimationjob_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativecustomparser_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativejsgrammar_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qv8contextwrapper_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qjsconverter_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/textwriter_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativeboundsignal_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativelistmodelworkeragent_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativeaccessors_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativewatcher_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativevaluetype_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativejskeywords_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativeprofilerservice_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qjsvalueiterator_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativejslexer_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qv8engine_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativeapplication_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativecleanup_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativeglobal_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativevme_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativeintegercache_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qjsvalueiterator_impl_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qv8include_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qv8qobjectwrapper_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativejsglobal_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativedebugstatesdelegate_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qv4bindings_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qv4ir_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativedata_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qv4irbuilder_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qscript_impl_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativethread_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativeinspectorinterface_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qv4compiler_p_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativeworkerscript_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qjsengine_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qsequentialanimationgroupjob_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativelistmodel_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qdeclarativexmlhttprequest_p.h ../../include/QtDeclarative/5.0.0/QtDeclarative/private/qv8typewrapper_p.h +SYNCQT.PRIVATE_HEADER_FILES = diff -Nru qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquickage_p.h qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquickage_p.h --- qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquickage_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquickage_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../../../../../src/quick/particles/qquickage_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquickangledirection_p.h qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquickangledirection_p.h --- qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquickangledirection_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquickangledirection_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../../../../../src/quick/particles/qquickangledirection_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquickcumulativedirection_p.h qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquickcumulativedirection_p.h --- qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquickcumulativedirection_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquickcumulativedirection_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../../../../../src/quick/particles/qquickcumulativedirection_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquickcustomaffector_p.h qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquickcustomaffector_p.h --- qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquickcustomaffector_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquickcustomaffector_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../../../../../src/quick/particles/qquickcustomaffector_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquickcustomparticle_p.h qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquickcustomparticle_p.h --- qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquickcustomparticle_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquickcustomparticle_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../../../../../src/quick/particles/qquickcustomparticle_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquickdirection_p.h qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquickdirection_p.h --- qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquickdirection_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquickdirection_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../../../../../src/quick/particles/qquickdirection_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquickellipseextruder_p.h qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquickellipseextruder_p.h --- qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquickellipseextruder_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquickellipseextruder_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../../../../../src/quick/particles/qquickellipseextruder_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquickfriction_p.h qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquickfriction_p.h --- qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquickfriction_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquickfriction_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../../../../../src/quick/particles/qquickfriction_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquickgravity_p.h qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquickgravity_p.h --- qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquickgravity_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquickgravity_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../../../../../src/quick/particles/qquickgravity_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquickgroupgoal_p.h qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquickgroupgoal_p.h --- qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquickgroupgoal_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquickgroupgoal_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../../../../../src/quick/particles/qquickgroupgoal_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquickimageparticle_p.h qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquickimageparticle_p.h --- qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquickimageparticle_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquickimageparticle_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../../../../../src/quick/particles/qquickimageparticle_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquickitemparticle_p.h qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquickitemparticle_p.h --- qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquickitemparticle_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquickitemparticle_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../../../../../src/quick/particles/qquickitemparticle_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquicklineextruder_p.h qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquicklineextruder_p.h --- qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquicklineextruder_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquicklineextruder_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../../../../../src/quick/particles/qquicklineextruder_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquickmaskextruder_p.h qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquickmaskextruder_p.h --- qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquickmaskextruder_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquickmaskextruder_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../../../../../src/quick/particles/qquickmaskextruder_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquickparticleaffector_p.h qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquickparticleaffector_p.h --- qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquickparticleaffector_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquickparticleaffector_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../../../../../src/quick/particles/qquickparticleaffector_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquickparticleemitter_p.h qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquickparticleemitter_p.h --- qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquickparticleemitter_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquickparticleemitter_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../../../../../src/quick/particles/qquickparticleemitter_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquickparticleextruder_p.h qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquickparticleextruder_p.h --- qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquickparticleextruder_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquickparticleextruder_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../../../../../src/quick/particles/qquickparticleextruder_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquickparticlegroup_p.h qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquickparticlegroup_p.h --- qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquickparticlegroup_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquickparticlegroup_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../../../../../src/quick/particles/qquickparticlegroup_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquickparticlepainter_p.h qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquickparticlepainter_p.h --- qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquickparticlepainter_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquickparticlepainter_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../../../../../src/quick/particles/qquickparticlepainter_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquickparticlesmodule_p.h qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquickparticlesmodule_p.h --- qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquickparticlesmodule_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquickparticlesmodule_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../../../../../src/quick/particles/qquickparticlesmodule_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquickparticlesystem_p.h qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquickparticlesystem_p.h --- qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquickparticlesystem_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquickparticlesystem_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../../../../../src/quick/particles/qquickparticlesystem_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquickpointattractor_p.h qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquickpointattractor_p.h --- qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquickpointattractor_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquickpointattractor_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../../../../../src/quick/particles/qquickpointattractor_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquickpointdirection_p.h qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquickpointdirection_p.h --- qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquickpointdirection_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquickpointdirection_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../../../../../src/quick/particles/qquickpointdirection_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquickrectangleextruder_p.h qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquickrectangleextruder_p.h --- qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquickrectangleextruder_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquickrectangleextruder_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../../../../../src/quick/particles/qquickrectangleextruder_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquickspritegoal_p.h qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquickspritegoal_p.h --- qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquickspritegoal_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquickspritegoal_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../../../../../src/quick/particles/qquickspritegoal_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquicktargetdirection_p.h qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquicktargetdirection_p.h --- qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquicktargetdirection_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquicktargetdirection_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../../../../../src/quick/particles/qquicktargetdirection_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquicktrailemitter_p.h qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquicktrailemitter_p.h --- qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquicktrailemitter_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquicktrailemitter_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../../../../../src/quick/particles/qquicktrailemitter_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquickturbulence_p.h qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquickturbulence_p.h --- qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquickturbulence_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquickturbulence_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../../../../../src/quick/particles/qquickturbulence_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquickv8particledata_p.h qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquickv8particledata_p.h --- qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquickv8particledata_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquickv8particledata_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../../../../../src/quick/particles/qquickv8particledata_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquickwander_p.h qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquickwander_p.h --- qt5-declarative-0.1~git20120402/include/QtQuick/5.0.0/QtQuick/private/qquickwander_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuick/5.0.0/QtQuick/private/qquickwander_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../../../../../src/quick/particles/qquickwander_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuick/headers.pri qt5-declarative-0.1~git20120423/include/QtQuick/headers.pri --- qt5-declarative-0.1~git20120402/include/QtQuick/headers.pri 2012-04-02 12:32:18.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuick/headers.pri 2012-04-23 14:04:17.000000000 +0000 @@ -1,3 +1,3 @@ SYNCQT.HEADER_FILES = qtquickglobal.h qtquickversion.h ../quick/designer/designersupport.h ../quick/items/qquickcanvas.h ../quick/items/qquickitem.h ../quick/items/qquickpainteditem.h ../quick/items/qquickview.h ../quick/scenegraph/coreapi/qsggeometry.h ../quick/scenegraph/coreapi/qsgmaterial.h ../quick/scenegraph/coreapi/qsgnode.h ../quick/scenegraph/util/qsgengine.h ../quick/scenegraph/util/qsgflatcolormaterial.h ../quick/scenegraph/util/qsgsimplematerial.h ../quick/scenegraph/util/qsgsimplerectnode.h ../quick/scenegraph/util/qsgsimpletexturenode.h ../quick/scenegraph/util/qsgtexture.h ../quick/scenegraph/util/qsgtexturematerial.h ../quick/scenegraph/util/qsgtextureprovider.h ../quick/scenegraph/util/qsgvertexcolormaterial.h ../../include/QtQuick/QtQuick SYNCQT.HEADER_CLASSES = ../../include/QtQuick/QQuickCanvas ../../include/QtQuick/QQuickTransform ../../include/QtQuick/QQuickItem ../../include/QtQuick/QQuickPaintedItem ../../include/QtQuick/QQuickView ../../include/QtQuick/QSGGeometry ../../include/QtQuick/QSGMaterialShader ../../include/QtQuick/QSGMaterialType ../../include/QtQuick/QSGMaterial ../../include/QtQuick/QSGNode ../../include/QtQuick/QSGBasicGeometryNode ../../include/QtQuick/QSGGeometryNode ../../include/QtQuick/QSGClipNode ../../include/QtQuick/QSGTransformNode ../../include/QtQuick/QSGRootNode ../../include/QtQuick/QSGOpacityNode ../../include/QtQuick/QSGNodeVisitor ../../include/QtQuick/QSGEngine ../../include/QtQuick/QSGFlatColorMaterial ../../include/QtQuick/QSGSimpleMaterialShader ../../include/QtQuick/QSGSimpleMaterial ../../include/QtQuick/QSGSimpleMaterialComparableMaterial ../../include/QtQuick/QSGSimpleRectNode ../../include/QtQuick/QSGSimpleTextureNode ../../include/QtQuick/QSGTexture ../../include/QtQuick/QSGDynamicTexture ../../include/QtQuick/QSGOpaqueTextureMaterial ../../include/QtQuick/QSGTextureMaterial ../../include/QtQuick/QSGTextureProvider ../../include/QtQuick/QSGVertexColorMaterial -SYNCQT.PRIVATE_HEADER_FILES = qtquick2_p.h qtquickglobal_p.h ../quick/items/qquickaccessibleattached_p.h ../quick/items/qquickanchors_p.h ../quick/items/qquickanchors_p_p.h ../quick/items/qquickanimatedimage_p.h ../quick/items/qquickanimatedimage_p_p.h ../quick/items/qquickanimatedsprite_p.h ../quick/items/qquickborderimage_p.h ../quick/items/qquickborderimage_p_p.h ../quick/items/qquickcanvas_p.h ../quick/items/qquickclipnode_p.h ../quick/items/qquickdrag_p.h ../quick/items/qquickdroparea_p.h ../quick/items/qquickevents_p_p.h ../quick/items/qquickflickable_p.h ../quick/items/qquickflickable_p_p.h ../quick/items/qquickflipable_p.h ../quick/items/qquickfocusscope_p.h ../quick/items/qquickgridview_p.h ../quick/items/qquickimage_p.h ../quick/items/qquickimage_p_p.h ../quick/items/qquickimagebase_p.h ../quick/items/qquickimagebase_p_p.h ../quick/items/qquickimplicitsizeitem_p.h ../quick/items/qquickimplicitsizeitem_p_p.h ../quick/items/qquickitem_p.h ../quick/items/qquickitemanimation_p.h ../quick/items/qquickitemanimation_p_p.h ../quick/items/qquickitemchangelistener_p.h ../quick/items/qquickitemsmodule_p.h ../quick/items/qquickitemview_p.h ../quick/items/qquickitemview_p_p.h ../quick/items/qquickitemviewtransition_p.h ../quick/items/qquicklistview_p.h ../quick/items/qquickloader_p.h ../quick/items/qquickloader_p_p.h ../quick/items/qquickmousearea_p.h ../quick/items/qquickmousearea_p_p.h ../quick/items/qquickmultipointtoucharea_p.h ../quick/items/qquickninepatchnode_p.h ../quick/items/qquickpainteditem_p.h ../quick/items/qquickpathview_p.h ../quick/items/qquickpathview_p_p.h ../quick/items/qquickpincharea_p.h ../quick/items/qquickpincharea_p_p.h ../quick/items/qquickpositioners_p.h ../quick/items/qquickpositioners_p_p.h ../quick/items/qquickrectangle_p.h ../quick/items/qquickrectangle_p_p.h ../quick/items/qquickrepeater_p.h ../quick/items/qquickrepeater_p_p.h ../quick/items/qquickscalegrid_p_p.h ../quick/items/qquickscreen_p.h ../quick/items/qquickshadereffect_p.h ../quick/items/qquickshadereffectmesh_p.h ../quick/items/qquickshadereffectnode_p.h ../quick/items/qquickshadereffectsource_p.h ../quick/items/qquicksprite_p.h ../quick/items/qquickspriteengine_p.h ../quick/items/qquickspriteimage_p.h ../quick/items/qquickspritesequence_p.h ../quick/items/qquickstateoperations_p.h ../quick/items/qquicktext_p.h ../quick/items/qquicktext_p_p.h ../quick/items/qquicktextcontrol_p.h ../quick/items/qquicktextcontrol_p_p.h ../quick/items/qquicktextedit_p.h ../quick/items/qquicktextedit_p_p.h ../quick/items/qquicktextinput_p.h ../quick/items/qquicktextinput_p_p.h ../quick/items/qquicktextnode_p.h ../quick/items/qquicktranslate_p.h ../quick/items/qquickview_p.h ../quick/items/qquickvisualadaptormodel_p.h ../quick/items/qquickvisualdatamodel_p.h ../quick/items/qquickvisualdatamodel_p_p.h ../quick/items/qquickvisualitemmodel_p.h ../quick/items/qquickwindowmanager_p.h ../quick/items/qquickwindowmodule_p.h ../quick/particles/qquickage_p.h ../quick/particles/qquickangledirection_p.h ../quick/particles/qquickcumulativedirection_p.h ../quick/particles/qquickcustomaffector_p.h ../quick/particles/qquickcustomparticle_p.h ../quick/particles/qquickdirection_p.h ../quick/particles/qquickellipseextruder_p.h ../quick/particles/qquickfriction_p.h ../quick/particles/qquickgravity_p.h ../quick/particles/qquickgroupgoal_p.h ../quick/particles/qquickimageparticle_p.h ../quick/particles/qquickitemparticle_p.h ../quick/particles/qquicklineextruder_p.h ../quick/particles/qquickmaskextruder_p.h ../quick/particles/qquickparticleaffector_p.h ../quick/particles/qquickparticleemitter_p.h ../quick/particles/qquickparticleextruder_p.h ../quick/particles/qquickparticlegroup_p.h ../quick/particles/qquickparticlepainter_p.h ../quick/particles/qquickparticlesmodule_p.h ../quick/particles/qquickparticlesystem_p.h ../quick/particles/qquickpointattractor_p.h ../quick/particles/qquickpointdirection_p.h ../quick/particles/qquickrectangleextruder_p.h ../quick/particles/qquickspritegoal_p.h ../quick/particles/qquicktargetdirection_p.h ../quick/particles/qquicktrailemitter_p.h ../quick/particles/qquickturbulence_p.h ../quick/particles/qquickv8particledata_p.h ../quick/particles/qquickwander_p.h ../quick/scenegraph/qsgadaptationlayer_p.h ../quick/scenegraph/qsgcontext_p.h ../quick/scenegraph/qsgcontextplugin_p.h ../quick/scenegraph/qsgdefaultdistancefieldglyphcache_p.h ../quick/scenegraph/qsgdefaultglyphnode_p.h ../quick/scenegraph/qsgdefaultglyphnode_p_p.h ../quick/scenegraph/qsgdefaultimagenode_p.h ../quick/scenegraph/qsgdefaultrectanglenode_p.h ../quick/scenegraph/qsgdistancefieldglyphnode_p.h ../quick/scenegraph/qsgdistancefieldglyphnode_p_p.h ../quick/scenegraph/qsgflashnode_p.h ../quick/scenegraph/qsgpathsimplifier_p.h ../quick/scenegraph/qsgshareddistancefieldglyphcache_p.h ../quick/util/qquickanimation_p.h ../quick/util/qquickanimation_p_p.h ../quick/util/qquickanimationcontroller_p.h ../quick/util/qquickbehavior_p.h ../quick/util/qquickbind_p.h ../quick/util/qquickchangeset_p.h ../quick/util/qquickconnections_p.h ../quick/util/qquickfontloader_p.h ../quick/util/qquicklistaccessor_p.h ../quick/util/qquicklistcompositor_p.h ../quick/util/qquickpackage_p.h ../quick/util/qquickpath_p.h ../quick/util/qquickpath_p_p.h ../quick/util/qquickpathinterpolator_p.h ../quick/util/qquickpixmapcache_p.h ../quick/util/qquickpropertychanges_p.h ../quick/util/qquicksmoothedanimation_p.h ../quick/util/qquicksmoothedanimation_p_p.h ../quick/util/qquickspringanimation_p.h ../quick/util/qquickstate_p.h ../quick/util/qquickstate_p_p.h ../quick/util/qquickstatechangescript_p.h ../quick/util/qquickstategroup_p.h ../quick/util/qquickstyledtext_p.h ../quick/util/qquicksvgparser_p.h ../quick/util/qquicksystempalette_p.h ../quick/util/qquicktimeline_p_p.h ../quick/util/qquicktimer_p.h ../quick/util/qquicktransition_p.h ../quick/util/qquicktransitionmanager_p_p.h ../quick/util/qquickutilmodule_p.h ../quick/items/context2d/qquickcanvascontext_p.h ../quick/items/context2d/qquickcanvasitem_p.h ../quick/items/context2d/qquickcontext2d_p.h ../quick/items/context2d/qquickcontext2dcommandbuffer_p.h ../quick/items/context2d/qquickcontext2dtexture_p.h ../quick/items/context2d/qquickcontext2dtile_p.h ../quick/scenegraph/coreapi/qsgdefaultrenderer_p.h ../quick/scenegraph/coreapi/qsggeometry_p.h ../quick/scenegraph/coreapi/qsgnodeupdater_p.h ../quick/scenegraph/coreapi/qsgrenderer_p.h ../quick/scenegraph/coreapi/qsgrendernode_p.h ../quick/scenegraph/util/qsgareaallocator_p.h ../quick/scenegraph/util/qsgdepthstencilbuffer_p.h ../quick/scenegraph/util/qsgdistancefieldutil_p.h ../quick/scenegraph/util/qsgpainternode_p.h ../quick/scenegraph/util/qsgtexture_p.h ../quick/scenegraph/util/qsgtexturematerial_p.h +SYNCQT.PRIVATE_HEADER_FILES = qtquick2_p.h qtquickglobal_p.h ../quick/items/qquickaccessibleattached_p.h ../quick/items/qquickanchors_p.h ../quick/items/qquickanchors_p_p.h ../quick/items/qquickanimatedimage_p.h ../quick/items/qquickanimatedimage_p_p.h ../quick/items/qquickanimatedsprite_p.h ../quick/items/qquickborderimage_p.h ../quick/items/qquickborderimage_p_p.h ../quick/items/qquickcanvas_p.h ../quick/items/qquickclipnode_p.h ../quick/items/qquickdrag_p.h ../quick/items/qquickdroparea_p.h ../quick/items/qquickevents_p_p.h ../quick/items/qquickflickable_p.h ../quick/items/qquickflickable_p_p.h ../quick/items/qquickflipable_p.h ../quick/items/qquickfocusscope_p.h ../quick/items/qquickgridview_p.h ../quick/items/qquickimage_p.h ../quick/items/qquickimage_p_p.h ../quick/items/qquickimagebase_p.h ../quick/items/qquickimagebase_p_p.h ../quick/items/qquickimplicitsizeitem_p.h ../quick/items/qquickimplicitsizeitem_p_p.h ../quick/items/qquickitem_p.h ../quick/items/qquickitemanimation_p.h ../quick/items/qquickitemanimation_p_p.h ../quick/items/qquickitemchangelistener_p.h ../quick/items/qquickitemsmodule_p.h ../quick/items/qquickitemview_p.h ../quick/items/qquickitemview_p_p.h ../quick/items/qquickitemviewtransition_p.h ../quick/items/qquicklistview_p.h ../quick/items/qquickloader_p.h ../quick/items/qquickloader_p_p.h ../quick/items/qquickmousearea_p.h ../quick/items/qquickmousearea_p_p.h ../quick/items/qquickmultipointtoucharea_p.h ../quick/items/qquickninepatchnode_p.h ../quick/items/qquickpainteditem_p.h ../quick/items/qquickpathview_p.h ../quick/items/qquickpathview_p_p.h ../quick/items/qquickpincharea_p.h ../quick/items/qquickpincharea_p_p.h ../quick/items/qquickpositioners_p.h ../quick/items/qquickpositioners_p_p.h ../quick/items/qquickrectangle_p.h ../quick/items/qquickrectangle_p_p.h ../quick/items/qquickrepeater_p.h ../quick/items/qquickrepeater_p_p.h ../quick/items/qquickscalegrid_p_p.h ../quick/items/qquickscreen_p.h ../quick/items/qquickshadereffect_p.h ../quick/items/qquickshadereffectmesh_p.h ../quick/items/qquickshadereffectnode_p.h ../quick/items/qquickshadereffectsource_p.h ../quick/items/qquicksprite_p.h ../quick/items/qquickspriteengine_p.h ../quick/items/qquickspriteimage_p.h ../quick/items/qquickspritesequence_p.h ../quick/items/qquickstateoperations_p.h ../quick/items/qquicktext_p.h ../quick/items/qquicktext_p_p.h ../quick/items/qquicktextcontrol_p.h ../quick/items/qquicktextcontrol_p_p.h ../quick/items/qquicktextedit_p.h ../quick/items/qquicktextedit_p_p.h ../quick/items/qquicktextinput_p.h ../quick/items/qquicktextinput_p_p.h ../quick/items/qquicktextnode_p.h ../quick/items/qquicktranslate_p.h ../quick/items/qquickview_p.h ../quick/items/qquickvisualadaptormodel_p.h ../quick/items/qquickvisualdatamodel_p.h ../quick/items/qquickvisualdatamodel_p_p.h ../quick/items/qquickvisualitemmodel_p.h ../quick/items/qquickwindowmanager_p.h ../quick/items/qquickwindowmodule_p.h ../quick/scenegraph/qsgadaptationlayer_p.h ../quick/scenegraph/qsgcontext_p.h ../quick/scenegraph/qsgcontextplugin_p.h ../quick/scenegraph/qsgdefaultdistancefieldglyphcache_p.h ../quick/scenegraph/qsgdefaultglyphnode_p.h ../quick/scenegraph/qsgdefaultglyphnode_p_p.h ../quick/scenegraph/qsgdefaultimagenode_p.h ../quick/scenegraph/qsgdefaultrectanglenode_p.h ../quick/scenegraph/qsgdistancefieldglyphnode_p.h ../quick/scenegraph/qsgdistancefieldglyphnode_p_p.h ../quick/scenegraph/qsgflashnode_p.h ../quick/scenegraph/qsgpathsimplifier_p.h ../quick/scenegraph/qsgshareddistancefieldglyphcache_p.h ../quick/util/qquickanimation_p.h ../quick/util/qquickanimation_p_p.h ../quick/util/qquickanimationcontroller_p.h ../quick/util/qquickbehavior_p.h ../quick/util/qquickbind_p.h ../quick/util/qquickchangeset_p.h ../quick/util/qquickconnections_p.h ../quick/util/qquickfontloader_p.h ../quick/util/qquicklistaccessor_p.h ../quick/util/qquicklistcompositor_p.h ../quick/util/qquickpackage_p.h ../quick/util/qquickpath_p.h ../quick/util/qquickpath_p_p.h ../quick/util/qquickpathinterpolator_p.h ../quick/util/qquickpixmapcache_p.h ../quick/util/qquickpropertychanges_p.h ../quick/util/qquicksmoothedanimation_p.h ../quick/util/qquicksmoothedanimation_p_p.h ../quick/util/qquickspringanimation_p.h ../quick/util/qquickstate_p.h ../quick/util/qquickstate_p_p.h ../quick/util/qquickstatechangescript_p.h ../quick/util/qquickstategroup_p.h ../quick/util/qquickstyledtext_p.h ../quick/util/qquicksvgparser_p.h ../quick/util/qquicksystempalette_p.h ../quick/util/qquicktimeline_p_p.h ../quick/util/qquicktimer_p.h ../quick/util/qquicktransition_p.h ../quick/util/qquicktransitionmanager_p_p.h ../quick/util/qquickutilmodule_p.h ../quick/items/context2d/qquickcanvascontext_p.h ../quick/items/context2d/qquickcanvasitem_p.h ../quick/items/context2d/qquickcontext2d_p.h ../quick/items/context2d/qquickcontext2dcommandbuffer_p.h ../quick/items/context2d/qquickcontext2dtexture_p.h ../quick/items/context2d/qquickcontext2dtile_p.h ../quick/scenegraph/coreapi/qsgdefaultrenderer_p.h ../quick/scenegraph/coreapi/qsggeometry_p.h ../quick/scenegraph/coreapi/qsgnodeupdater_p.h ../quick/scenegraph/coreapi/qsgrenderer_p.h ../quick/scenegraph/coreapi/qsgrendernode_p.h ../quick/scenegraph/util/qsgareaallocator_p.h ../quick/scenegraph/util/qsgdepthstencilbuffer_p.h ../quick/scenegraph/util/qsgdistancefieldutil_p.h ../quick/scenegraph/util/qsgpainternode_p.h ../quick/scenegraph/util/qsgtexture_p.h ../quick/scenegraph/util/qsgtexturematerial_p.h diff -Nru qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickage_p.h qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickage_p.h --- qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickage_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickage_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1 @@ +#include "../../../../../src/particles/qquickage_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickangledirection_p.h qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickangledirection_p.h --- qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickangledirection_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickangledirection_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1 @@ +#include "../../../../../src/particles/qquickangledirection_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickcumulativedirection_p.h qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickcumulativedirection_p.h --- qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickcumulativedirection_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickcumulativedirection_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1 @@ +#include "../../../../../src/particles/qquickcumulativedirection_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickcustomaffector_p.h qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickcustomaffector_p.h --- qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickcustomaffector_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickcustomaffector_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1 @@ +#include "../../../../../src/particles/qquickcustomaffector_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickcustomparticle_p.h qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickcustomparticle_p.h --- qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickcustomparticle_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickcustomparticle_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1 @@ +#include "../../../../../src/particles/qquickcustomparticle_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickdirection_p.h qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickdirection_p.h --- qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickdirection_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickdirection_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1 @@ +#include "../../../../../src/particles/qquickdirection_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickellipseextruder_p.h qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickellipseextruder_p.h --- qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickellipseextruder_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickellipseextruder_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1 @@ +#include "../../../../../src/particles/qquickellipseextruder_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickfriction_p.h qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickfriction_p.h --- qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickfriction_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickfriction_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1 @@ +#include "../../../../../src/particles/qquickfriction_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickgravity_p.h qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickgravity_p.h --- qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickgravity_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickgravity_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1 @@ +#include "../../../../../src/particles/qquickgravity_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickgroupgoal_p.h qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickgroupgoal_p.h --- qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickgroupgoal_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickgroupgoal_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1 @@ +#include "../../../../../src/particles/qquickgroupgoal_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickimageparticle_p.h qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickimageparticle_p.h --- qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickimageparticle_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickimageparticle_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1 @@ +#include "../../../../../src/particles/qquickimageparticle_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickitemparticle_p.h qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickitemparticle_p.h --- qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickitemparticle_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickitemparticle_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1 @@ +#include "../../../../../src/particles/qquickitemparticle_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquicklineextruder_p.h qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquicklineextruder_p.h --- qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquicklineextruder_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquicklineextruder_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1 @@ +#include "../../../../../src/particles/qquicklineextruder_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickmaskextruder_p.h qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickmaskextruder_p.h --- qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickmaskextruder_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickmaskextruder_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1 @@ +#include "../../../../../src/particles/qquickmaskextruder_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickparticleaffector_p.h qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickparticleaffector_p.h --- qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickparticleaffector_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickparticleaffector_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1 @@ +#include "../../../../../src/particles/qquickparticleaffector_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickparticleemitter_p.h qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickparticleemitter_p.h --- qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickparticleemitter_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickparticleemitter_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1 @@ +#include "../../../../../src/particles/qquickparticleemitter_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickparticleextruder_p.h qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickparticleextruder_p.h --- qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickparticleextruder_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickparticleextruder_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1 @@ +#include "../../../../../src/particles/qquickparticleextruder_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickparticlegroup_p.h qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickparticlegroup_p.h --- qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickparticlegroup_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickparticlegroup_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1 @@ +#include "../../../../../src/particles/qquickparticlegroup_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickparticlepainter_p.h qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickparticlepainter_p.h --- qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickparticlepainter_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickparticlepainter_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1 @@ +#include "../../../../../src/particles/qquickparticlepainter_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickparticlesmodule_p.h qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickparticlesmodule_p.h --- qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickparticlesmodule_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickparticlesmodule_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1 @@ +#include "../../../../../src/particles/qquickparticlesmodule_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickparticlesystem_p.h qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickparticlesystem_p.h --- qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickparticlesystem_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickparticlesystem_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1 @@ +#include "../../../../../src/particles/qquickparticlesystem_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickpointattractor_p.h qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickpointattractor_p.h --- qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickpointattractor_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickpointattractor_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1 @@ +#include "../../../../../src/particles/qquickpointattractor_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickpointdirection_p.h qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickpointdirection_p.h --- qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickpointdirection_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickpointdirection_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1 @@ +#include "../../../../../src/particles/qquickpointdirection_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickrectangleextruder_p.h qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickrectangleextruder_p.h --- qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickrectangleextruder_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickrectangleextruder_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1 @@ +#include "../../../../../src/particles/qquickrectangleextruder_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickspritegoal_p.h qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickspritegoal_p.h --- qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickspritegoal_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickspritegoal_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1 @@ +#include "../../../../../src/particles/qquickspritegoal_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquicktargetdirection_p.h qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquicktargetdirection_p.h --- qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquicktargetdirection_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquicktargetdirection_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1 @@ +#include "../../../../../src/particles/qquicktargetdirection_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquicktrailemitter_p.h qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquicktrailemitter_p.h --- qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquicktrailemitter_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquicktrailemitter_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1 @@ +#include "../../../../../src/particles/qquicktrailemitter_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickturbulence_p.h qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickturbulence_p.h --- qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickturbulence_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickturbulence_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1 @@ +#include "../../../../../src/particles/qquickturbulence_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickv8particledata_p.h qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickv8particledata_p.h --- qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickv8particledata_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickv8particledata_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1 @@ +#include "../../../../../src/particles/qquickv8particledata_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickwander_p.h qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickwander_p.h --- qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickwander_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qquickwander_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1 @@ +#include "../../../../../src/particles/qquickwander_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qtquickparticlesglobal_p.h qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qtquickparticlesglobal_p.h --- qt5-declarative-0.1~git20120402/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qtquickparticlesglobal_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuickParticles/5.0.0/QtQuickParticles/private/qtquickparticlesglobal_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1 @@ +#include "../../../../../src/particles/qtquickparticlesglobal_p.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuickParticles/headers.pri qt5-declarative-0.1~git20120423/include/QtQuickParticles/headers.pri --- qt5-declarative-0.1~git20120402/include/QtQuickParticles/headers.pri 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuickParticles/headers.pri 2012-04-23 14:04:17.000000000 +0000 @@ -0,0 +1,3 @@ +SYNCQT.HEADER_FILES = qtquickparticlesversion.h ../../include/QtQuickParticles/QtQuickParticles +SYNCQT.HEADER_CLASSES = +SYNCQT.PRIVATE_HEADER_FILES = qquickage_p.h qquickangledirection_p.h qquickcumulativedirection_p.h qquickcustomaffector_p.h qquickcustomparticle_p.h qquickdirection_p.h qquickellipseextruder_p.h qquickfriction_p.h qquickgravity_p.h qquickgroupgoal_p.h qquickimageparticle_p.h qquickitemparticle_p.h qquicklineextruder_p.h qquickmaskextruder_p.h qquickparticleaffector_p.h qquickparticleemitter_p.h qquickparticleextruder_p.h qquickparticlegroup_p.h qquickparticlepainter_p.h qquickparticlesmodule_p.h qquickparticlesystem_p.h qquickpointattractor_p.h qquickpointdirection_p.h qquickrectangleextruder_p.h qquickspritegoal_p.h qquicktargetdirection_p.h qquicktrailemitter_p.h qquickturbulence_p.h qquickv8particledata_p.h qquickwander_p.h qtquickparticlesglobal_p.h diff -Nru qt5-declarative-0.1~git20120402/include/QtQuickParticles/QtQuickParticles qt5-declarative-0.1~git20120423/include/QtQuickParticles/QtQuickParticles --- qt5-declarative-0.1~git20120402/include/QtQuickParticles/QtQuickParticles 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuickParticles/QtQuickParticles 2012-04-23 14:04:17.000000000 +0000 @@ -0,0 +1,7 @@ +#ifndef QT_QTQUICKPARTICLES_MODULE_H +#define QT_QTQUICKPARTICLES_MODULE_H +#include +#include +#include +#include "qtquickparticlesversion.h" +#endif diff -Nru qt5-declarative-0.1~git20120402/include/QtQuickParticles/qtquickparticlesversion.h qt5-declarative-0.1~git20120423/include/QtQuickParticles/qtquickparticlesversion.h --- qt5-declarative-0.1~git20120402/include/QtQuickParticles/qtquickparticlesversion.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuickParticles/qtquickparticlesversion.h 2012-04-23 14:04:17.000000000 +0000 @@ -0,0 +1 @@ +#include "../../src/particles/qtquickparticlesversion.h" diff -Nru qt5-declarative-0.1~git20120402/include/QtQuickTest/QtQuickTest qt5-declarative-0.1~git20120423/include/QtQuickTest/QtQuickTest --- qt5-declarative-0.1~git20120402/include/QtQuickTest/QtQuickTest 2012-04-02 12:32:18.000000000 +0000 +++ qt5-declarative-0.1~git20120423/include/QtQuickTest/QtQuickTest 2012-04-23 14:04:17.000000000 +0000 @@ -3,6 +3,7 @@ #include #include #include +#include #include #include "qtquicktestversion.h" #include "quicktest.h" diff -Nru qt5-declarative-0.1~git20120402/lib/cmake/Qt5QuickParticles/Qt5QuickParticlesConfig.cmake qt5-declarative-0.1~git20120423/lib/cmake/Qt5QuickParticles/Qt5QuickParticlesConfig.cmake --- qt5-declarative-0.1~git20120402/lib/cmake/Qt5QuickParticles/Qt5QuickParticlesConfig.cmake 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/lib/cmake/Qt5QuickParticles/Qt5QuickParticlesConfig.cmake 2012-04-23 14:16:17.000000000 +0000 @@ -0,0 +1,49 @@ + +get_filename_component(_qt5QuickParticles_install_prefix "${CMAKE_CURRENT_LIST_DIR}/../../../" ABSOLUTE) + +set(Qt5QuickParticles_VERSION_MAJOR 5) +set(Qt5QuickParticles_VERSION_MINOR 0) +set(Qt5QuickParticles_VERSION_PATCH 0) + +set(Qt5QuickParticles_LIBRARIES Qt5::QuickParticles) + +set(Qt5QuickParticles_INCLUDE_DIRS "${_qt5QuickParticles_install_prefix}/include/" "${_qt5QuickParticles_install_prefix}/include/QtQuickParticles") + +string(TOUPPER QuickParticles _CMAKE_MODULE_NAME_UPPER) +set(Qt5QuickParticles_DEFINITIONS -DQT_${_CMAKE_MODULE_NAME_UPPER}_LIB) +set(Qt5QuickParticles_COMPILE_DEFINITIONS QT_${_CMAKE_MODULE_NAME_UPPER}_LIB) + +set(_Qt5_MODULE_DEPENDENCIES "") + +foreach(_module_dep ${_Qt5_MODULE_DEPENDENCIES}) + if (NOT Qt5${_module_dep}_FOUND) + find_package(Qt5${_module_dep} REQUIRED) + endif() + list(APPEND Qt5QuickParticles_INCLUDE_DIRS ${Qt5${_module_dep}_INCLUDE_DIRS}) + list(APPEND Qt5QuickParticles_DEFINITIONS ${Qt5${_module_dep}_DEFINITIONS}) + list(APPEND Qt5QuickParticles_COMPILE_DEFINITIONS ${Qt5${_module_dep}_COMPILE_DEFINITIONS}) + list(APPEND Qt5QuickParticles_EXECUTABLE_COMPILE_FLAGS ${Qt5${_module_dep}_EXECUTABLE_COMPILE_FLAGS}) +endforeach() +list(REMOVE_DUPLICATES Qt5QuickParticles_INCLUDE_DIRS) +list(REMOVE_DUPLICATES Qt5QuickParticles_DEFINITIONS) +list(REMOVE_DUPLICATES Qt5QuickParticles_COMPILE_DEFINITIONS) +if (Qt5QuickParticles_EXECUTABLE_COMPILE_FLAGS) + list(REMOVE_DUPLICATES Qt5QuickParticles_EXECUTABLE_COMPILE_FLAGS) +endif() + +set(Qt5QuickParticles_LIB_DEPENDENCIES ) + + +if (NOT _Qt5QuickParticles_target) + set(_Qt5QuickParticles_target 1) + add_library(Qt5::QuickParticles SHARED IMPORTED) +endif() + + +set_property(TARGET Qt5::QuickParticles APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE) +set_target_properties(Qt5::QuickParticles PROPERTIES + IMPORTED_LINK_INTERFACE_LIBRARIES_RELEASE "${Qt5QuickParticles_LIB_DEPENDENCIES}" + IMPORTED_LOCATION_RELEASE "${_qt5QuickParticles_install_prefix}/lib/libQtQuickParticles.so.5.0.0" +) + + diff -Nru qt5-declarative-0.1~git20120402/lib/cmake/Qt5QuickParticles/Qt5QuickParticlesConfigVersion.cmake qt5-declarative-0.1~git20120423/lib/cmake/Qt5QuickParticles/Qt5QuickParticlesConfigVersion.cmake --- qt5-declarative-0.1~git20120402/lib/cmake/Qt5QuickParticles/Qt5QuickParticlesConfigVersion.cmake 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/lib/cmake/Qt5QuickParticles/Qt5QuickParticlesConfigVersion.cmake 2012-04-23 14:16:17.000000000 +0000 @@ -0,0 +1,11 @@ + +set(PACKAGE_VERSION 5.0.0) + +if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}") + set(PACKAGE_VERSION_COMPATIBLE FALSE) +else("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}") + set(PACKAGE_VERSION_COMPATIBLE TRUE) + if("${PACKAGE_FIND_VERSION}" STREQUAL "${PACKAGE_VERSION}") + set(PACKAGE_VERSION_EXACT TRUE) + endif("${PACKAGE_FIND_VERSION}" STREQUAL "${PACKAGE_VERSION}") +endif("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}") Binary files /tmp/39TcBOrOwX/qt5-declarative-0.1~git20120402/lib/libQtQmlDevTools.a and /tmp/4OL5ZoauBZ/qt5-declarative-0.1~git20120423/lib/libQtQmlDevTools.a differ diff -Nru qt5-declarative-0.1~git20120402/lib/libQtQmlDevTools.la qt5-declarative-0.1~git20120423/lib/libQtQmlDevTools.la --- qt5-declarative-0.1~git20120402/lib/libQtQmlDevTools.la 2012-04-02 12:48:15.000000000 +0000 +++ qt5-declarative-0.1~git20120423/lib/libQtQmlDevTools.la 2012-04-23 14:34:31.000000000 +0000 @@ -1,5 +1,5 @@ # libQtQmlDevTools.la - a libtool library file -# Generated by qmake/libtool (2.01a) (Qt 5.0.0) on: Mon Apr 2 15:48:15 2012 +# Generated by qmake/libtool (2.01a) (Qt 5.0.0) on: Mon Apr 23 17:34:31 2012 # The name that we can dlopen(3). dlname='' diff -Nru qt5-declarative-0.1~git20120402/lib/libQtQmlDevTools.prl qt5-declarative-0.1~git20120423/lib/libQtQmlDevTools.prl --- qt5-declarative-0.1~git20120402/lib/libQtQmlDevTools.prl 2012-04-02 12:48:15.000000000 +0000 +++ qt5-declarative-0.1~git20120423/lib/libQtQmlDevTools.prl 2012-04-23 14:34:31.000000000 +0000 @@ -1,4 +1,4 @@ -QMAKE_PRL_BUILD_DIR = /home1/kate/qt5/qt5-20120402/qtdeclarative/src/qmldevtools/ +QMAKE_PRL_BUILD_DIR = /home1/kate/qt5/qt5-20120423/qtdeclarative/src/qmldevtools/ QMAKE_PRO_INPUT = qmldevtools.pro QMAKE_PRL_TARGET = libQtQmlDevTools.a QMAKE_PRL_DEFINES = QT_SHARED diff -Nru qt5-declarative-0.1~git20120402/lib/libQtQml.la qt5-declarative-0.1~git20120423/lib/libQtQml.la --- qt5-declarative-0.1~git20120402/lib/libQtQml.la 2012-04-02 12:32:19.000000000 +0000 +++ qt5-declarative-0.1~git20120423/lib/libQtQml.la 2012-04-23 14:20:08.000000000 +0000 @@ -1,5 +1,5 @@ # libQtQml.la - a libtool library file -# Generated by qmake/libtool (2.01a) (Qt 5.0.0) on: Mon Apr 2 15:32:19 2012 +# Generated by qmake/libtool (2.01a) (Qt 5.0.0) on: Mon Apr 23 17:20:08 2012 # The name that we can dlopen(3). dlname='libQtQml.so.5' diff -Nru qt5-declarative-0.1~git20120402/lib/libQtQml.prl qt5-declarative-0.1~git20120423/lib/libQtQml.prl --- qt5-declarative-0.1~git20120402/lib/libQtQml.prl 2012-04-02 12:32:19.000000000 +0000 +++ qt5-declarative-0.1~git20120423/lib/libQtQml.prl 2012-04-23 14:20:08.000000000 +0000 @@ -1,4 +1,4 @@ -QMAKE_PRL_BUILD_DIR = /home1/kate/qt5/qt5-20120402/qtdeclarative/src/qml/ +QMAKE_PRL_BUILD_DIR = /home1/kate/qt5/qt5-20120423/qtdeclarative/src/qml/ QMAKE_PRO_INPUT = qml.pro QMAKE_PRL_TARGET = libQtQml.so.5.0.0 QMAKE_PRL_DEFINES = QT_SHARED diff -Nru qt5-declarative-0.1~git20120402/lib/libQtQuick.la qt5-declarative-0.1~git20120423/lib/libQtQuick.la --- qt5-declarative-0.1~git20120402/lib/libQtQuick.la 2012-04-02 12:37:02.000000000 +0000 +++ qt5-declarative-0.1~git20120423/lib/libQtQuick.la 2012-04-23 14:24:30.000000000 +0000 @@ -1,5 +1,5 @@ # libQtQuick.la - a libtool library file -# Generated by qmake/libtool (2.01a) (Qt 5.0.0) on: Mon Apr 2 15:37:02 2012 +# Generated by qmake/libtool (2.01a) (Qt 5.0.0) on: Mon Apr 23 17:24:30 2012 # The name that we can dlopen(3). dlname='libQtQuick.so.5' @@ -10,7 +10,7 @@ old_library='libQtQuick.a' # Libraries that this one depends upon. -dependency_libs='-L/opt/qt5/lib -L/home1/kate/qt5/qt5-20120402/qtdeclarative/lib -lQtQml -L/opt/qt5/lib -lQtNetwork -lQtGui -lQtV8 -lQtCore -lpthread ' +dependency_libs='-L/opt/qt5/lib -L/home1/kate/qt5/qt5-20120423/qtdeclarative/lib -lQtQml -L/opt/qt5/lib -lQtXmlPatterns -lQtNetwork -lQtGui -lQtV8 -lQtCore -lpthread ' # Version information for libQtQuick.la current=50 diff -Nru qt5-declarative-0.1~git20120402/lib/libQtQuickParticles.la qt5-declarative-0.1~git20120423/lib/libQtQuickParticles.la --- qt5-declarative-0.1~git20120402/lib/libQtQuickParticles.la 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/lib/libQtQuickParticles.la 2012-04-23 14:31:54.000000000 +0000 @@ -0,0 +1,28 @@ +# libQtQuickParticles.la - a libtool library file +# Generated by qmake/libtool (2.01a) (Qt 5.0.0) on: Mon Apr 23 17:31:54 2012 +# The name that we can dlopen(3). +dlname='libQtQuickParticles.so.5' + +# Names of this library. +library_names='libQtQuickParticles.so.5.0.0 libQtQuickParticles.so.5 libQtQuickParticles.so' + +# The name of the static archive. +old_library='libQtQuickParticles.a' + +# Libraries that this one depends upon. +dependency_libs='-L/opt/qt5/lib -L/home1/kate/qt5/qt5-20120423/qtdeclarative/lib -lQtQuick -L/opt/qt5/lib -L/home1/kate/qt5/qt5-20120423/qtdeclarative/lib -lQtQml -lQtXmlPatterns -lQtNetwork -lQtGui -lQtV8 -lQtCore -lpthread ' + +# Version information for libQtQuickParticles.la +current=50 +age=0 +revision=0 + +# Is this an already installed library. +installed=yes + +# Files to dlopen/dlpreopen. +dlopen='' +dlpreopen='' + +# Directory that this library needs to be installed in: +libdir='/opt/qt5/lib' diff -Nru qt5-declarative-0.1~git20120402/lib/libQtQuickParticles.prl qt5-declarative-0.1~git20120423/lib/libQtQuickParticles.prl --- qt5-declarative-0.1~git20120402/lib/libQtQuickParticles.prl 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/lib/libQtQuickParticles.prl 2012-04-23 14:31:54.000000000 +0000 @@ -0,0 +1,7 @@ +QMAKE_PRL_BUILD_DIR = /home1/kate/qt5/qt5-20120423/qtdeclarative/src/particles/ +QMAKE_PRO_INPUT = particles.pro +QMAKE_PRL_TARGET = libQtQuickParticles.so.5.0.0 +QMAKE_PRL_DEFINES = QT_SHARED +QMAKE_PRL_CONFIG = lex yacc warn_on uic resources wayland-scanner qt warn_on release incremental link_prl gdb_dwarf_index qpa exceptions no_mocdepend release stl qt_no_framework create_prl link_prl use_libmysqlclient_r module dll warn_on qt_install_headers qt warn_on depend_includepath qmake_cache target_qt create_cmake hide_symbols bsymbolic_functions create_pc create_libtool explicitlib moc thread opengl shared dll +QMAKE_PRL_VERSION = 5.0.0 +QMAKE_PRL_LIBS = -L/opt/qt5/lib -L/home1/kate/qt5/qt5-20120423/qtdeclarative/lib -lQtQuick -L/opt/qt5/lib -L/home1/kate/qt5/qt5-20120423/qtdeclarative/lib -lQtQml -lQtXmlPatterns -lQtNetwork -lQtGui -lQtV8 -lQtCore -lpthread diff -Nru qt5-declarative-0.1~git20120402/lib/libQtQuick.prl qt5-declarative-0.1~git20120423/lib/libQtQuick.prl --- qt5-declarative-0.1~git20120402/lib/libQtQuick.prl 2012-04-02 12:37:02.000000000 +0000 +++ qt5-declarative-0.1~git20120423/lib/libQtQuick.prl 2012-04-23 14:24:30.000000000 +0000 @@ -1,7 +1,7 @@ -QMAKE_PRL_BUILD_DIR = /home1/kate/qt5/qt5-20120402/qtdeclarative/src/quick/ +QMAKE_PRL_BUILD_DIR = /home1/kate/qt5/qt5-20120423/qtdeclarative/src/quick/ QMAKE_PRO_INPUT = quick.pro QMAKE_PRL_TARGET = libQtQuick.so.5.0.0 QMAKE_PRL_DEFINES = QT_SHARED QMAKE_PRL_CONFIG = lex yacc warn_on uic resources wayland-scanner qt warn_on release incremental link_prl gdb_dwarf_index qpa exceptions no_mocdepend release stl qt_no_framework create_prl link_prl use_libmysqlclient_r module dll warn_on qt_install_headers qt warn_on depend_includepath qmake_cache target_qt create_cmake hide_symbols bsymbolic_functions create_pc create_libtool explicitlib moc thread opengl shared dll QMAKE_PRL_VERSION = 5.0.0 -QMAKE_PRL_LIBS = -L/opt/qt5/lib -L/home1/kate/qt5/qt5-20120402/qtdeclarative/lib -lQtQml -L/opt/qt5/lib -lQtNetwork -lQtGui -lQtV8 -lQtCore -lpthread +QMAKE_PRL_LIBS = -L/opt/qt5/lib -L/home1/kate/qt5/qt5-20120423/qtdeclarative/lib -lQtQml -L/opt/qt5/lib -lQtXmlPatterns -lQtNetwork -lQtGui -lQtV8 -lQtCore -lpthread diff -Nru qt5-declarative-0.1~git20120402/lib/libQtQuickTest.la qt5-declarative-0.1~git20120423/lib/libQtQuickTest.la --- qt5-declarative-0.1~git20120402/lib/libQtQuickTest.la 2012-04-02 12:47:56.000000000 +0000 +++ qt5-declarative-0.1~git20120423/lib/libQtQuickTest.la 2012-04-23 14:33:59.000000000 +0000 @@ -1,5 +1,5 @@ # libQtQuickTest.la - a libtool library file -# Generated by qmake/libtool (2.01a) (Qt 5.0.0) on: Mon Apr 2 15:47:56 2012 +# Generated by qmake/libtool (2.01a) (Qt 5.0.0) on: Mon Apr 23 17:33:59 2012 # The name that we can dlopen(3). dlname='libQtQuickTest.so.5' @@ -10,7 +10,7 @@ old_library='libQtQuickTest.a' # Libraries that this one depends upon. -dependency_libs='-L/opt/qt5/lib -L/home1/kate/qt5/qt5-20120402/qtdeclarative/lib -lQtQuick -L/opt/qt5/lib -L/home1/kate/qt5/qt5-20120402/qtdeclarative/lib -lQtQml -lQtV8 -lQtNetwork -lQtTest -lQtGui -lQtCore -lpthread ' +dependency_libs='-L/opt/qt5/lib -L/home1/kate/qt5/qt5-20120423/qtdeclarative/lib -lQtQuick -L/opt/qt5/lib -L/home1/kate/qt5/qt5-20120423/qtdeclarative/lib -lQtQml -lQtV8 -lQtXmlPatterns -lQtNetwork -lQtTest -lQtGui -lQtCore -lpthread ' # Version information for libQtQuickTest.la current=50 diff -Nru qt5-declarative-0.1~git20120402/lib/libQtQuickTest.prl qt5-declarative-0.1~git20120423/lib/libQtQuickTest.prl --- qt5-declarative-0.1~git20120402/lib/libQtQuickTest.prl 2012-04-02 12:47:56.000000000 +0000 +++ qt5-declarative-0.1~git20120423/lib/libQtQuickTest.prl 2012-04-23 14:33:59.000000000 +0000 @@ -1,7 +1,7 @@ -QMAKE_PRL_BUILD_DIR = /home1/kate/qt5/qt5-20120402/qtdeclarative/src/qmltest/ +QMAKE_PRL_BUILD_DIR = /home1/kate/qt5/qt5-20120423/qtdeclarative/src/qmltest/ QMAKE_PRO_INPUT = qmltest.pro QMAKE_PRL_TARGET = libQtQuickTest.so.5.0.0 QMAKE_PRL_DEFINES = QT_SHARED QMAKE_PRL_CONFIG = lex yacc warn_on uic resources wayland-scanner qt warn_on release incremental link_prl gdb_dwarf_index qpa exceptions no_mocdepend release stl qt_no_framework create_prl link_prl use_libmysqlclient_r module dll warn_on qt_install_headers qt warn_on depend_includepath qmake_cache target_qt create_cmake hide_symbols bsymbolic_functions create_pc create_libtool explicitlib moc thread console opengl shared dll QMAKE_PRL_VERSION = 5.0.0 -QMAKE_PRL_LIBS = -L/opt/qt5/lib -L/home1/kate/qt5/qt5-20120402/qtdeclarative/lib -lQtQuick -L/opt/qt5/lib -L/home1/kate/qt5/qt5-20120402/qtdeclarative/lib -lQtQml -lQtV8 -lQtNetwork -lQtTest -lQtGui -lQtCore -lpthread +QMAKE_PRL_LIBS = -L/opt/qt5/lib -L/home1/kate/qt5/qt5-20120423/qtdeclarative/lib -lQtQuick -L/opt/qt5/lib -L/home1/kate/qt5/qt5-20120423/qtdeclarative/lib -lQtQml -lQtV8 -lQtXmlPatterns -lQtNetwork -lQtTest -lQtGui -lQtCore -lpthread diff -Nru qt5-declarative-0.1~git20120402/lib/pkgconfig/QtQuickParticles.pc qt5-declarative-0.1~git20120423/lib/pkgconfig/QtQuickParticles.pc --- qt5-declarative-0.1~git20120402/lib/pkgconfig/QtQuickParticles.pc 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/lib/pkgconfig/QtQuickParticles.pc 2012-04-23 14:31:54.000000000 +0000 @@ -0,0 +1,18 @@ +prefix=/opt/qt5 +exec_prefix=${prefix} +libdir=${prefix}/lib +includedir=${prefix}/include/QtQuickParticles +qt_config=lex yacc warn_on uic resources wayland-scanner qt warn_on release incremental link_prl gdb_dwarf_index qpa exceptions no_mocdepend release stl qt_no_framework create_prl link_prl use_libmysqlclient_r module dll warn_on qt_install_headers qt warn_on depend_includepath qmake_cache target_qt create_cmake hide_symbols bsymbolic_functions create_pc create_libtool explicitlib moc thread opengl shared dll +moc_location=${prefix}/bin/moc +uic_location=${prefix}/bin/uic +rcc_location=${prefix}/bin/rcc +lupdate_location=${prefix}/bin/lupdate +lrelease_location=${prefix}/bin/lrelease + +Name: Qtquickparticles +Description: Qtquickparticles Library +Version: 5.0.0 +Libs: -L${libdir} -lQtQuickParticles +Libs.private: -L/opt/qt5/lib -L/home1/kate/qt5/qt5-20120423/qtdeclarative/lib -lQtQuick -L/opt/qt5/lib -L/home1/kate/qt5/qt5-20120423/qtdeclarative/lib -lQtQml -lQtXmlPatterns -lQtNetwork -lQtGui -lQtV8 -lQtCore -lpthread -lGL +Cflags: -DQT_SHARED -I/opt/qt5/include -I${includedir} + diff -Nru qt5-declarative-0.1~git20120402/lib/pkgconfig/QtQuick.pc qt5-declarative-0.1~git20120423/lib/pkgconfig/QtQuick.pc --- qt5-declarative-0.1~git20120402/lib/pkgconfig/QtQuick.pc 2012-04-02 12:37:02.000000000 +0000 +++ qt5-declarative-0.1~git20120423/lib/pkgconfig/QtQuick.pc 2012-04-23 14:24:30.000000000 +0000 @@ -13,6 +13,6 @@ Description: Qtquick Library Version: 5.0.0 Libs: -L${libdir} -lQtQuick -Libs.private: -L/opt/qt5/lib -L/home1/kate/qt5/qt5-20120402/qtdeclarative/lib -lQtQml -L/opt/qt5/lib -lQtNetwork -lQtGui -lQtV8 -lQtCore -lpthread -lGL +Libs.private: -L/opt/qt5/lib -L/home1/kate/qt5/qt5-20120423/qtdeclarative/lib -lQtQml -L/opt/qt5/lib -lQtXmlPatterns -lQtNetwork -lQtGui -lQtV8 -lQtCore -lpthread -lGL Cflags: -DQT_SHARED -I/opt/qt5/include -I${includedir} diff -Nru qt5-declarative-0.1~git20120402/lib/pkgconfig/QtQuickTest.pc qt5-declarative-0.1~git20120423/lib/pkgconfig/QtQuickTest.pc --- qt5-declarative-0.1~git20120402/lib/pkgconfig/QtQuickTest.pc 2012-04-02 12:47:56.000000000 +0000 +++ qt5-declarative-0.1~git20120423/lib/pkgconfig/QtQuickTest.pc 2012-04-23 14:33:59.000000000 +0000 @@ -13,6 +13,6 @@ Description: Qtquicktest Library Version: 5.0.0 Libs: -L${libdir} -lQtQuickTest -Libs.private: -L/opt/qt5/lib -L/home1/kate/qt5/qt5-20120402/qtdeclarative/lib -lQtQuick -L/opt/qt5/lib -L/home1/kate/qt5/qt5-20120402/qtdeclarative/lib -lQtQml -lQtV8 -lQtNetwork -lQtTest -lQtGui -lQtCore -lpthread -lGL +Libs.private: -L/opt/qt5/lib -L/home1/kate/qt5/qt5-20120423/qtdeclarative/lib -lQtQuick -L/opt/qt5/lib -L/home1/kate/qt5/qt5-20120423/qtdeclarative/lib -lQtQml -lQtV8 -lQtXmlPatterns -lQtNetwork -lQtTest -lQtGui -lQtCore -lpthread -lGL Cflags: -DQT_SHARED -I/opt/qt5/include -I${includedir} diff -Nru qt5-declarative-0.1~git20120402/module-paths/modules/qt_declarative.pri qt5-declarative-0.1~git20120423/module-paths/modules/qt_declarative.pri --- qt5-declarative-0.1~git20120402/module-paths/modules/qt_declarative.pri 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/module-paths/modules/qt_declarative.pri 2012-04-23 11:44:59.000000000 +0000 @@ -1,7 +1,7 @@ -QT_MODULE_BASE = /home1/kate/qt5/qt5-20120402/qtdeclarative -QT_MODULE_BIN_BASE = /home1/kate/qt5/qt5-20120402/qtdeclarative/bin -QT_MODULE_INCLUDE_BASE = /home1/kate/qt5/qt5-20120402/qtdeclarative/include -QT_MODULE_IMPORT_BASE = /home1/kate/qt5/qt5-20120402/qtdeclarative/imports -QT_MODULE_LIB_BASE = /home1/kate/qt5/qt5-20120402/qtdeclarative/lib -QT_MODULE_PLUGIN_BASE = /home1/kate/qt5/qt5-20120402/qtdeclarative/plugins -include(/home1/kate/qt5/qt5-20120402/qtdeclarative/modules/qt_declarative.pri) +QT_MODULE_BASE = /home1/kate/qt5/qt5-20120423/qtdeclarative +QT_MODULE_BIN_BASE = /home1/kate/qt5/qt5-20120423/qtdeclarative/bin +QT_MODULE_INCLUDE_BASE = /home1/kate/qt5/qt5-20120423/qtdeclarative/include +QT_MODULE_IMPORT_BASE = /home1/kate/qt5/qt5-20120423/qtdeclarative/imports +QT_MODULE_LIB_BASE = /home1/kate/qt5/qt5-20120423/qtdeclarative/lib +QT_MODULE_PLUGIN_BASE = /home1/kate/qt5/qt5-20120423/qtdeclarative/plugins +include(/home1/kate/qt5/qt5-20120423/qtdeclarative/modules/qt_declarative.pri) diff -Nru qt5-declarative-0.1~git20120402/module-paths/modules/qt_qmldevtools.pri qt5-declarative-0.1~git20120423/module-paths/modules/qt_qmldevtools.pri --- qt5-declarative-0.1~git20120402/module-paths/modules/qt_qmldevtools.pri 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/module-paths/modules/qt_qmldevtools.pri 2012-04-23 11:32:40.000000000 +0000 @@ -1,7 +1,7 @@ -QT_MODULE_BASE = /home1/kate/qt5/qt5-20120402/qtdeclarative -QT_MODULE_BIN_BASE = /home1/kate/qt5/qt5-20120402/qtdeclarative/bin -QT_MODULE_INCLUDE_BASE = /home1/kate/qt5/qt5-20120402/qtdeclarative/include -QT_MODULE_IMPORT_BASE = /home1/kate/qt5/qt5-20120402/qtdeclarative/imports -QT_MODULE_LIB_BASE = /home1/kate/qt5/qt5-20120402/qtdeclarative/lib -QT_MODULE_PLUGIN_BASE = /home1/kate/qt5/qt5-20120402/qtdeclarative/plugins -include(/home1/kate/qt5/qt5-20120402/qtdeclarative/modules/qt_qmldevtools.pri) +QT_MODULE_BASE = /home1/kate/qt5/qt5-20120423/qtdeclarative +QT_MODULE_BIN_BASE = /home1/kate/qt5/qt5-20120423/qtdeclarative/bin +QT_MODULE_INCLUDE_BASE = /home1/kate/qt5/qt5-20120423/qtdeclarative/include +QT_MODULE_IMPORT_BASE = /home1/kate/qt5/qt5-20120423/qtdeclarative/imports +QT_MODULE_LIB_BASE = /home1/kate/qt5/qt5-20120423/qtdeclarative/lib +QT_MODULE_PLUGIN_BASE = /home1/kate/qt5/qt5-20120423/qtdeclarative/plugins +include(/home1/kate/qt5/qt5-20120423/qtdeclarative/modules/qt_qmldevtools.pri) diff -Nru qt5-declarative-0.1~git20120402/module-paths/modules/qt_qml.pri qt5-declarative-0.1~git20120423/module-paths/modules/qt_qml.pri --- qt5-declarative-0.1~git20120402/module-paths/modules/qt_qml.pri 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/module-paths/modules/qt_qml.pri 2012-04-23 11:44:59.000000000 +0000 @@ -1,7 +1,7 @@ -QT_MODULE_BASE = /home1/kate/qt5/qt5-20120402/qtdeclarative -QT_MODULE_BIN_BASE = /home1/kate/qt5/qt5-20120402/qtdeclarative/bin -QT_MODULE_INCLUDE_BASE = /home1/kate/qt5/qt5-20120402/qtdeclarative/include -QT_MODULE_IMPORT_BASE = /home1/kate/qt5/qt5-20120402/qtdeclarative/imports -QT_MODULE_LIB_BASE = /home1/kate/qt5/qt5-20120402/qtdeclarative/lib -QT_MODULE_PLUGIN_BASE = /home1/kate/qt5/qt5-20120402/qtdeclarative/plugins -include(/home1/kate/qt5/qt5-20120402/qtdeclarative/modules/qt_qml.pri) +QT_MODULE_BASE = /home1/kate/qt5/qt5-20120423/qtdeclarative +QT_MODULE_BIN_BASE = /home1/kate/qt5/qt5-20120423/qtdeclarative/bin +QT_MODULE_INCLUDE_BASE = /home1/kate/qt5/qt5-20120423/qtdeclarative/include +QT_MODULE_IMPORT_BASE = /home1/kate/qt5/qt5-20120423/qtdeclarative/imports +QT_MODULE_LIB_BASE = /home1/kate/qt5/qt5-20120423/qtdeclarative/lib +QT_MODULE_PLUGIN_BASE = /home1/kate/qt5/qt5-20120423/qtdeclarative/plugins +include(/home1/kate/qt5/qt5-20120423/qtdeclarative/modules/qt_qml.pri) diff -Nru qt5-declarative-0.1~git20120402/module-paths/modules/qt_qmltest.pri qt5-declarative-0.1~git20120423/module-paths/modules/qt_qmltest.pri --- qt5-declarative-0.1~git20120402/module-paths/modules/qt_qmltest.pri 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/module-paths/modules/qt_qmltest.pri 2012-04-23 11:32:40.000000000 +0000 @@ -1,7 +1,7 @@ -QT_MODULE_BASE = /home1/kate/qt5/qt5-20120402/qtdeclarative -QT_MODULE_BIN_BASE = /home1/kate/qt5/qt5-20120402/qtdeclarative/bin -QT_MODULE_INCLUDE_BASE = /home1/kate/qt5/qt5-20120402/qtdeclarative/include -QT_MODULE_IMPORT_BASE = /home1/kate/qt5/qt5-20120402/qtdeclarative/imports -QT_MODULE_LIB_BASE = /home1/kate/qt5/qt5-20120402/qtdeclarative/lib -QT_MODULE_PLUGIN_BASE = /home1/kate/qt5/qt5-20120402/qtdeclarative/plugins -include(/home1/kate/qt5/qt5-20120402/qtdeclarative/modules/qt_qmltest.pri) +QT_MODULE_BASE = /home1/kate/qt5/qt5-20120423/qtdeclarative +QT_MODULE_BIN_BASE = /home1/kate/qt5/qt5-20120423/qtdeclarative/bin +QT_MODULE_INCLUDE_BASE = /home1/kate/qt5/qt5-20120423/qtdeclarative/include +QT_MODULE_IMPORT_BASE = /home1/kate/qt5/qt5-20120423/qtdeclarative/imports +QT_MODULE_LIB_BASE = /home1/kate/qt5/qt5-20120423/qtdeclarative/lib +QT_MODULE_PLUGIN_BASE = /home1/kate/qt5/qt5-20120423/qtdeclarative/plugins +include(/home1/kate/qt5/qt5-20120423/qtdeclarative/modules/qt_qmltest.pri) diff -Nru qt5-declarative-0.1~git20120402/module-paths/modules/qt_quickparticles.pri qt5-declarative-0.1~git20120423/module-paths/modules/qt_quickparticles.pri --- qt5-declarative-0.1~git20120402/module-paths/modules/qt_quickparticles.pri 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/module-paths/modules/qt_quickparticles.pri 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,7 @@ +QT_MODULE_BASE = /home1/kate/qt5/qt5-20120423/qtdeclarative +QT_MODULE_BIN_BASE = /home1/kate/qt5/qt5-20120423/qtdeclarative/bin +QT_MODULE_INCLUDE_BASE = /home1/kate/qt5/qt5-20120423/qtdeclarative/include +QT_MODULE_IMPORT_BASE = /home1/kate/qt5/qt5-20120423/qtdeclarative/imports +QT_MODULE_LIB_BASE = /home1/kate/qt5/qt5-20120423/qtdeclarative/lib +QT_MODULE_PLUGIN_BASE = /home1/kate/qt5/qt5-20120423/qtdeclarative/plugins +include(/home1/kate/qt5/qt5-20120423/qtdeclarative/modules/qt_quickparticles.pri) diff -Nru qt5-declarative-0.1~git20120402/module-paths/modules/qt_quick.pri qt5-declarative-0.1~git20120423/module-paths/modules/qt_quick.pri --- qt5-declarative-0.1~git20120402/module-paths/modules/qt_quick.pri 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/module-paths/modules/qt_quick.pri 2012-04-23 11:32:40.000000000 +0000 @@ -1,7 +1,7 @@ -QT_MODULE_BASE = /home1/kate/qt5/qt5-20120402/qtdeclarative -QT_MODULE_BIN_BASE = /home1/kate/qt5/qt5-20120402/qtdeclarative/bin -QT_MODULE_INCLUDE_BASE = /home1/kate/qt5/qt5-20120402/qtdeclarative/include -QT_MODULE_IMPORT_BASE = /home1/kate/qt5/qt5-20120402/qtdeclarative/imports -QT_MODULE_LIB_BASE = /home1/kate/qt5/qt5-20120402/qtdeclarative/lib -QT_MODULE_PLUGIN_BASE = /home1/kate/qt5/qt5-20120402/qtdeclarative/plugins -include(/home1/kate/qt5/qt5-20120402/qtdeclarative/modules/qt_quick.pri) +QT_MODULE_BASE = /home1/kate/qt5/qt5-20120423/qtdeclarative +QT_MODULE_BIN_BASE = /home1/kate/qt5/qt5-20120423/qtdeclarative/bin +QT_MODULE_INCLUDE_BASE = /home1/kate/qt5/qt5-20120423/qtdeclarative/include +QT_MODULE_IMPORT_BASE = /home1/kate/qt5/qt5-20120423/qtdeclarative/imports +QT_MODULE_LIB_BASE = /home1/kate/qt5/qt5-20120423/qtdeclarative/lib +QT_MODULE_PLUGIN_BASE = /home1/kate/qt5/qt5-20120423/qtdeclarative/plugins +include(/home1/kate/qt5/qt5-20120423/qtdeclarative/modules/qt_quick.pri) diff -Nru qt5-declarative-0.1~git20120402/modules/qt_quickparticles.pri qt5-declarative-0.1~git20120423/modules/qt_quickparticles.pri --- qt5-declarative-0.1~git20120402/modules/qt_quickparticles.pri 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/modules/qt_quickparticles.pri 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,17 @@ +QT.quickparticles.VERSION = 5.0.0 +QT.quickparticles.MAJOR_VERSION = 5 +QT.quickparticles.MINOR_VERSION = 0 +QT.quickparticles.PATCH_VERSION = 0 + +QT.quickparticles.name = QtQuickParticles +QT.quickparticles.bins = $$QT_MODULE_BIN_BASE +QT.quickparticles.includes = $$QT_MODULE_INCLUDE_BASE $$QT_MODULE_INCLUDE_BASE/QtQuickParticles +QT.quickparticles.private_includes = $$QT_MODULE_INCLUDE_BASE/QtQuickParticles/$$QT.quickparticles.VERSION +QT.quickparticles.sources = $$QT_MODULE_BASE/src/particles +QT.quickparticles.libs = $$QT_MODULE_LIB_BASE +QT.quickparticles.plugins = $$QT_MODULE_PLUGIN_BASE +QT.quickparticles.imports = $$QT_MODULE_IMPORT_BASE +QT.quickparticles.depends = qml quick +QT.quickparticles.DEFINES = QT_QUICKPARTICLES_LIB + +QT_CONFIG += quickparticles Binary files /tmp/39TcBOrOwX/qt5-declarative-0.1~git20120402/plugins/qmltooling/libqmldbg_qtquick2.so and /tmp/4OL5ZoauBZ/qt5-declarative-0.1~git20120423/plugins/qmltooling/libqmldbg_qtquick2.so differ Binary files /tmp/39TcBOrOwX/qt5-declarative-0.1~git20120402/plugins/qmltooling/libqmldbg_tcp.so and /tmp/4OL5ZoauBZ/qt5-declarative-0.1~git20120423/plugins/qmltooling/libqmldbg_tcp.so differ diff -Nru qt5-declarative-0.1~git20120402/src/3rdparty/javascriptcore/COPYING.LIB qt5-declarative-0.1~git20120423/src/3rdparty/javascriptcore/COPYING.LIB --- qt5-declarative-0.1~git20120402/src/3rdparty/javascriptcore/COPYING.LIB 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/3rdparty/javascriptcore/COPYING.LIB 1970-01-01 00:00:00.000000000 +0000 @@ -1,488 +0,0 @@ - - -NOTE! The LGPL below is copyrighted by the Free Software Foundation, but -the instance of code that it refers to (the kde libraries) are copyrighted -by the authors who actually wrote it. - ---------------------------------------------------------------------------- - GNU LIBRARY GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1991 Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor - Boston, MA 02110-1301, USA. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the library GPL. It is - numbered 2 because it goes with version 2 of the ordinary GPL.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Library General Public License, applies to some -specially designated Free Software Foundation software, and to any -other libraries whose authors decide to use it. You can use it for -your libraries, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if -you distribute copies of the library, or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link a program with the library, you must provide -complete object files to the recipients so that they can relink them -with the library, after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - Our method of protecting your rights has two steps: (1) copyright -the library, and (2) offer you this license which gives you legal -permission to copy, distribute and/or modify the library. - - Also, for each distributor's protection, we want to make certain -that everyone understands that there is no warranty for this free -library. If the library is modified by someone else and passed on, we -want its recipients to know that what they have is not the original -version, so that any problems introduced by others will not reflect on -the original authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that companies distributing free -software will individually obtain patent licenses, thus in effect -transforming the program into proprietary software. To prevent this, -we have made it clear that any patent must be licensed for everyone's -free use or not licensed at all. - - Most GNU software, including some libraries, is covered by the ordinary -GNU General Public License, which was designed for utility programs. This -license, the GNU Library General Public License, applies to certain -designated libraries. This license is quite different from the ordinary -one; be sure to read it in full, and don't assume that anything in it is -the same as in the ordinary license. - - The reason we have a separate public license for some libraries is that -they blur the distinction we usually make between modifying or adding to a -program and simply using it. Linking a program with a library, without -changing the library, is in some sense simply using the library, and is -analogous to running a utility program or application program. However, in -a textual and legal sense, the linked executable is a combined work, a -derivative of the original library, and the ordinary General Public License -treats it as such. - - Because of this blurred distinction, using the ordinary General -Public License for libraries did not effectively promote software -sharing, because most developers did not use the libraries. We -concluded that weaker conditions might promote sharing better. - - However, unrestricted linking of non-free programs would deprive the -users of those programs of all benefit from the free status of the -libraries themselves. This Library General Public License is intended to -permit developers of non-free programs to use free libraries, while -preserving your freedom as a user of such programs to change the free -libraries that are incorporated in them. (We have not seen how to achieve -this as regards changes in header files, but we have achieved it as regards -changes in the actual functions of the Library.) The hope is that this -will lead to faster development of free libraries. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, while the latter only -works together with the library. - - Note that it is possible for a library to be covered by the ordinary -General Public License rather than by this special one. - - GNU LIBRARY GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library which -contains a notice placed by the copyright holder or other authorized -party saying it may be distributed under the terms of this Library -General Public License (also called "this License"). Each licensee is -addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also compile or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - c) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - d) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the source code distributed need not include anything that is normally -distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Library General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! diff -Nru qt5-declarative-0.1~git20120402/src/3rdparty/javascriptcore/DateMath.cpp qt5-declarative-0.1~git20120423/src/3rdparty/javascriptcore/DateMath.cpp --- qt5-declarative-0.1~git20120402/src/3rdparty/javascriptcore/DateMath.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/3rdparty/javascriptcore/DateMath.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,393 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. - * Copyright (C) 2009 Google Inc. All rights reserved. - * Copyright (C) 2007-2009 Torch Mobile, Inc. - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Alternatively, the contents of this file may be used under the terms - * of either the Mozilla Public License Version 1.1, found at - * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public - * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html - * (the "GPL"), in which case the provisions of the MPL or the GPL are - * applicable instead of those above. If you wish to allow use of your - * version of this file only under the terms of one of those two - * licenses (the MPL or the GPL) and not to allow others to use your - * version of this file under the LGPL, indicate your decision by - * deletingthe provisions above and replace them with the notice and - * other provisions required by the MPL or the GPL, as the case may be. - * If you do not delete the provisions above, a recipient may use your - * version of this file under any of the LGPL, the MPL or the GPL. - - * Copyright 2006-2008 the V8 project authors. All rights reserved. - * 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 Google Inc. 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. - */ - -#include "DateMath.h" - -#include -#include -#include -#include -#include - -//#if HAVE(SYS_TIME_H) -#if defined(EXISTS_SYS_TIME) -#include -#endif - -//#if HAVE(SYS_TIMEB_H) -#if defined(EXISTS_SYS_TIMEB) -#include -#endif - -#define NaN std::numeric_limits::quiet_NaN() - -using namespace QV8DateConverter::WTF; - -namespace QV8DateConverter { - -namespace WTF { - -/* Constants */ - -static const double minutesPerDay = 24.0 * 60.0; -static const double secondsPerDay = 24.0 * 60.0 * 60.0; -static const double secondsPerYear = 24.0 * 60.0 * 60.0 * 365.0; - -static const double usecPerSec = 1000000.0; - -static const double maxUnixTime = 2145859200.0; // 12/31/2037 -// ECMAScript asks not to support for a date of which total -// millisecond value is larger than the following value. -// See 15.9.1.14 of ECMA-262 5th edition. -static const double maxECMAScriptTime = 8.64E15; - -// Day of year for the first day of each month, where index 0 is January, and day 0 is January 1. -// First for non-leap years, then for leap years. -static const int firstDayOfMonth[2][12] = { - {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}, - {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335} -}; - -static inline bool isLeapYear(int year) -{ - if (year % 4 != 0) - return false; - if (year % 400 == 0) - return true; - if (year % 100 == 0) - return false; - return true; -} - -static inline int daysInYear(int year) -{ - return 365 + isLeapYear(year); -} - -static inline double daysFrom1970ToYear(int year) -{ - // The Gregorian Calendar rules for leap years: - // Every fourth year is a leap year. 2004, 2008, and 2012 are leap years. - // However, every hundredth year is not a leap year. 1900 and 2100 are not leap years. - // Every four hundred years, there's a leap year after all. 2000 and 2400 are leap years. - - static const int leapDaysBefore1971By4Rule = 1970 / 4; - static const int excludedLeapDaysBefore1971By100Rule = 1970 / 100; - static const int leapDaysBefore1971By400Rule = 1970 / 400; - - const double yearMinusOne = year - 1; - const double yearsToAddBy4Rule = floor(yearMinusOne / 4.0) - leapDaysBefore1971By4Rule; - const double yearsToExcludeBy100Rule = floor(yearMinusOne / 100.0) - excludedLeapDaysBefore1971By100Rule; - const double yearsToAddBy400Rule = floor(yearMinusOne / 400.0) - leapDaysBefore1971By400Rule; - - return 365.0 * (year - 1970) + yearsToAddBy4Rule - yearsToExcludeBy100Rule + yearsToAddBy400Rule; -} - -static inline double msToDays(double ms) -{ - return floor(ms / msPerDay); -} - -int msToYear(double ms) -{ - int approxYear = static_cast(floor(ms / (msPerDay * 365.2425)) + 1970); - double msFromApproxYearTo1970 = msPerDay * daysFrom1970ToYear(approxYear); - if (msFromApproxYearTo1970 > ms) - return approxYear - 1; - if (msFromApproxYearTo1970 + msPerDay * daysInYear(approxYear) <= ms) - return approxYear + 1; - return approxYear; -} - -int dayInYear(double ms, int year) -{ - return static_cast(msToDays(ms) - daysFrom1970ToYear(year)); -} - -static inline double msToMilliseconds(double ms) -{ - double result = fmod(ms, msPerDay); - if (result < 0) - result += msPerDay; - return result; -} - -// 0: Sunday, 1: Monday, etc. -static inline int msToWeekDay(double ms) -{ - int wd = (static_cast(msToDays(ms)) + 4) % 7; - if (wd < 0) - wd += 7; - return wd; -} - -static inline int msToSeconds(double ms) -{ - double result = fmod(floor(ms / msPerSecond), secondsPerMinute); - if (result < 0) - result += secondsPerMinute; - return static_cast(result); -} - -static inline int msToMinutes(double ms) -{ - double result = fmod(floor(ms / msPerMinute), minutesPerHour); - if (result < 0) - result += minutesPerHour; - return static_cast(result); -} - -static inline int msToHours(double ms) -{ - double result = fmod(floor(ms/msPerHour), hoursPerDay); - if (result < 0) - result += hoursPerDay; - return static_cast(result); -} - -int monthFromDayInYear(int dayInYear, bool leapYear) -{ - const int d = dayInYear; - int step; - - if (d < (step = 31)) - return 0; - step += (leapYear ? 29 : 28); - if (d < step) - return 1; - if (d < (step += 31)) - return 2; - if (d < (step += 30)) - return 3; - if (d < (step += 31)) - return 4; - if (d < (step += 30)) - return 5; - if (d < (step += 31)) - return 6; - if (d < (step += 31)) - return 7; - if (d < (step += 30)) - return 8; - if (d < (step += 31)) - return 9; - if (d < (step += 30)) - return 10; - return 11; -} - -static inline bool checkMonth(int dayInYear, int& startDayOfThisMonth, int& startDayOfNextMonth, int daysInThisMonth) -{ - startDayOfThisMonth = startDayOfNextMonth; - startDayOfNextMonth += daysInThisMonth; - return (dayInYear <= startDayOfNextMonth); -} - -int dayInMonthFromDayInYear(int dayInYear, bool leapYear) -{ - const int d = dayInYear; - int step; - int next = 30; - - if (d <= next) - return d + 1; - const int daysInFeb = (leapYear ? 29 : 28); - if (checkMonth(d, step, next, daysInFeb)) - return d - step; - if (checkMonth(d, step, next, 31)) - return d - step; - if (checkMonth(d, step, next, 30)) - return d - step; - if (checkMonth(d, step, next, 31)) - return d - step; - if (checkMonth(d, step, next, 30)) - return d - step; - if (checkMonth(d, step, next, 31)) - return d - step; - if (checkMonth(d, step, next, 31)) - return d - step; - if (checkMonth(d, step, next, 30)) - return d - step; - if (checkMonth(d, step, next, 31)) - return d - step; - if (checkMonth(d, step, next, 30)) - return d - step; - step = next; - return d - step; -} - -static inline int monthToDayInYear(int month, bool isLeapYear) -{ - return firstDayOfMonth[isLeapYear][month]; -} - -static inline double timeToMS(double hour, double min, double sec, double ms) -{ - return (((hour * minutesPerHour + min) * secondsPerMinute + sec) * msPerSecond + ms); -} - -double dateToDaysFrom1970(int year, int month, int day) -{ - year += month / 12; - - month %= 12; - if (month < 0) { - month += 12; - --year; - } - - double yearday = floor(daysFrom1970ToYear(year)); - int monthday = monthToDayInYear(month, isLeapYear(year)); - - return yearday + monthday + day - 1; -} - -static inline double ymdhmsToSeconds(long year, int mon, int day, int hour, int minute, int second) -{ - double days = (day - 32075) - + floor(1461 * (year + 4800.0 + (mon - 14) / 12) / 4) - + 367 * (mon - 2 - (mon - 14) / 12 * 12) / 12 - - floor(3 * ((year + 4900.0 + (mon - 14) / 12) / 100) / 4) - - 2440588; - return ((days * hoursPerDay + hour) * minutesPerHour + minute) * secondsPerMinute + second; -} - -// We follow the recommendation of RFC 2822 to consider all -// obsolete time zones not listed here equivalent to "-0000". -static const struct KnownZone { - const - char tzName[4]; - int tzOffset; -} known_zones[] = { - { "UT", 0 }, - { "GMT", 0 }, - { "EST", -300 }, - { "EDT", -240 }, - { "CST", -360 }, - { "CDT", -300 }, - { "MST", -420 }, - { "MDT", -360 }, - { "PST", -480 }, - { "PDT", -420 } -}; - -double timeClip(double t) -{ -#if defined(_MSC_VER) - if (!_finite(t) || fabs(t) > maxECMAScriptTime) - return NaN; - return t >= 0 ? floor(t) : ceil(t); -#else - -#if defined(__QNXNTO__) - if (!isfinite(t) || fabs(t) > maxECMAScriptTime) - return NaN; -#else - if (!std::isfinite(t) || fabs(t) > maxECMAScriptTime) - return NaN; -#endif - - return trunc(t); -#endif -} -} // namespace WTF - -namespace JSC { - -double gregorianDateTimeToMS(const GregorianDateTime& t, double milliSeconds) -{ - double day = dateToDaysFrom1970(t.year + 1900, t.month, t.monthDay); - double ms = timeToMS(t.hour, t.minute, t.second, milliSeconds); - double result = (day * WTF::msPerDay) + ms; - - return result; -} - -// input is UTC -void msToGregorianDateTime(double ms, GregorianDateTime& tm) -{ - const int year = msToYear(ms); - tm.second = msToSeconds(ms); - tm.minute = msToMinutes(ms); - tm.hour = msToHours(ms); - tm.weekDay = msToWeekDay(ms); - tm.yearDay = dayInYear(ms, year); - tm.monthDay = dayInMonthFromDayInYear(tm.yearDay, isLeapYear(year)); - tm.month = monthFromDayInYear(tm.yearDay, isLeapYear(year)); - tm.year = year - 1900; - tm.isDST = false; - tm.utcOffset = static_cast(0); // no ExecState :. cannot calculate offset. Assume UTC output. - tm.timeZone = NULL; -} - -} // namespace JSC - -} // namespace QV8DateConverter - diff -Nru qt5-declarative-0.1~git20120402/src/3rdparty/javascriptcore/DateMath.h qt5-declarative-0.1~git20120423/src/3rdparty/javascriptcore/DateMath.h --- qt5-declarative-0.1~git20120402/src/3rdparty/javascriptcore/DateMath.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/3rdparty/javascriptcore/DateMath.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,190 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. - * Copyright (C) 2009 Google Inc. All rights reserved. - * - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - */ - -#ifndef DateMath_h -#define DateMath_h - -#include -#include -#include - -namespace QV8DateConverter { - -namespace WTF { - -double timeClip(double); - -const char * const weekdayName[7] = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" }; -const char * const monthName[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; - -const double hoursPerDay = 24.0; -const double minutesPerHour = 60.0; -const double secondsPerHour = 60.0 * 60.0; -const double secondsPerMinute = 60.0; -const double msPerSecond = 1000.0; -const double msPerMinute = 60.0 * 1000.0; -const double msPerHour = 60.0 * 60.0 * 1000.0; -const double msPerDay = 24.0 * 60.0 * 60.0 * 1000.0; -const double msPerMonth = 2592000000.0; - -// Returns the number of days from 1970-01-01 to the specified date. -double dateToDaysFrom1970(int year, int month, int day); -int msToYear(double ms); -int dayInYear(double ms, int year); -int monthFromDayInYear(int dayInYear, bool leapYear); -int dayInMonthFromDayInYear(int dayInYear, bool leapYear); - -} // namespace WTF - -using WTF::dateToDaysFrom1970; -using WTF::dayInMonthFromDayInYear; -using WTF::dayInYear; -using WTF::minutesPerHour; -using WTF::monthFromDayInYear; -using WTF::msPerDay; -using WTF::msPerSecond; -using WTF::msToYear; -using WTF::secondsPerMinute; - -namespace JSC { -struct GregorianDateTime; - -void msToGregorianDateTime(double, GregorianDateTime&); -double gregorianDateTimeToMS(const GregorianDateTime&, double); - -// Intentionally overridding the default tm of the system. -// The members of tm differ on various operating systems. -struct GregorianDateTime { - GregorianDateTime() - : second(0) - , minute(0) - , hour(0) - , weekDay(0) - , monthDay(0) - , yearDay(0) - , month(0) - , year(0) - , isDST(0) - , utcOffset(0) - , timeZone(0) - { - } - - ~GregorianDateTime() - { - delete [] timeZone; - } - - GregorianDateTime(const tm& inTm) - : second(inTm.tm_sec) - , minute(inTm.tm_min) - , hour(inTm.tm_hour) - , weekDay(inTm.tm_wday) - , monthDay(inTm.tm_mday) - , yearDay(inTm.tm_yday) - , month(inTm.tm_mon) - , year(inTm.tm_year) - , isDST(inTm.tm_isdst) - { - utcOffset = static_cast(0); - timeZone = 0; - } - - operator tm() const - { - tm ret; - memset(&ret, 0, sizeof(ret)); - - ret.tm_sec = second; - ret.tm_min = minute; - ret.tm_hour = hour; - ret.tm_wday = weekDay; - ret.tm_mday = monthDay; - ret.tm_yday = yearDay; - ret.tm_mon = month; - ret.tm_year = year; - ret.tm_isdst = isDST; - return ret; - } - - void copyFrom(const GregorianDateTime& rhs) - { - second = rhs.second; - minute = rhs.minute; - hour = rhs.hour; - weekDay = rhs.weekDay; - monthDay = rhs.monthDay; - yearDay = rhs.yearDay; - month = rhs.month; - year = rhs.year; - isDST = rhs.isDST; - utcOffset = rhs.utcOffset; - if (rhs.timeZone) { - int inZoneSize = strlen(rhs.timeZone) + 1; - timeZone = new char[inZoneSize]; - strncpy(timeZone, rhs.timeZone, inZoneSize); - } else - timeZone = 0; - } - - int second; - int minute; - int hour; - int weekDay; - int monthDay; - int yearDay; - int month; - int year; - int isDST; - int utcOffset; - char* timeZone; -}; - -static inline int gmtoffset(const GregorianDateTime& t) -{ - return t.utcOffset; -} - -} // namespace JSC - -} // namespace QV8DateConverter - -#endif // DateMath_h diff -Nru qt5-declarative-0.1~git20120402/src/3rdparty/javascriptcore/VERSION qt5-declarative-0.1~git20120423/src/3rdparty/javascriptcore/VERSION --- qt5-declarative-0.1~git20120402/src/3rdparty/javascriptcore/VERSION 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/3rdparty/javascriptcore/VERSION 1970-01-01 00:00:00.000000000 +0000 @@ -1,15 +0,0 @@ -This is a snapshot of the files: DateMath.h and DateMath.cpp -from a snapshot of JavaScriptCore from - - git://gitorious.org/qtwebkit/qtwebkit.git - -The commit imported was from the - - javascriptcore-snapshot-27012011 branch/tag - -and has the sha1 checksum - - 3ab0f621048fbeb480b687a28ed31d92d8506150 - -The two files were then modified slightly so that unneeded -functionality was removed (mostly regarding timezone offset). diff -Nru qt5-declarative-0.1~git20120402/src/imports/imports.pro qt5-declarative-0.1~git20120423/src/imports/imports.pro --- qt5-declarative-0.1~git20120402/src/imports/imports.pro 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/imports/imports.pro 2012-04-23 11:32:40.000000000 +0000 @@ -1,5 +1,5 @@ TEMPLATE = subdirs -SUBDIRS += qtquick2 folderlistmodel localstorage +SUBDIRS += qtquick2 particles window folderlistmodel localstorage contains(QT_CONFIG, qmltest): SUBDIRS += testlib contains(QT_CONFIG, xmlpatterns) : SUBDIRS += xmllistmodel diff -Nru qt5-declarative-0.1~git20120402/src/imports/particles/particles.pro qt5-declarative-0.1~git20120423/src/imports/particles/particles.pro --- qt5-declarative-0.1~git20120402/src/imports/particles/particles.pro 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/imports/particles/particles.pro 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,19 @@ +TARGET = particlesplugin +TARGETPATH = QtQuick/Particles.2 +include(../qimportbase.pri) + +SOURCES += \ + plugin.cpp + +QT += quick-private quickparticles-private qml-private + +OTHER_FILES += \ + qmldir + +DESTDIR = $$QT.qml.imports/$$TARGETPATH +target.path = $$[QT_INSTALL_IMPORTS]/$$TARGETPATH + +qmldir.files += $$PWD/qmldir +qmldir.path += $$[QT_INSTALL_IMPORTS]/$$TARGETPATH + +INSTALLS += target qmldir diff -Nru qt5-declarative-0.1~git20120402/src/imports/particles/plugin.cpp qt5-declarative-0.1~git20120423/src/imports/particles/plugin.cpp --- qt5-declarative-0.1~git20120402/src/imports/particles/plugin.cpp 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/imports/particles/plugin.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include + +QT_BEGIN_NAMESPACE + +//![class decl] +class QtQuick2ParticlesPlugin : public QQmlExtensionPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface/1.0") +public: + virtual void registerTypes(const char *uri) + { + Q_ASSERT(QLatin1String(uri) == QLatin1String("QtQuick.Particles")); + Q_UNUSED(uri); + QQuickParticlesModule::defineModule(); + } +}; +//![class decl] + +QT_END_NAMESPACE + +#include "plugin.moc" diff -Nru qt5-declarative-0.1~git20120402/src/imports/particles/qmldir qt5-declarative-0.1~git20120423/src/imports/particles/qmldir --- qt5-declarative-0.1~git20120402/src/imports/particles/qmldir 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/imports/particles/qmldir 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1 @@ +plugin particlesplugin diff -Nru qt5-declarative-0.1~git20120402/src/imports/testlib/testcase.qdoc qt5-declarative-0.1~git20120423/src/imports/testlib/testcase.qdoc --- qt5-declarative-0.1~git20120402/src/imports/testlib/testcase.qdoc 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/imports/testlib/testcase.qdoc 2012-04-23 11:32:40.000000000 +0000 @@ -51,8 +51,8 @@ element: \code - import QtQuick 1.0 - import QtQuickTest 1.0 + import QtQuick 2.0 + import QtTest 1.0 TestCase { name: "MathTests" @@ -97,15 +97,24 @@ \section1 Data-driven tests Table data can be provided to a test using a function name that ends - with "_data": + with "_data". Alternatively, the \c init_data() function can be used + to provide default test data for all test functions in a TestCase element: + \code - import QtQuick 1.0 - import QtQuickTest 1.0 + import QtQuick 2.0 + import QtTest 1.0 TestCase { name: "DataTests" + function init_data() { + return [ + {tag:"init_data_1", a:1, b:2, answer: 3}, + {tag:"init_data_2", a:2, b:4, answer: 6} + ]; + } + function test_table_data() { return [ {tag: "2 + 2 = 4", a: 2, b: 2, answer: 4 }, @@ -114,6 +123,12 @@ } function test_table(data) { + //data comes from test_table_data + compare(data.a + data.b, data.answer) + } + + function test__default_table(data) { + //data comes from init_data compare(data.a + data.b, data.answer) } } diff -Nru qt5-declarative-0.1~git20120402/src/imports/testlib/TestCase.qml qt5-declarative-0.1~git20120423/src/imports/testlib/TestCase.qml --- qt5-declarative-0.1~git20120402/src/imports/testlib/TestCase.qml 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/imports/testlib/TestCase.qml 2012-04-23 11:44:59.000000000 +0000 @@ -607,6 +607,10 @@ functionsToRun.splice(index, 1) } qtest_results.functionName = prop + + if (!(datafunc in testCase)) + datafunc = "init_data"; + if (datafunc in testCase) { if (qtest_runInternal(datafunc)) { var table = qtest_testCaseResult @@ -624,9 +628,13 @@ qtest_runFunction(prop, row) qtest_results.dataTag = "" } - if (!haveData) - qtest_results.warn("no data supplied for " + prop + "() by " + datafunc + "()" - , util.callerFile(), util.callerLine()); + if (!haveData) { + if (datafunc === "init_data") + qtest_runFunction(prop, null, isBenchmark) + else + qtest_results.warn("no data supplied for " + prop + "() by " + datafunc + "()" + , util.callerFile(), util.callerLine()); + } qtest_results.clearTestTable() } } else if (isBenchmark) { diff -Nru qt5-declarative-0.1~git20120402/src/imports/window/plugin.cpp qt5-declarative-0.1~git20120423/src/imports/window/plugin.cpp --- qt5-declarative-0.1~git20120402/src/imports/window/plugin.cpp 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/imports/window/plugin.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include + +QT_BEGIN_NAMESPACE + +//![class decl] +class QtQuick2WindowPlugin : public QQmlExtensionPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface/1.0") +public: + virtual void registerTypes(const char *uri) + { + Q_ASSERT(QLatin1String(uri) == QLatin1String("QtQuick.Window")); + Q_UNUSED(uri); + QQuickWindowModule::defineModule(); + } +}; +//![class decl] + +QT_END_NAMESPACE + +#include "plugin.moc" diff -Nru qt5-declarative-0.1~git20120402/src/imports/window/qmldir qt5-declarative-0.1~git20120423/src/imports/window/qmldir --- qt5-declarative-0.1~git20120402/src/imports/window/qmldir 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/imports/window/qmldir 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1 @@ +plugin windowplugin diff -Nru qt5-declarative-0.1~git20120402/src/imports/window/window.pro qt5-declarative-0.1~git20120423/src/imports/window/window.pro --- qt5-declarative-0.1~git20120402/src/imports/window/window.pro 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/imports/window/window.pro 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,19 @@ +TARGET = windowplugin +TARGETPATH = QtQuick/Window.2 +include(../qimportbase.pri) + +SOURCES += \ + plugin.cpp + +QT += quick-private qml-private + +OTHER_FILES += \ + qmldir + +DESTDIR = $$QT.qml.imports/$$TARGETPATH +target.path = $$[QT_INSTALL_IMPORTS]/$$TARGETPATH + +qmldir.files += $$PWD/qmldir +qmldir.path += $$[QT_INSTALL_IMPORTS]/$$TARGETPATH + +INSTALLS += target qmldir Binary files /tmp/39TcBOrOwX/qt5-declarative-0.1~git20120402/src/particles/particleresources/noise.png and /tmp/4OL5ZoauBZ/qt5-declarative-0.1~git20120423/src/particles/particleresources/noise.png differ diff -Nru qt5-declarative-0.1~git20120402/src/particles/particles.pri qt5-declarative-0.1~git20120423/src/particles/particles.pri --- qt5-declarative-0.1~git20120402/src/particles/particles.pri 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/particles.pri 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,70 @@ +HEADERS += \ + $$PWD/qquickangledirection_p.h \ + $$PWD/qquickcustomparticle_p.h \ + $$PWD/qquickcustomaffector_p.h \ + $$PWD/qquickellipseextruder_p.h \ + $$PWD/qquicktrailemitter_p.h \ + $$PWD/qquickfriction_p.h \ + $$PWD/qquickgravity_p.h \ + $$PWD/qquickimageparticle_p.h \ + $$PWD/qquickitemparticle_p.h \ + $$PWD/qquickage_p.h \ + $$PWD/qquicklineextruder_p.h \ + $$PWD/qquickmaskextruder_p.h \ + $$PWD/qquickparticleaffector_p.h \ + $$PWD/qquickparticleemitter_p.h \ + $$PWD/qquickparticleextruder_p.h \ + $$PWD/qquickparticlepainter_p.h \ + $$PWD/qquickparticlesmodule_p.h \ + $$PWD/qquickparticlesystem_p.h \ + $$PWD/qquickpointattractor_p.h \ + $$PWD/qquickpointdirection_p.h \ + $$PWD/qquickspritegoal_p.h \ + $$PWD/qquickdirection_p.h \ + $$PWD/qquicktargetdirection_p.h \ + $$PWD/qquickturbulence_p.h \ + $$PWD/qquickwander_p.h \ + $$PWD/qquickcumulativedirection_p.h \ + $$PWD/qquickv8particledata_p.h \ + $$PWD/qquickrectangleextruder_p.h \ + $$PWD/qquickparticlegroup_p.h \ + $$PWD/qquickgroupgoal_p.h \ + $$PWD/qtquickparticlesglobal_p.h + +SOURCES += \ + $$PWD/qquickangledirection.cpp \ + $$PWD/qquickcustomparticle.cpp \ + $$PWD/qquickcustomaffector.cpp \ + $$PWD/qquickellipseextruder.cpp \ + $$PWD/qquicktrailemitter.cpp \ + $$PWD/qquickfriction.cpp \ + $$PWD/qquickgravity.cpp \ + $$PWD/qquickimageparticle.cpp \ + $$PWD/qquickitemparticle.cpp \ + $$PWD/qquickage.cpp \ + $$PWD/qquicklineextruder.cpp \ + $$PWD/qquickmaskextruder.cpp \ + $$PWD/qquickparticleaffector.cpp \ + $$PWD/qquickparticleemitter.cpp \ + $$PWD/qquickparticleextruder.cpp \ + $$PWD/qquickparticlepainter.cpp \ + $$PWD/qquickparticlesmodule.cpp \ + $$PWD/qquickparticlesystem.cpp \ + $$PWD/qquickpointattractor.cpp \ + $$PWD/qquickpointdirection.cpp \ + $$PWD/qquickspritegoal.cpp \ + $$PWD/qquickdirection.cpp \ + $$PWD/qquicktargetdirection.cpp \ + $$PWD/qquickturbulence.cpp \ + $$PWD/qquickwander.cpp \ + $$PWD/qquickcumulativedirection.cpp \ + $$PWD/qquickv8particledata.cpp \ + $$PWD/qquickrectangleextruder.cpp \ + $$PWD/qquickparticlegroup.cpp \ + $$PWD/qquickgroupgoal.cpp + +RESOURCES += \ + $$PWD/particles.qrc + + + diff -Nru qt5-declarative-0.1~git20120402/src/particles/particles.pro qt5-declarative-0.1~git20120423/src/particles/particles.pro --- qt5-declarative-0.1~git20120402/src/particles/particles.pro 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/particles.pro 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,40 @@ +load(qt_module) + +TARGET = QtQuickParticles + +CONFIG += module +CONFIG += dll warn_on +MODULE_PRI = ../../modules/qt_quickparticles.pri + +QT = core-private gui-private v8-private qml-private quick-private + +DEFINES += QT_BUILD_QUICKPARTICLES_LIB QT_NO_URL_CAST_FROM_STRING QT_NO_INTEGER_EVENT_COORDINATES +win32-msvc*:DEFINES *= _CRT_SECURE_NO_WARNINGS +solaris-cc*:QMAKE_CXXFLAGS_RELEASE -= -O2 + +exists("qqml_enable_gcov") { + QMAKE_CXXFLAGS = -fprofile-arcs -ftest-coverage -fno-elide-constructors + LIBS += -lgcov +} + +MODULE = quickparticles +load(qt_module_config) + +include(particles.pri) + +mac { + # FIXME: this is a workaround for broken qmake logic in qtAddModule() + # This function refuses to use frameworks unless the framework exists on + # the filesystem at the time qmake is run, resulting in a build failure + # if QtQuick is qmaked before QtQml is built and frameworks are + # in use. qtAddLibrary() contains correct logic to deal with this, so + # we'll explicitly call that for now. + load(qt) + LIBS -= -lQtQml # in non-framework builds, these should be re-added + LIBS -= -lQtQml_debug # within the qtAddLibrary if appropriate, so no + qtAddLibrary(QtQml) # harm done :) + LIBS -= -lQtQuick + LIBS -= -lQtQuick_debug + qtAddLibrary(QtQuick) +} + diff -Nru qt5-declarative-0.1~git20120402/src/particles/particles.qrc qt5-declarative-0.1~git20120423/src/particles/particles.qrc --- qt5-declarative-0.1~git20120402/src/particles/particles.qrc 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/particles.qrc 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,5 @@ + + + particleresources/noise.png + + diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquickage.cpp qt5-declarative-0.1~git20120423/src/particles/qquickage.cpp --- qt5-declarative-0.1~git20120402/src/particles/qquickage.cpp 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquickage.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,112 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickage_p.h" +#include "qquickparticleemitter_p.h" +QT_BEGIN_NAMESPACE +/*! + \qmlclass Age QQuickAgeAffector + \inqmlmodule QtQuick.Particles 2 + \inherits Affector + \brief The Age affector allows you to prematurely age particles + + The Age affector allows you to alter where the particle is in its lifecycle. Common uses + are to expire particles prematurely, possibly giving them time to animate out. + + The Age affector only applies to particles which are still alive. +*/ +/*! + \qmlproperty int QtQuick.Particles2::Age::lifeLeft + + The amount of life to set the particle to have. Affected particles + will advance to a point in their life where they will have this many + milliseconds left to live. +*/ + +/*! + \qmlproperty bool QtQuick.Particles2::Age::advancePosition + + advancePosition determines whether position, veclocity and acceleration are included in + the simulated aging done by the affector. If advancePosition is false, + then the position, velocity and acceleration will remain the same and only + other attributes (such as opacity) will advance in the simulation to where + it would normally be for that point in the particle's life. With advancePosition set to + true the position, velocity and acceleration will also advance to where it would + normally be by that point in the particle's life, making it advance its position + on screen. + + Default value is true. +*/ + +QQuickAgeAffector::QQuickAgeAffector(QQuickItem *parent) : + QQuickParticleAffector(parent), m_lifeLeft(0), m_advancePosition(true) +{ +} + + +bool QQuickAgeAffector::affectParticle(QQuickParticleData *d, qreal dt) +{ + Q_UNUSED(dt); + if (d->stillAlive()){ + qreal curT = (qreal)m_system->timeInt/1000.0; + qreal ttl = (qreal)m_lifeLeft/1000.0; + if (!m_advancePosition && ttl > 0){ + qreal x = d->curX(); + qreal vx = d->curVX(); + qreal ax = d->curAX(); + qreal y = d->curY(); + qreal vy = d->curVY(); + qreal ay = d->curAY(); + d->t = curT - (d->lifeSpan - ttl); + d->setInstantaneousX(x); + d->setInstantaneousVX(vx); + d->setInstantaneousAX(ax); + d->setInstantaneousY(y); + d->setInstantaneousVY(vy); + d->setInstantaneousAY(ay); + } else { + d->t = curT - (d->lifeSpan - ttl); + } + return true; + } + return false; +} +QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquickage_p.h qt5-declarative-0.1~git20120423/src/particles/qquickage_p.h --- qt5-declarative-0.1~git20120402/src/particles/qquickage_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquickage_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef KILLAFFECTOR_H +#define KILLAFFECTOR_H +#include "qquickparticleaffector_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QQuickAgeAffector : public QQuickParticleAffector +{ + Q_OBJECT + Q_PROPERTY(int lifeLeft READ lifeLeft WRITE setLifeLeft NOTIFY lifeLeftChanged) + Q_PROPERTY(bool advancePosition READ advancePosition WRITE setAdvancePosition NOTIFY advancePositionChanged) + +public: + explicit QQuickAgeAffector(QQuickItem *parent = 0); + + int lifeLeft() const + { + return m_lifeLeft; + } + + bool advancePosition() const + { + return m_advancePosition; + } + +protected: + virtual bool affectParticle(QQuickParticleData *d, qreal dt); +signals: + void lifeLeftChanged(int arg); + void advancePositionChanged(bool arg); + +public slots: + void setLifeLeft(int arg) + { + if (m_lifeLeft != arg) { + m_lifeLeft = arg; + emit lifeLeftChanged(arg); + } + } + + void setAdvancePosition(bool arg) + { + if (m_advancePosition != arg) { + m_advancePosition = arg; + emit advancePositionChanged(arg); + } + } + +private: + int m_lifeLeft; + bool m_advancePosition; +}; + +QT_END_NAMESPACE +QT_END_HEADER +#endif // KILLAFFECTOR_H diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquickangledirection.cpp qt5-declarative-0.1~git20120423/src/particles/qquickangledirection.cpp --- qt5-declarative-0.1~git20120402/src/particles/qquickangledirection.cpp 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquickangledirection.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,120 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickangledirection_p.h" +#include +#include +#ifdef Q_OS_QNX +#include +#endif +QT_BEGIN_NAMESPACE +const qreal CONV = 0.017453292519943295; +/*! + \qmlclass AngleDirection QQuickAngleDirection + \inqmlmodule QtQuick.Particles 2 + \inherits Direction + \brief The AngleDirection element allows you to specify a direction that varies in angle + + The AngledDirection element allows both the specification of a direction by angle and magnitude, + as well as varying the parameters by angle or magnitude. +*/ +/*! + \qmlproperty real QtQuick.Particles2::AngleDirection::angle + This property specifies the base angle for the direction. + The angle of this direction will vary by no more than angleVariation + from this angle. + + Angle is specified by degrees clockwise from straight right. + + The default value is zero. +*/ +/*! + \qmlproperty real QtQuick.Particles2::AngleDirection::magnitude + This property specifies the base magnitude for the direction. + The magnitude of this direction will vary by no more than magnitudeVariation + from this magnitude. + + Magnitude is specified in units of pixels per second. + + The default value is zero. +*/ +/*! + \qmlproperty real QtQuick.Particles2::AngleDirection::angleVariation + This property specifies the maximum angle variation for the direction. + The angle of the direction will vary by up to angleVariation clockwise + and anticlockwise from the value specified in angle. + + Angle is specified by degrees clockwise from straight right. + + The default value is zero. +*/ +/*! + \qmlproperty real QtQuick.Particles2::AngleDirection::magnitudeVariation + This property specifies the base magnitude for the direction. + The magnitude of this direction will vary by no more than magnitudeVariation + from the base magnitude. + + Magnitude is specified in units of pixels per second. + + The default value is zero. +*/ +QQuickAngleDirection::QQuickAngleDirection(QObject *parent) : + QQuickDirection(parent) + , m_angle(0) + , m_magnitude(0) + , m_angleVariation(0) + , m_magnitudeVariation(0) +{ + +} + +const QPointF QQuickAngleDirection::sample(const QPointF &from) +{ + Q_UNUSED(from); + QPointF ret; + qreal theta = m_angle*CONV - m_angleVariation*CONV + rand()/float(RAND_MAX) * m_angleVariation*CONV * 2; + qreal mag = m_magnitude- m_magnitudeVariation + rand()/float(RAND_MAX) * m_magnitudeVariation * 2; + ret.setX(mag * cos(theta)); + ret.setY(mag * sin(theta)); + return ret; +} + +QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquickangledirection_p.h qt5-declarative-0.1~git20120423/src/particles/qquickangledirection_p.h --- qt5-declarative-0.1~git20120402/src/particles/qquickangledirection_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquickangledirection_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,131 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQuickANGLEDDIRECTION_H +#define QQuickANGLEDDIRECTION_H +#include "qquickdirection_p.h" +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QQuickAngleDirection : public QQuickDirection +{ + Q_OBJECT + Q_PROPERTY(qreal angle READ angle WRITE setAngle NOTIFY angleChanged) + Q_PROPERTY(qreal magnitude READ magnitude WRITE setMagnitude NOTIFY magnitudeChanged) + Q_PROPERTY(qreal angleVariation READ angleVariation WRITE setAngleVariation NOTIFY angleVariationChanged) + Q_PROPERTY(qreal magnitudeVariation READ magnitudeVariation WRITE setMagnitudeVariation NOTIFY magnitudeVariationChanged) +public: + explicit QQuickAngleDirection(QObject *parent = 0); + const QPointF sample(const QPointF &from); + qreal angle() const + { + return m_angle; + } + + qreal magnitude() const + { + return m_magnitude; + } + + qreal angleVariation() const + { + return m_angleVariation; + } + + qreal magnitudeVariation() const + { + return m_magnitudeVariation; + } + +signals: + + void angleChanged(qreal arg); + + void magnitudeChanged(qreal arg); + + void angleVariationChanged(qreal arg); + + void magnitudeVariationChanged(qreal arg); + +public slots: +void setAngle(qreal arg) +{ + if (m_angle != arg) { + m_angle = arg; + emit angleChanged(arg); + } +} + +void setMagnitude(qreal arg) +{ + if (m_magnitude != arg) { + m_magnitude = arg; + emit magnitudeChanged(arg); + } +} + +void setAngleVariation(qreal arg) +{ + if (m_angleVariation != arg) { + m_angleVariation = arg; + emit angleVariationChanged(arg); + } +} + +void setMagnitudeVariation(qreal arg) +{ + if (m_magnitudeVariation != arg) { + m_magnitudeVariation = arg; + emit magnitudeVariationChanged(arg); + } +} + +private: +qreal m_angle; +qreal m_magnitude; +qreal m_angleVariation; +qreal m_magnitudeVariation; +}; + +QT_END_NAMESPACE +QT_END_HEADER +#endif // QQuickANGLEDDIRECTION_H diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquickcumulativedirection.cpp qt5-declarative-0.1~git20120423/src/particles/qquickcumulativedirection.cpp --- qt5-declarative-0.1~git20120402/src/particles/qquickcumulativedirection.cpp 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquickcumulativedirection.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickcumulativedirection_p.h" +QT_BEGIN_NAMESPACE + +/*! + \qmlclass CumulativeDirection QQuickCumulativeDirection + \inqmlmodule QtQuick.Particles 2 + \inherits Direction + \brief The CumulativeDirection element allows you to specify a direction made of other directions + + The CumulativeDirection element will act as a direction that sums the directions within it. +*/ +QQuickCumulativeDirection::QQuickCumulativeDirection(QObject *parent):QQuickDirection(parent) +{ +} + +QQmlListProperty QQuickCumulativeDirection::directions() +{ + return QQmlListProperty(this, m_directions);//TODO: Proper list property +} + +const QPointF QQuickCumulativeDirection::sample(const QPointF &from) +{ + QPointF ret; + foreach (QQuickDirection* dir, m_directions) + ret += dir->sample(from); + return ret; +} + +QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquickcumulativedirection_p.h qt5-declarative-0.1~git20120423/src/particles/qquickcumulativedirection_p.h --- qt5-declarative-0.1~git20120402/src/particles/qquickcumulativedirection_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquickcumulativedirection_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQuickCUMULATIVEDIRECTION_P_H +#define QQuickCUMULATIVEDIRECTION_P_H +#include "qquickdirection_p.h" +#include +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QQuickCumulativeDirection : public QQuickDirection +{ + Q_OBJECT + Q_PROPERTY(QQmlListProperty directions READ directions) + Q_CLASSINFO("DefaultProperty", "directions") +public: + explicit QQuickCumulativeDirection(QObject *parent = 0); + QQmlListProperty directions(); + const QPointF sample(const QPointF &from); +private: + QList m_directions; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QQuickCUMULATIVEDIRECTION_P_H diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquickcustomaffector.cpp qt5-declarative-0.1~git20120423/src/particles/qquickcustomaffector.cpp --- qt5-declarative-0.1~git20120402/src/particles/qquickcustomaffector.cpp 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquickcustomaffector.cpp 2012-04-23 11:44:59.000000000 +0000 @@ -0,0 +1,211 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickcustomaffector_p.h" +#include +#include +#include +#include +QT_BEGIN_NAMESPACE + +//TODO: Move docs (and inheritence) to real base when docs can propagate. Currently this pretends to be the base class! +/*! + \qmlsignal QtQuick.Particles2::Affector::affectParticles(Array particles, real dt) + + This handler is called when particles are selected to be affected. particles contains + an array of particle objects which can be directly manipulated. + + dt is the time since the last time it was affected. Use dt to normalize + trajectory manipulations to real time. + + Note that JS is slower to execute, so it is not recommended to use this in + high-volume particle systems. +*/ + +/*! + \qmlproperty StochasticDirection QtQuick.Particles2::Affector::position + + Affected particles will have their position set to this direction, + relative to the ParticleSystem. When interpreting directions as points, + imagine it as an arrow with the base at the 0,0 of the ParticleSystem and the + tip at where the specified position will be. +*/ + +/*! + \qmlproperty StochasticDirection QtQuick.Particles2::Affector::speed + + Affected particles will have their speed set to this direction. +*/ + + +/*! + \qmlproperty StochasticDirection QtQuick.Particles2::Affector::acceleration + + Affected particles will have their acceleration set to this direction. +*/ + + +/*! + \qmlproperty bool QtQuick.Particles2::Affector::relative + + Whether the affected particles have their existing position/speed/acceleration added + to the new one. + + Default is true. +*/ +QQuickCustomAffector::QQuickCustomAffector(QQuickItem *parent) : + QQuickParticleAffector(parent) + , m_position(&m_nullVector) + , m_speed(&m_nullVector) + , m_acceleration(&m_nullVector) + , m_relative(true) +{ +} + +bool QQuickCustomAffector::isAffectConnected() +{ + static int idx = QObjectPrivate::get(this)->signalIndex("affectParticles(QQmlV8Handle,qreal)"); + return QObjectPrivate::get(this)->isSignalConnected(idx); +} + +void QQuickCustomAffector::affectSystem(qreal dt) +{ + if (!isAffectConnected()) { + QQuickParticleAffector::affectSystem(dt); + return; + } + if (!m_enabled) + return; + updateOffsets(); + + QList toAffect; + foreach (QQuickParticleGroupData* gd, m_system->groupData) + if (activeGroup(m_system->groupData.key(gd))) + foreach (QQuickParticleData* d, gd->data) + if (shouldAffect(d)) + toAffect << d; + + if (toAffect.isEmpty()) + return; + + if (m_onceOff) + dt = 1.0; + + v8::HandleScope handle_scope; + v8::Context::Scope scope(QQmlEnginePrivate::getV8Engine(qmlEngine(this))->context()); + v8::Handle array = v8::Array::New(toAffect.size()); + for (int i=0; iSet(i, toAffect[i]->v8Value().toHandle()); + + if (dt >= simulationCutoff || dt <= simulationDelta) { + affectProperties(toAffect, dt); + emit affectParticles(QQmlV8Handle::fromHandle(array), dt); + } else { + int realTime = m_system->timeInt; + m_system->timeInt -= dt * 1000.0; + while (dt > simulationDelta) { + m_system->timeInt += simulationDelta * 1000.0; + dt -= simulationDelta; + affectProperties(toAffect, simulationDelta); + emit affectParticles(QQmlV8Handle::fromHandle(array), simulationDelta); + } + m_system->timeInt = realTime; + if (dt > 0.0) { + affectProperties(toAffect, dt); + emit affectParticles(QQmlV8Handle::fromHandle(array), dt); + } + } + + foreach (QQuickParticleData* d, toAffect) + if (d->update == 1.0) + postAffect(d); +} + +bool QQuickCustomAffector::affectParticle(QQuickParticleData *d, qreal dt) +{ + //This does the property based affecting, called by superclass if signal isn't hooked up. + bool changed = false; + QPointF curPos(d->curX(), d->curY()); + + if (m_acceleration != &m_nullVector){ + QPointF pos = m_acceleration->sample(curPos); + if (m_relative) { + pos *= dt; + pos += QPointF(d->curAX(), d->curAY()); + } + d->setInstantaneousAX(pos.x()); + d->setInstantaneousAY(pos.y()); + changed = true; + } + + if (m_speed != &m_nullVector){ + QPointF pos = m_speed->sample(curPos); + if (m_relative) { + pos *= dt; + pos += QPointF(d->curVX(), d->curVY()); + } + d->setInstantaneousVX(pos.x()); + d->setInstantaneousVY(pos.y()); + changed = true; + } + + if (m_position != &m_nullVector){ + QPointF pos = m_position->sample(curPos); + if (m_relative) { + pos *= dt; + pos += curPos; + } + d->setInstantaneousX(pos.x()); + d->setInstantaneousY(pos.y()); + changed = true; + } + + return changed; +} + +void QQuickCustomAffector::affectProperties(const QList particles, qreal dt) +{ + foreach (QQuickParticleData* d, particles) + if ( affectParticle(d, dt) ) + d->update = 1.0; +} + +QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquickcustomaffector_p.h qt5-declarative-0.1~git20120423/src/particles/qquickcustomaffector_p.h --- qt5-declarative-0.1~git20120402/src/particles/qquickcustomaffector_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquickcustomaffector_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,162 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef CUSTOMAFFECTOR_H +#define CUSTOMAFFECTOR_H + +#include +#include "qquickparticlesystem_p.h" +#include "qquickparticleextruder_p.h" +#include "qquickparticleaffector_p.h" +#include "qquickdirection_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QQuickCustomAffector : public QQuickParticleAffector +{ + Q_OBJECT + Q_PROPERTY(bool relative READ relative WRITE setRelative NOTIFY relativeChanged) + Q_PROPERTY(QQuickDirection *position READ position WRITE setPosition NOTIFY positionChanged RESET positionReset) + Q_PROPERTY(QQuickDirection *speed READ speed WRITE setSpeed NOTIFY speedChanged RESET speedReset) + Q_PROPERTY(QQuickDirection *acceleration READ acceleration WRITE setAcceleration NOTIFY accelerationChanged RESET accelerationReset) + +public: + explicit QQuickCustomAffector(QQuickItem *parent = 0); + virtual void affectSystem(qreal dt); + + QQuickDirection * position() const + { + return m_position; + } + + QQuickDirection * speed() const + { + return m_speed; + } + + QQuickDirection * acceleration() const + { + return m_acceleration; + } + + void positionReset() + { + m_position = &m_nullVector; + } + + void speedReset() + { + m_speed = &m_nullVector; + } + + void accelerationReset() + { + m_acceleration = &m_nullVector; + } + + bool relative() const + { + return m_relative; + } + + +signals: + void affectParticles(QQmlV8Handle particles, qreal dt); + + void positionChanged(QQuickDirection * arg); + + void speedChanged(QQuickDirection * arg); + + void accelerationChanged(QQuickDirection * arg); + + void relativeChanged(bool arg); + +public slots: + void setPosition(QQuickDirection * arg) + { + if (m_position != arg) { + m_position = arg; + emit positionChanged(arg); + } + } + + void setSpeed(QQuickDirection * arg) + { + if (m_speed != arg) { + m_speed = arg; + emit speedChanged(arg); + } + } + + void setAcceleration(QQuickDirection * arg) + { + if (m_acceleration != arg) { + m_acceleration = arg; + emit accelerationChanged(arg); + } + } + + void setRelative(bool arg) + { + if (m_relative != arg) { + m_relative = arg; + emit relativeChanged(arg); + } + } + +protected: + bool isAffectConnected(); + virtual bool affectParticle(QQuickParticleData *d, qreal dt); +private: + void affectProperties(const QList particles, qreal dt); + QQuickDirection * m_position; + QQuickDirection * m_speed; + QQuickDirection * m_acceleration; + + QQuickDirection m_nullVector; + bool m_relative; +}; + +QT_END_NAMESPACE +QT_END_HEADER +#endif // CUSTOMAFFECTOR_H diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquickcustomparticle.cpp qt5-declarative-0.1~git20120423/src/particles/qquickcustomparticle.cpp --- qt5-declarative-0.1~git20120402/src/particles/qquickcustomparticle.cpp 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquickcustomparticle.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,473 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickcustomparticle_p.h" +#include +#include + +QT_BEGIN_NAMESPACE + +//Includes comments because the code isn't self explanatory +static const char qt_particles_template_vertex_code[] = + "attribute highp vec2 qt_ParticlePos;\n" + "attribute highp vec2 qt_ParticleTex;\n" + "attribute highp vec4 qt_ParticleData; // x = time, y = lifeSpan, z = size, w = endSize\n" + "attribute highp vec4 qt_ParticleVec; // x,y = constant speed, z,w = acceleration\n" + "attribute highp float qt_ParticleR;\n" + "uniform highp mat4 qt_Matrix;\n" + "uniform highp float qt_Timestamp;\n" + "varying highp vec2 qt_TexCoord0;\n" + "void defaultMain() {\n" + " qt_TexCoord0 = qt_ParticleTex;\n" + " highp float size = qt_ParticleData.z;\n" + " highp float endSize = qt_ParticleData.w;\n" + " highp float t = (qt_Timestamp - qt_ParticleData.x) / qt_ParticleData.y;\n" + " highp float currentSize = mix(size, endSize, t * t);\n" + " if (t < 0. || t > 1.)\n" + " currentSize = 0.;\n" + " highp vec2 pos = qt_ParticlePos\n" + " - currentSize / 2. + currentSize * qt_ParticleTex // adjust size\n" + " + qt_ParticleVec.xy * t * qt_ParticleData.y // apply speed vector..\n" + " + 0.5 * qt_ParticleVec.zw * pow(t * qt_ParticleData.y, 2.);\n" + " gl_Position = qt_Matrix * vec4(pos.x, pos.y, 0, 1);\n" + "}"; +static const char qt_particles_default_vertex_code[] = + "void main() { \n" + " defaultMain(); \n" + "}"; + +static const char qt_particles_default_fragment_code[] = + "uniform sampler2D source; \n" + "varying highp vec2 qt_TexCoord0; \n" + "uniform lowp float qt_Opacity; \n" + "void main() { \n" + " gl_FragColor = texture2D(source, qt_TexCoord0) * qt_Opacity; \n" + "}"; + +static QSGGeometry::Attribute PlainParticle_Attributes[] = { + QSGGeometry::Attribute::create(0, 2, GL_FLOAT, true), // Position + QSGGeometry::Attribute::create(1, 2, GL_FLOAT), // TexCoord + QSGGeometry::Attribute::create(2, 4, GL_FLOAT), // Data + QSGGeometry::Attribute::create(3, 4, GL_FLOAT), // Vectors + QSGGeometry::Attribute::create(4, 1, GL_FLOAT) // r +}; + +static QSGGeometry::AttributeSet PlainParticle_AttributeSet = +{ + 5, // Attribute Count + (2 + 2 + 4 + 4 + 1) * sizeof(float), + PlainParticle_Attributes +}; + +struct PlainVertex { + float x; + float y; + float tx; + float ty; + float t; + float lifeSpan; + float size; + float endSize; + float vx; + float vy; + float ax; + float ay; + float r; +}; + +struct PlainVertices { + PlainVertex v1; + PlainVertex v2; + PlainVertex v3; + PlainVertex v4; +}; + +/*! + \qmlclass CustomParticle QQuickCustomParticle + \inqmlmodule QtQuick.Particles 2 + \inherits ParticlePainter + \brief The CustomParticle element allows you to specify your own shader to paint particles. + +*/ + +QQuickCustomParticle::QQuickCustomParticle(QQuickItem* parent) + : QQuickParticlePainter(parent) + , m_dirtyUniforms(true) + , m_dirtyUniformValues(true) + , m_dirtyTextureProviders(true) + , m_dirtyProgram(true) +{ + setFlag(QQuickItem::ItemHasContents); +} + +void QQuickCustomParticle::sceneGraphInvalidated() +{ + m_nodes.clear(); +} + +QQuickCustomParticle::~QQuickCustomParticle() +{ +} + +void QQuickCustomParticle::componentComplete() +{ + m_common.updateShader(this, Key::FragmentShader); + updateVertexShader(); + reset(); + QQuickParticlePainter::componentComplete(); +} + + +//Trying to keep the shader conventions the same as in qsgshadereffectitem +/*! + \qmlproperty string QtQuick.Particles2::CustomParticle::fragmentShader + + This property holds the fragment shader's GLSL source code. + The default shader expects the texture coordinate to be passed from the + vertex shader as "varying highp vec2 qt_TexCoord0", and it samples from a + sampler2D named "source". +*/ + +void QQuickCustomParticle::setFragmentShader(const QByteArray &code) +{ + if (m_common.source.sourceCode[Key::FragmentShader].constData() == code.constData()) + return; + m_common.source.sourceCode[Key::FragmentShader] = code; + m_dirtyProgram = true; + if (isComponentComplete()) { + m_common.updateShader(this, Key::FragmentShader); + reset(); + } + emit fragmentShaderChanged(); +} + +/*! + \qmlproperty string QtQuick.Particles2::CustomParticle::vertexShader + + This property holds the vertex shader's GLSL source code. + + The default shader passes the texture coordinate along to the fragment + shader as "varying highp vec2 qt_TexCoord0". + + To aid writing a particle vertex shader, the following GLSL code is prepended + to your vertex shader: + \code + attribute highp vec2 qt_ParticlePos; + attribute highp vec2 qt_ParticleTex; + attribute highp vec4 qt_ParticleData; // x = time, y = lifeSpan, z = size, w = endSize + attribute highp vec4 qt_ParticleVec; // x,y = constant speed, z,w = acceleration + attribute highp float qt_ParticleR; + uniform highp mat4 qt_Matrix; + uniform highp float qt_Timestamp; + varying highp vec2 qt_TexCoord0; + void defaultMain() { + qt_TexCoord0 = qt_ParticleTex; + highp float size = qt_ParticleData.z; + highp float endSize = qt_ParticleData.w; + highp float t = (qt_Timestamp - qt_ParticleData.x) / qt_ParticleData.y; + highp float currentSize = mix(size, endSize, t * t); + if (t < 0. || t > 1.) + currentSize = 0.; + highp vec2 pos = qt_ParticlePos + - currentSize / 2. + currentSize * qt_ParticleTex // adjust size + + qt_ParticleVec.xy * t * qt_ParticleData.y // apply speed vector.. + + 0.5 * qt_ParticleVec.zw * pow(t * qt_ParticleData.y, 2.); + gl_Position = qt_Matrix * vec4(pos.x, pos.y, 0, 1); + } + \endcode + + defaultMain() is the same code as in the default shader, you can call this for basic + particle functions and then add additional variables for custom effects. Note that + the vertex shader for particles is responsible for simulating the movement of particles + over time, the particle data itself only has the starting position and spawn time. +*/ + +void QQuickCustomParticle::setVertexShader(const QByteArray &code) +{ + if (m_common.source.sourceCode[Key::VertexShader].constData() == code.constData()) + return; + m_common.source.sourceCode[Key::VertexShader] = code; + + m_dirtyProgram = true; + if (isComponentComplete()) { + updateVertexShader(); + reset(); + } + emit vertexShaderChanged(); +} + +void QQuickCustomParticle::updateVertexShader() +{ + m_common.disconnectPropertySignals(this, Key::VertexShader); + qDeleteAll(m_common.signalMappers[Key::VertexShader]); + m_common.uniformData[Key::VertexShader].clear(); + m_common.signalMappers[Key::VertexShader].clear(); + m_common.attributes.clear(); + m_common.attributes.append("qt_ParticlePos"); + m_common.attributes.append("qt_ParticleTex"); + m_common.attributes.append("qt_ParticleData"); + m_common.attributes.append("qt_ParticleVec"); + m_common.attributes.append("qt_ParticleR"); + + UniformData d; + d.name = "qt_Matrix"; + d.specialType = UniformData::Matrix; + m_common.uniformData[Key::VertexShader].append(d); + m_common.signalMappers[Key::VertexShader].append(0); + + d.name = "qt_Timestamp"; + d.specialType = UniformData::None; + m_common.uniformData[Key::VertexShader].append(d); + m_common.signalMappers[Key::VertexShader].append(0); + + const QByteArray &code = m_common.source.sourceCode[Key::VertexShader]; + if (!code.isEmpty()) + m_common.lookThroughShaderCode(this, Key::VertexShader, code); + + m_common.connectPropertySignals(this, Key::VertexShader); +} + +void QQuickCustomParticle::reset() +{ + QQuickParticlePainter::reset(); + update(); +} + +QSGNode *QQuickCustomParticle::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) +{ + QQuickShaderEffectNode *rootNode = static_cast(oldNode); + if (m_pleaseReset){ + delete rootNode;//Automatically deletes children + rootNode = 0; + m_nodes.clear(); + m_pleaseReset = false; + m_dirtyProgram = true; + } + + if (m_system && m_system->isRunning() && !m_system->isPaused()){ + rootNode = prepareNextFrame(rootNode); + if (rootNode) + update(); + } + + return rootNode; +} + +QQuickShaderEffectNode *QQuickCustomParticle::prepareNextFrame(QQuickShaderEffectNode *rootNode) +{ + if (!rootNode) + rootNode = buildCustomNodes(); + + if (!rootNode) + return 0; + + if (m_dirtyProgram) { + QQuickShaderEffectMaterial *material = static_cast(rootNode->material()); + Q_ASSERT(material); + + Key s = m_common.source; + if (s.sourceCode[Key::FragmentShader].isEmpty()) + s.sourceCode[Key::FragmentShader] = qt_particles_default_fragment_code; + if (s.sourceCode[Key::VertexShader].isEmpty()) + s.sourceCode[Key::VertexShader] = qt_particles_default_vertex_code; + s.sourceCode[Key::VertexShader] = qt_particles_template_vertex_code + s.sourceCode[Key::VertexShader]; + s.className = metaObject()->className(); + + material->setProgramSource(s); + material->attributes = m_common.attributes; + foreach (QQuickShaderEffectNode* node, m_nodes) + node->markDirty(QSGNode::DirtyMaterial); + + m_dirtyProgram = false; + m_dirtyUniforms = true; + } + + m_lastTime = m_system->systemSync(this) / 1000.; + if (true) //Currently this is how we update timestamp... potentially over expensive. + buildData(rootNode); + return rootNode; +} + +QQuickShaderEffectNode* QQuickCustomParticle::buildCustomNodes() +{ +#ifdef QT_OPENGL_ES_2 + if (m_count * 4 > 0xffff) { + printf("CustomParticle: Too many particles... \n"); + return 0; + } +#endif + + if (m_count <= 0) { + printf("CustomParticle: Too few particles... \n"); + return 0; + } + + if (m_groups.isEmpty()) + return 0; + + QQuickShaderEffectNode *rootNode = 0; + QQuickShaderEffectMaterial *material = new QQuickShaderEffectMaterial; + m_dirtyProgram = true; + + foreach (const QString &str, m_groups){ + int gIdx = m_system->groupIds[str]; + int count = m_system->groupData[gIdx]->size(); + + QQuickShaderEffectNode* node = new QQuickShaderEffectNode(); + m_nodes.insert(gIdx, node); + + node->setMaterial(material); + + //Create Particle Geometry + int vCount = count * 4; + int iCount = count * 6; + QSGGeometry *g = new QSGGeometry(PlainParticle_AttributeSet, vCount, iCount); + g->setDrawingMode(GL_TRIANGLES); + node->setGeometry(g); + node->setFlag(QSGNode::OwnsGeometry, true); + PlainVertex *vertices = (PlainVertex *) g->vertexData(); + for (int p=0; p < count; ++p) { + commit(gIdx, p); + vertices[0].tx = 0; + vertices[0].ty = 0; + + vertices[1].tx = 1; + vertices[1].ty = 0; + + vertices[2].tx = 0; + vertices[2].ty = 1; + + vertices[3].tx = 1; + vertices[3].ty = 1; + vertices += 4; + } + quint16 *indices = g->indexDataAsUShort(); + for (int i=0; i < count; ++i) { + int o = i * 4; + indices[0] = o; + indices[1] = o + 1; + indices[2] = o + 2; + indices[3] = o + 1; + indices[4] = o + 3; + indices[5] = o + 2; + indices += 6; + } + } + + QHash::const_iterator it = m_nodes.begin(); + rootNode = it.value(); + rootNode->setFlag(QSGNode::OwnsMaterial, true); + for (++it; it != m_nodes.end(); ++it) + rootNode->appendChildNode(it.value()); + + return rootNode; +} + +void QQuickCustomParticle::sourceDestroyed(QObject *object) +{ + m_common.sourceDestroyed(object); +} + +void QQuickCustomParticle::propertyChanged(int mappedId) +{ + bool textureProviderChanged; + m_common.propertyChanged(this, mappedId, &textureProviderChanged); + m_dirtyTextureProviders |= textureProviderChanged; + m_dirtyUniformValues = true; + update(); +} + + +void QQuickCustomParticle::buildData(QQuickShaderEffectNode *rootNode) +{ + if (!rootNode) + return; + for (int shaderType = 0; shaderType < Key::ShaderTypeCount; ++shaderType) { + for (int i = 0; i < m_common.uniformData[shaderType].size(); ++i) { + if (m_common.uniformData[shaderType].at(i).name == "qt_Timestamp") + m_common.uniformData[shaderType][i].value = qVariantFromValue(m_lastTime); + } + } + m_common.updateMaterial(rootNode, static_cast(rootNode->material()), + m_dirtyUniforms, true, m_dirtyTextureProviders); + foreach (QQuickShaderEffectNode* node, m_nodes) + node->markDirty(QSGNode::DirtyMaterial); + m_dirtyUniforms = m_dirtyUniformValues = m_dirtyTextureProviders = false; +} + +void QQuickCustomParticle::initialize(int gIdx, int pIdx) +{ + QQuickParticleData* datum = m_system->groupData[gIdx]->data[pIdx]; + datum->r = rand()/(qreal)RAND_MAX; +} + +void QQuickCustomParticle::commit(int gIdx, int pIdx) +{ + if (m_nodes[gIdx] == 0) + return; + + QQuickParticleData* datum = m_system->groupData[gIdx]->data[pIdx]; + PlainVertices *particles = (PlainVertices *) m_nodes[gIdx]->geometry()->vertexData(); + PlainVertex *vertices = (PlainVertex *)&particles[pIdx]; + for (int i=0; i<4; ++i) { + vertices[i].x = datum->x - m_systemOffset.x(); + vertices[i].y = datum->y - m_systemOffset.y(); + vertices[i].t = datum->t; + vertices[i].lifeSpan = datum->lifeSpan; + vertices[i].size = datum->size; + vertices[i].endSize = datum->endSize; + vertices[i].vx = datum->vx; + vertices[i].vy = datum->vy; + vertices[i].ax = datum->ax; + vertices[i].ay = datum->ay; + vertices[i].r = datum->r; + } +} + +void QQuickCustomParticle::itemChange(ItemChange change, const ItemChangeData &value) +{ + if (change == QQuickItem::ItemSceneChange) + m_common.updateCanvas(value.canvas); + QQuickParticlePainter::itemChange(change, value); +} + + +QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquickcustomparticle_p.h qt5-declarative-0.1~git20120423/src/particles/qquickcustomparticle_p.h --- qt5-declarative-0.1~git20120402/src/particles/qquickcustomparticle_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquickcustomparticle_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,119 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef CUSTOM_PARTICLE_H +#define CUSTOM_PARTICLE_H +#include "qquickparticlepainter_p.h" +#include +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QSGNode; +struct PlainVertices; + +class QQuickShaderEffectMaterialObject; + +//Genealogy: Hybrid of UltraParticle and ShaderEffect +class QQuickCustomParticle : public QQuickParticlePainter +{ + Q_OBJECT + Q_PROPERTY(QByteArray fragmentShader READ fragmentShader WRITE setFragmentShader NOTIFY fragmentShaderChanged) + Q_PROPERTY(QByteArray vertexShader READ vertexShader WRITE setVertexShader NOTIFY vertexShaderChanged) + +public: + explicit QQuickCustomParticle(QQuickItem* parent=0); + ~QQuickCustomParticle(); + + QByteArray fragmentShader() const { return m_common.source.sourceCode[Key::FragmentShader]; } + void setFragmentShader(const QByteArray &code); + + QByteArray vertexShader() const { return m_common.source.sourceCode[Key::VertexShader]; } + void setVertexShader(const QByteArray &code); + +Q_SIGNALS: + void fragmentShaderChanged(); + void vertexShaderChanged(); + +protected: + virtual void initialize(int gIdx, int pIdx); + virtual void commit(int gIdx, int pIdx); + + QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *); + QQuickShaderEffectNode *prepareNextFrame(QQuickShaderEffectNode *rootNode); + void reset(); + void resize(int oldCount, int newCount); + virtual void componentComplete(); + QQuickShaderEffectNode *buildCustomNodes(); + + void sceneGraphInvalidated(); + void itemChange(ItemChange change, const ItemChangeData &value); + +private Q_SLOTS: + void sourceDestroyed(QObject *object); + void propertyChanged(int mappedId); + +private: + typedef QQuickShaderEffectMaterialKey Key; + typedef QQuickShaderEffectMaterial::UniformData UniformData; + + void buildData(QQuickShaderEffectNode *rootNode); + void updateVertexShader(); + + QQuickShaderEffectCommon m_common; + + QHash m_nodes; + qreal m_lastTime; + + uint m_dirtyUniforms : 1; + uint m_dirtyUniformValues : 1; + uint m_dirtyTextureProviders : 1; + uint m_dirtyProgram : 1; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif //HEADER_GUARD diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquickdirection.cpp qt5-declarative-0.1~git20120423/src/particles/qquickdirection.cpp --- qt5-declarative-0.1~git20120402/src/particles/qquickdirection.cpp 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquickdirection.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickdirection_p.h" + +QT_BEGIN_NAMESPACE +/*! + \qmlclass Direction QQuickDirection + \inqmlmodule QtQuick.Particles 2 + \brief The Direction elements allow you to specify a vector space. + +*/ + + +QQuickDirection::QQuickDirection(QObject *parent) : + QObject(parent) +{ +} + +const QPointF QQuickDirection::sample(const QPointF &from) +{ + Q_UNUSED(from); + return QPointF(); +} + +QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquickdirection_p.h qt5-declarative-0.1~git20120423/src/particles/qquickdirection_p.h --- qt5-declarative-0.1~git20120402/src/particles/qquickdirection_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquickdirection_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef VARYINGVECTOR_H +#define VARYINGVECTOR_H + +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QQuickDirection : public QObject +{ + Q_OBJECT +public: + explicit QQuickDirection(QObject *parent = 0); + + virtual const QPointF sample(const QPointF &from); +signals: + +public slots: + +protected: +}; + +QT_END_NAMESPACE +QT_END_HEADER +#endif // VARYINGVECTOR_H diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquickellipseextruder.cpp qt5-declarative-0.1~git20120423/src/particles/qquickellipseextruder.cpp --- qt5-declarative-0.1~git20120402/src/particles/qquickellipseextruder.cpp 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquickellipseextruder.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickellipseextruder_p.h" +#include +#include + +#ifdef Q_OS_QNX +#include +#endif + +QT_BEGIN_NAMESPACE +/*! + \qmlclass EllipseShape QQuickEllipseExtruder + \inqmlmodule QtQuick.Particles 2 + \inherits Shape + \brief The EllipseShape represents an ellipse to other particle system elements + + This shape can be used by Emitter subclasses and Affector subclasses to have + them act upon an ellipse shaped area. +*/ +QQuickEllipseExtruder::QQuickEllipseExtruder(QObject *parent) : + QQuickParticleExtruder(parent) + , m_fill(true) +{ +} + +/*! + \qmlproperty bool QtQuick.Particles2::EllipseShape::fill + If fill is true the ellipse is filled; otherwise it is just a border. + + Default is true. +*/ + +QPointF QQuickEllipseExtruder::extrude(const QRectF & r) +{ + qreal theta = ((qreal)rand()/RAND_MAX) * 6.2831853071795862; + qreal mag = m_fill ? ((qreal)rand()/RAND_MAX) : 1; + return QPointF(r.x() + r.width()/2 + mag * (r.width()/2) * cos(theta), + r.y() + r.height()/2 + mag * (r.height()/2) * sin(theta)); +} + +bool QQuickEllipseExtruder::contains(const QRectF &bounds, const QPointF &point) +{ + return bounds.contains(point);//TODO: Ellipse +} + +QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquickellipseextruder_p.h qt5-declarative-0.1~git20120423/src/particles/qquickellipseextruder_p.h --- qt5-declarative-0.1~git20120402/src/particles/qquickellipseextruder_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquickellipseextruder_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef ELLIPSEEXTRUDER_H +#define ELLIPSEEXTRUDER_H +#include "qquickparticleextruder_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QQuickEllipseExtruder : public QQuickParticleExtruder +{ + Q_OBJECT + Q_PROPERTY(bool fill READ fill WRITE setFill NOTIFY fillChanged)//###Use base class? If it's still box +public: + explicit QQuickEllipseExtruder(QObject *parent = 0); + virtual QPointF extrude(const QRectF &); + virtual bool contains(const QRectF &bounds, const QPointF &point); + + bool fill() const + { + return m_fill; + } + +signals: + + void fillChanged(bool arg); + +public slots: + + void setFill(bool arg) + { + if (m_fill != arg) { + m_fill = arg; + emit fillChanged(arg); + } + } +private: + bool m_fill; +}; + +QT_END_NAMESPACE +QT_END_HEADER +#endif // ELLIPSEEXTRUDER_H diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquickfriction.cpp qt5-declarative-0.1~git20120423/src/particles/qquickfriction.cpp --- qt5-declarative-0.1~git20120402/src/particles/qquickfriction.cpp 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquickfriction.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickfriction_p.h" +QT_BEGIN_NAMESPACE +/*! + \qmlclass Friction QQuickFrictionAffector + \inqmlmodule QtQuick.Particles 2 + \inherits Affector + \brief The Friction affector slows down movement proportional to the particle's current speed. + +*/ + +/*! + \qmlproperty real QtQuick.Particles2::Friction::factor + + A drag will be applied to moving objects which is this factor of their current velocity. +*/ +/*! + \qmlproperty real QtQuick.Particles2::Friction::threshold + + The drag will only be applied to objects with a velocity above the threshold velocity. The + drag applied will bring objects down to the threshold velocity, but no further. + + The default threshold is 0 +*/ +static qreal sign(qreal a) +{ + return a >= 0 ? 1 : -1; +} + +static const qreal epsilon = 0.00001; + +QQuickFrictionAffector::QQuickFrictionAffector(QQuickItem *parent) : + QQuickParticleAffector(parent), m_factor(0.0), m_threshold(0.0) +{ +} + +bool QQuickFrictionAffector::affectParticle(QQuickParticleData *d, qreal dt) +{ + if (!m_factor) + return false; + qreal curVX = d->curVX(); + qreal curVY = d->curVY(); + if (!curVX && !curVY) + return false; + qreal newVX = curVX + (curVX * m_factor * -1 * dt); + qreal newVY = curVY + (curVY * m_factor * -1 * dt); + + if (!m_threshold) { + if (sign(curVX) != sign(newVX)) + newVX = 0; + if (sign(curVY) != sign(newVY)) + newVY = 0; + } else { + qreal curMag = sqrt(curVX*curVX + curVY*curVY); + if (curMag <= m_threshold + epsilon) + return false; + qreal newMag = sqrt(newVX*newVX + newVY*newVY); + if (newMag <= m_threshold + epsilon || //went past the threshold, stop there instead + sign(curVX) != sign(newVX) || //went so far past maybe it came out the other side! + sign(curVY) != sign(newVY)) { + qreal theta = atan2(curVY, curVX); + newVX = m_threshold * cos(theta); + newVY = m_threshold * sin(theta); + } + } + + d->setInstantaneousVX(newVX); + d->setInstantaneousVY(newVY); + return true; +} +QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquickfriction_p.h qt5-declarative-0.1~git20120423/src/particles/qquickfriction_p.h --- qt5-declarative-0.1~git20120402/src/particles/qquickfriction_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquickfriction_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef FRICTIONAFFECTOR_H +#define FRICTIONAFFECTOR_H +#include "qquickparticleaffector_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QQuickFrictionAffector : public QQuickParticleAffector +{ + Q_OBJECT + Q_PROPERTY(qreal factor READ factor WRITE setFactor NOTIFY factorChanged) + Q_PROPERTY(qreal threshold READ threshold WRITE setThreshold NOTIFY thresholdChanged) +public: + explicit QQuickFrictionAffector(QQuickItem *parent = 0); + + qreal factor() const + { + return m_factor; + } + + qreal threshold() const + { + return m_threshold; + } + +protected: + virtual bool affectParticle(QQuickParticleData *d, qreal dt); + +signals: + + void factorChanged(qreal arg); + void thresholdChanged(qreal arg); + +public slots: + + void setFactor(qreal arg) + { + if (m_factor != arg) { + m_factor = arg; + emit factorChanged(arg); + } + } + + void setThreshold(qreal arg) + { + if (m_threshold != arg) { + m_threshold = arg; + emit thresholdChanged(arg); + } + } + +private: + qreal m_factor; + qreal m_threshold; +}; + +QT_END_NAMESPACE +QT_END_HEADER +#endif // FRICTIONAFFECTOR_H diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquickgravity.cpp qt5-declarative-0.1~git20120423/src/particles/qquickgravity.cpp --- qt5-declarative-0.1~git20120402/src/particles/qquickgravity.cpp 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquickgravity.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickgravity_p.h" +#include +QT_BEGIN_NAMESPACE +const qreal CONV = 0.017453292520444443; +/*! + \qmlclass Gravity QQuickGravityAffector + \inqmlmodule QtQuick.Particles 2 + \inherits Affector + \brief The Gravity element allows you to set an accleration in an angle + + This element will accelerate all affected particles to a vector of + the specified magnitude in the specified angle. If the angle and acceleration do + not vary, it is more efficient to set the specified acceleration on the Emitter. + + This element models the gravity of a massive object whose center of + gravity is far away (and thus the gravitational pull is effectively constant + across the scene). To model the gravity of an object near or inside the scene, + use PointAttractor. +*/ + +/*! + \qmlproperty real QtQuick.Particles2::Gravity::magnitude + + Pixels per second that objects will be accelerated by. +*/ +/*! + \qmlproperty real QtQuick.Particles2::Gravity::acceleration + + Name changed to magnitude, will be removed soon. +*/ +/*! + \qmlproperty real QtQuick.Particles2::Gravity::angle + + Angle of acceleration. +*/ + +QQuickGravityAffector::QQuickGravityAffector(QQuickItem *parent) : + QQuickParticleAffector(parent), m_magnitude(-10), m_angle(90), m_needRecalc(true) +{ +} + +bool QQuickGravityAffector::affectParticle(QQuickParticleData *d, qreal dt) +{ + if (!m_magnitude) + return false; + if (m_needRecalc) { + m_needRecalc = false; + m_dx = m_magnitude * cos(m_angle * CONV); + m_dy = m_magnitude * sin(m_angle * CONV); + } + + d->setInstantaneousVX(d->curVX() + m_dx*dt); + d->setInstantaneousVY(d->curVY() + m_dy*dt); + return true; +} +QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquickgravity_p.h qt5-declarative-0.1~git20120423/src/particles/qquickgravity_p.h --- qt5-declarative-0.1~git20120402/src/particles/qquickgravity_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquickgravity_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,115 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef GRAVITYAFFECTOR_H +#define GRAVITYAFFECTOR_H +#include "qquickparticleaffector_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QQuickGravityAffector : public QQuickParticleAffector +{ + Q_OBJECT + Q_PROPERTY(qreal magnitude READ magnitude WRITE setMagnitude NOTIFY magnitudeChanged) + Q_PROPERTY(qreal acceleration READ magnitude WRITE setAcceleration NOTIFY magnitudeChanged) + Q_PROPERTY(qreal angle READ angle WRITE setAngle NOTIFY angleChanged) +public: + explicit QQuickGravityAffector(QQuickItem *parent = 0); + qreal magnitude() const + { + return m_magnitude; + } + + qreal angle() const + { + return m_angle; + } +protected: + virtual bool affectParticle(QQuickParticleData *d, qreal dt); +signals: + + void magnitudeChanged(qreal arg); + + void angleChanged(qreal arg); + +public slots: +void setAcceleration(qreal arg) +{ + qWarning() << "Gravity::acceleration has been renamed Gravity::magnitude"; + if (m_magnitude != arg) { + m_magnitude = arg; + m_needRecalc = true; + emit magnitudeChanged(arg); + } +} + +void setMagnitude(qreal arg) +{ + if (m_magnitude != arg) { + m_magnitude = arg; + m_needRecalc = true; + emit magnitudeChanged(arg); + } +} + +void setAngle(qreal arg) +{ + if (m_angle != arg) { + m_angle = arg; + m_needRecalc = true; + emit angleChanged(arg); + } +} + +private: + qreal m_magnitude; + qreal m_angle; + + bool m_needRecalc; + qreal m_dx; + qreal m_dy; +}; + +QT_END_NAMESPACE +QT_END_HEADER +#endif // GRAVITYAFFECTOR_H diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquickgroupgoal.cpp qt5-declarative-0.1~git20120423/src/particles/qquickgroupgoal.cpp --- qt5-declarative-0.1~git20120402/src/particles/qquickgroupgoal.cpp 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquickgroupgoal.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,112 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickgroupgoal_p.h" +#include +#include +#include "qquickimageparticle_p.h" +#include + +QT_BEGIN_NAMESPACE + +/*! + \qmlclass GroupGoal QQuickGroupGoalAffector + \inqmlmodule QtQuick.Particles 2 + \inherits Affector + \brief The GroupGoal Affector allows you to change the state of a group of a particle. + +*/ +/*! + \qmlproperty string QtQuick.Particles2::GroupGoal::goalState + + The name of the group which the affected particles should move to. + + Groups can have defined durations and transitions between them, setting goalState + will cause it to disregard any path weightings (including 0) and head down the path + which will reach the goalState quickest. It will pass through intermediate groups + on that path for their respective durations. +*/ +/*! + \qmlproperty bool QtQuick.Particles2::GroupGoal::jump + + If true, affected particles will jump directly to the target group instead of taking the + the shortest valid path to get there. They will also not finish their current state, + but immediately move to the beginning of the goal state. + + Default is false. +*/ + +QQuickGroupGoalAffector::QQuickGroupGoalAffector(QQuickItem *parent) : + QQuickParticleAffector(parent), m_jump(false) +{ + m_ignoresTime = true; +} + +void QQuickGroupGoalAffector::setGoalState(QString arg) +{ + if (m_goalState != arg) { + m_goalState = arg; + emit goalStateChanged(arg); + } +} + +bool QQuickGroupGoalAffector::affectParticle(QQuickParticleData *d, qreal dt) +{ + Q_UNUSED(dt); + QQuickStochasticEngine *engine = m_system->stateEngine; + bool notUsingEngine = false; + if (!engine) + notUsingEngine = true; + + int index = d->systemIndex; + int goalIdx = m_system->groupIds[m_goalState]; + if (notUsingEngine){//no stochastic states defined. So cut out the engine + //TODO: It's possible to move to a group that is intermediate and not used by painters or emitters - but right now that will redirect to the default group + m_system->moveGroups(d, goalIdx); + return true; + }else if (engine->curState(index) != goalIdx){ + engine->setGoal(goalIdx, index, m_jump); + return true; + } + return false; +} + +QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquickgroupgoal_p.h qt5-declarative-0.1~git20120423/src/particles/qquickgroupgoal_p.h --- qt5-declarative-0.1~git20120402/src/particles/qquickgroupgoal_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquickgroupgoal_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef GROUPGOALAFFECTOR_H +#define GROUPGOALAFFECTOR_H +#include "qquickparticleaffector_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QQuickStochasticEngine; + +class QQuickGroupGoalAffector : public QQuickParticleAffector +{ + Q_OBJECT + Q_PROPERTY(QString goalState READ goalState WRITE setGoalState NOTIFY goalStateChanged) + Q_PROPERTY(bool jump READ jump WRITE setJump NOTIFY jumpChanged) +public: + explicit QQuickGroupGoalAffector(QQuickItem *parent = 0); + + QString goalState() const + { + return m_goalState; + } + + bool jump() const + { + return m_jump; + } + +protected: + virtual bool affectParticle(QQuickParticleData *d, qreal dt); + +signals: + + void goalStateChanged(QString arg); + + void jumpChanged(bool arg); + +public slots: + + void setGoalState(QString arg); + + void setJump(bool arg) + { + if (m_jump != arg) { + m_jump = arg; + emit jumpChanged(arg); + } + } + +private: + QString m_goalState; + bool m_jump; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // GROUPGOALAFFECTOR_H diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquickimageparticle.cpp qt5-declarative-0.1~git20120423/src/particles/qquickimageparticle.cpp --- qt5-declarative-0.1~git20120402/src/particles/qquickimageparticle.cpp 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquickimageparticle.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,1978 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include "qquickimageparticle_p.h" +#include "qquickparticleemitter_p.h" +#include +#include +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +#ifndef QT_OPENGL_ES_2 +#define SHADER_DEFINES "#version 120\n" +#else +#define SHADER_DEFINES "" +#endif + +//TODO: Make it larger on desktop? Requires fixing up shader code with the same define +#define UNIFORM_ARRAY_SIZE 64 + +static const char vertexShaderCode[] = + "#if defined(DEFORM)\n" + "attribute highp vec4 vPosTex;\n" + "#else\n" + "attribute highp vec2 vPos;\n" + "#endif\n" + "attribute highp vec4 vData; // x = time, y = lifeSpan, z = size, w = endSize\n" + "attribute highp vec4 vVec; // x,y = constant speed, z,w = acceleration\n" + "uniform highp float entry;\n" + "#if defined(COLOR)\n" + "attribute highp vec4 vColor;\n" + "#endif\n" + "#if defined(DEFORM)\n" + "attribute highp vec4 vDeformVec; //x,y x unit vector; z,w = y unit vector\n" + "attribute highp vec3 vRotation; //x = radians of rotation, y=rotation speed, z= bool autoRotate\n" + "#endif\n" + "#if defined(SPRITE)\n" + "attribute highp vec3 vAnimData;// w,h(premultiplied of anim), interpolation progress\n" + "attribute highp vec4 vAnimPos;//x,y, x,y (two frames for interpolation)\n" + "#endif\n" + "\n" + "uniform highp mat4 qt_Matrix;\n" + "uniform highp float timestamp;\n" + "#if defined(TABLE)\n" + "varying lowp vec2 tt;//y is progress if Sprite mode\n" + "uniform highp float sizetable[64];\n" + "uniform highp float opacitytable[64];\n" + "#endif\n" + "#if defined(SPRITE)\n" + "varying highp vec4 fTexS;\n" + "#elif defined(DEFORM)\n" + "varying highp vec2 fTex;\n" + "#endif\n" + "#if defined(COLOR)\n" + "varying lowp vec4 fColor;\n" + "#else\n" + "varying lowp float fFade;\n" + "#endif\n" + "\n" + "\n" + "void main() {\n" + "\n" + " highp float t = (timestamp - vData.x) / vData.y;\n" + " if (t < 0. || t > 1.) {\n" + "#if defined(DEFORM)\n" + " gl_Position = qt_Matrix * vec4(vPosTex.x, vPosTex.y, 0., 1.);\n" + "#else\n" + " gl_PointSize = 0.;\n" + "#endif\n" + " } else {\n" + "#if defined(SPRITE)\n" + " tt.y = vAnimData.z;\n" + " //Calculate frame location in texture\n" + " fTexS.xy = vAnimPos.xy + vPosTex.zw * vAnimData.xy;\n" + " //Next frame is also passed, for interpolation\n" + " fTexS.zw = vAnimPos.zw + vPosTex.zw * vAnimData.xy;\n" + "\n" + "#elif defined(DEFORM)\n" + " fTex = vPosTex.zw;\n" + "#endif\n" + " highp float currentSize = mix(vData.z, vData.w, t * t);\n" + " lowp float fade = 1.;\n" + " highp float fadeIn = min(t * 10., 1.);\n" + " highp float fadeOut = 1. - clamp((t - 0.75) * 4.,0., 1.);\n" + "\n" + "#if defined(TABLE)\n" + " currentSize = currentSize * sizetable[int(floor(t*64.))];\n" + " fade = fade * opacitytable[int(floor(t*64.))];\n" + "#endif\n" + "\n" + " if (entry == 1.)\n" + " fade = fade * fadeIn * fadeOut;\n" + " else if (entry == 2.)\n" + " currentSize = currentSize * fadeIn * fadeOut;\n" + "\n" + " if (currentSize <= 0.) {\n" + "#if defined(DEFORM)\n" + " gl_Position = qt_Matrix * vec4(vPosTex.x, vPosTex.y, 0., 1.);\n" + "#else\n" + " gl_PointSize = 0.;\n" + "#endif\n" + " } else {\n" + " if (currentSize < 3.)//Sizes too small look jittery as they move\n" + " currentSize = 3.;\n" + "\n" + " highp vec2 pos;\n" + "#if defined(DEFORM)\n" + " highp float rotation = vRotation.x + vRotation.y * t * vData.y;\n" + " if (vRotation.z == 1.0){\n" + " highp vec2 curVel = vVec.zw * t * vData.y + vVec.xy;\n" + " rotation += atan(curVel.y, curVel.x);\n" + " }\n" + " highp vec2 trigCalcs = vec2(cos(rotation), sin(rotation));\n" + " highp vec4 deform = vDeformVec * currentSize * (vPosTex.zzww - 0.5);\n" + " highp vec4 rotatedDeform = deform.xxzz * trigCalcs.xyxy;\n" + " rotatedDeform = rotatedDeform + (deform.yyww * trigCalcs.yxyx * vec4(-1.,1.,-1.,1.));\n" + " /* The readable version:\n" + " highp vec2 xDeform = vDeformVec.xy * currentSize * (vTex.x-0.5);\n" + " highp vec2 yDeform = vDeformVec.zw * currentSize * (vTex.y-0.5);\n" + " highp vec2 xRotatedDeform;\n" + " xRotatedDeform.x = trigCalcs.x*xDeform.x - trigCalcs.y*xDeform.y;\n" + " xRotatedDeform.y = trigCalcs.y*xDeform.x + trigCalcs.x*xDeform.y;\n" + " highp vec2 yRotatedDeform;\n" + " yRotatedDeform.x = trigCalcs.x*yDeform.x - trigCalcs.y*yDeform.y;\n" + " yRotatedDeform.y = trigCalcs.y*yDeform.x + trigCalcs.x*yDeform.y;\n" + " */\n" + " pos = vPosTex.xy\n" + " + rotatedDeform.xy\n" + " + rotatedDeform.zw\n" + " + vVec.xy * t * vData.y // apply speed\n" + " + 0.5 * vVec.zw * pow(t * vData.y, 2.); // apply acceleration\n" + "#else\n" + " pos = vPos\n" + " + vVec.xy * t * vData.y // apply speed vector..\n" + " + 0.5 * vVec.zw * pow(t * vData.y, 2.);\n" + " gl_PointSize = currentSize;\n" + "#endif\n" + " gl_Position = qt_Matrix * vec4(pos.x, pos.y, 0, 1);\n" + "\n" + "#if defined(COLOR)\n" + " fColor = vColor * fade;\n" + "#else\n" + " fFade = fade;\n" + "#endif\n" + "#if defined(TABLE)\n" + " tt.x = t;\n" + "#endif\n" + " }\n" + " }\n" + "}\n"; + +static const char fragmentShaderCode[] = + "uniform sampler2D texture;\n" + "uniform lowp float qt_Opacity;\n" + "\n" + "#if defined(SPRITE)\n" + "varying highp vec4 fTexS;\n" + "#elif defined(DEFORM)\n" + "varying highp vec2 fTex;\n" + "#endif\n" + "#if defined(COLOR)\n" + "varying lowp vec4 fColor;\n" + "#else\n" + "varying lowp float fFade;\n" + "#endif\n" + "#if defined(TABLE)\n" + "varying lowp vec2 tt;\n" + "uniform sampler2D colortable;\n" + "#endif\n" + "\n" + "void main() {\n" + "#if defined(SPRITE)\n" + " gl_FragColor = mix(texture2D(texture, fTexS.xy), texture2D(texture, fTexS.zw), tt.y)\n" + " * fColor\n" + " * texture2D(colortable, tt)\n" + " * qt_Opacity;\n" + "#elif defined(TABLE)\n" + " gl_FragColor = texture2D(texture, fTex)\n" + " * fColor\n" + " * texture2D(colortable, tt)\n" + " * qt_Opacity;\n" + "#elif defined(DEFORM)\n" + " gl_FragColor = (texture2D(texture, fTex)) * fColor * qt_Opacity;\n" + "#elif defined(COLOR)\n" + " gl_FragColor = (texture2D(texture, gl_PointCoord)) * fColor * qt_Opacity;\n" + "#else\n" + " gl_FragColor = texture2D(texture, gl_PointCoord) * (fFade * qt_Opacity);\n" + "#endif\n" + "}\n"; + +const qreal CONV = 0.017453292519943295; +class ImageMaterialData +{ + public: + ImageMaterialData() + : texture(0), colorTable(0) + {} + + ~ImageMaterialData(){ + delete texture; + delete colorTable; + } + + QSGTexture *texture; + QSGTexture *colorTable; + float sizeTable[UNIFORM_ARRAY_SIZE]; + float opacityTable[UNIFORM_ARRAY_SIZE]; + + qreal timestamp; + qreal entry; + QSizeF animSheetSize; +}; + +class TabledMaterialData : public ImageMaterialData {}; +class TabledMaterial : public QSGSimpleMaterialShader +{ + QSG_DECLARE_SIMPLE_SHADER(TabledMaterial, TabledMaterialData) + +public: + TabledMaterial() + { + m_vertex_code = QByteArray(SHADER_DEFINES) + + QByteArray("#define TABLE\n#define DEFORM\n#define COLOR\n") + + vertexShaderCode; + + m_fragment_code = QByteArray(SHADER_DEFINES) + + QByteArray("#define TABLE\n#define DEFORM\n#define COLOR\n") + + fragmentShaderCode; + + Q_ASSERT(!m_vertex_code.isNull()); + Q_ASSERT(!m_fragment_code.isNull()); + } + + const char *vertexShader() const { return m_vertex_code.constData(); } + const char *fragmentShader() const { return m_fragment_code.constData(); } + + QList attributes() const { + return QList() << "vPosTex" << "vData" << "vVec" + << "vColor" << "vDeformVec" << "vRotation"; + }; + + void initialize() { + QSGSimpleMaterialShader::initialize(); + program()->bind(); + program()->setUniformValue("texture", 0); + program()->setUniformValue("colortable", 1); + glFuncs = QOpenGLContext::currentContext()->functions(); + m_timestamp_id = program()->uniformLocation("timestamp"); + m_entry_id = program()->uniformLocation("entry"); + m_sizetable_id = program()->uniformLocation("sizetable"); + m_opacitytable_id = program()->uniformLocation("opacitytable"); + } + + void updateState(const TabledMaterialData* d, const TabledMaterialData*) { + glFuncs->glActiveTexture(GL_TEXTURE1); + d->colorTable->bind(); + + glFuncs->glActiveTexture(GL_TEXTURE0); + d->texture->bind(); + + program()->setUniformValue(m_timestamp_id, (float) d->timestamp); + program()->setUniformValue(m_entry_id, (float) d->entry); + program()->setUniformValueArray(m_sizetable_id, (float*) d->sizeTable, UNIFORM_ARRAY_SIZE, 1); + program()->setUniformValueArray(m_opacitytable_id, (float*) d->opacityTable, UNIFORM_ARRAY_SIZE, 1); + } + + int m_entry_id; + int m_timestamp_id; + int m_sizetable_id; + int m_opacitytable_id; + QByteArray m_vertex_code; + QByteArray m_fragment_code; + QOpenGLFunctions* glFuncs; +}; + +class DeformableMaterialData : public ImageMaterialData {}; +class DeformableMaterial : public QSGSimpleMaterialShader +{ + QSG_DECLARE_SIMPLE_SHADER(DeformableMaterial, DeformableMaterialData) + +public: + DeformableMaterial() + { + m_vertex_code = QByteArray(SHADER_DEFINES) + + QByteArray("#define DEFORM\n#define COLOR\n") + + vertexShaderCode; + + m_fragment_code = QByteArray(SHADER_DEFINES) + + QByteArray("#define DEFORM\n#define COLOR\n") + + fragmentShaderCode; + + Q_ASSERT(!m_vertex_code.isNull()); + Q_ASSERT(!m_fragment_code.isNull()); + } + + const char *vertexShader() const { return m_vertex_code.constData(); } + const char *fragmentShader() const { return m_fragment_code.constData(); } + + QList attributes() const { + return QList() << "vPosTex" << "vData" << "vVec" + << "vColor" << "vDeformVec" << "vRotation"; + }; + + void initialize() { + QSGSimpleMaterialShader::initialize(); + program()->bind(); + program()->setUniformValue("texture", 0); + glFuncs = QOpenGLContext::currentContext()->functions(); + m_timestamp_id = program()->uniformLocation("timestamp"); + m_entry_id = program()->uniformLocation("entry"); + } + + void updateState(const DeformableMaterialData* d, const DeformableMaterialData*) { + glFuncs->glActiveTexture(GL_TEXTURE0); + d->texture->bind(); + + program()->setUniformValue(m_timestamp_id, (float) d->timestamp); + program()->setUniformValue(m_entry_id, (float) d->entry); + } + + int m_entry_id; + int m_timestamp_id; + QByteArray m_vertex_code; + QByteArray m_fragment_code; + QOpenGLFunctions* glFuncs; +}; + +class SpriteMaterialData : public ImageMaterialData {}; +class SpriteMaterial : public QSGSimpleMaterialShader +{ + QSG_DECLARE_SIMPLE_SHADER(SpriteMaterial, SpriteMaterialData) + +public: + SpriteMaterial() + { + m_vertex_code = QByteArray(SHADER_DEFINES) + + QByteArray("#define SPRITE\n#define TABLE\n#define DEFORM\n#define COLOR\n") + + vertexShaderCode; + + m_fragment_code = QByteArray(SHADER_DEFINES) + + QByteArray("#define SPRITE\n#define TABLE\n#define DEFORM\n#define COLOR\n") + + fragmentShaderCode; + + Q_ASSERT(!m_vertex_code.isNull()); + Q_ASSERT(!m_fragment_code.isNull()); + } + + const char *vertexShader() const { return m_vertex_code.constData(); } + const char *fragmentShader() const { return m_fragment_code.constData(); } + + QList attributes() const { + return QList() << "vPosTex" << "vData" << "vVec" + << "vColor" << "vDeformVec" << "vRotation" << "vAnimData" << "vAnimPos"; + }; + + void initialize() { + QSGSimpleMaterialShader::initialize(); + program()->bind(); + program()->setUniformValue("texture", 0); + program()->setUniformValue("colortable", 1); + glFuncs = QOpenGLContext::currentContext()->functions(); + //Don't actually expose the animSheetSize in the shader, it's currently only used for CPU calculations. + m_timestamp_id = program()->uniformLocation("timestamp"); + m_entry_id = program()->uniformLocation("entry"); + m_sizetable_id = program()->uniformLocation("sizetable"); + m_opacitytable_id = program()->uniformLocation("opacitytable"); + } + + void updateState(const SpriteMaterialData* d, const SpriteMaterialData*) { + glFuncs->glActiveTexture(GL_TEXTURE1); + d->colorTable->bind(); + + // make sure we end by setting GL_TEXTURE0 as active texture + glFuncs->glActiveTexture(GL_TEXTURE0); + d->texture->bind(); + + program()->setUniformValue(m_timestamp_id, (float) d->timestamp); + program()->setUniformValue(m_entry_id, (float) d->entry); + program()->setUniformValueArray(m_sizetable_id, (float*) d->sizeTable, 64, 1); + program()->setUniformValueArray(m_opacitytable_id, (float*) d->opacityTable, UNIFORM_ARRAY_SIZE, 1); + } + + int m_timestamp_id; + int m_entry_id; + int m_sizetable_id; + int m_opacitytable_id; + QByteArray m_vertex_code; + QByteArray m_fragment_code; + QOpenGLFunctions* glFuncs; +}; + +class ColoredMaterialData : public ImageMaterialData {}; +class ColoredMaterial : public QSGSimpleMaterialShader +{ + QSG_DECLARE_SIMPLE_SHADER(ColoredMaterial, ColoredMaterialData) + +public: + ColoredMaterial() + { + m_vertex_code = QByteArray(SHADER_DEFINES) + + QByteArray("#define COLOR\n") + + vertexShaderCode; + + m_fragment_code = QByteArray(SHADER_DEFINES) + + QByteArray("#define COLOR\n") + + fragmentShaderCode; + + Q_ASSERT(!m_vertex_code.isNull()); + Q_ASSERT(!m_fragment_code.isNull()); + } + + const char *vertexShader() const { return m_vertex_code.constData(); } + const char *fragmentShader() const { return m_fragment_code.constData(); } + + void activate() { + QSGSimpleMaterialShader::activate(); +#if !defined(QT_OPENGL_ES_2) && !defined(Q_OS_WIN) + glEnable(GL_POINT_SPRITE); + glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); +#endif + } + + void deactivate() { + QSGSimpleMaterialShader::deactivate(); +#if !defined(QT_OPENGL_ES_2) && !defined(Q_OS_WIN) + glDisable(GL_POINT_SPRITE); + glDisable(GL_VERTEX_PROGRAM_POINT_SIZE); +#endif + } + + QList attributes() const { + return QList() << "vPos" << "vData" << "vVec" << "vColor"; + } + + void initialize() { + QSGSimpleMaterialShader::initialize(); + program()->bind(); + program()->setUniformValue("texture", 0); + glFuncs = QOpenGLContext::currentContext()->functions(); + m_timestamp_id = program()->uniformLocation("timestamp"); + m_entry_id = program()->uniformLocation("entry"); + } + + void updateState(const ColoredMaterialData* d, const ColoredMaterialData*) { + glFuncs->glActiveTexture(GL_TEXTURE0); + d->texture->bind(); + + program()->setUniformValue(m_timestamp_id, (float) d->timestamp); + program()->setUniformValue(m_entry_id, (float) d->entry); + } + + int m_timestamp_id; + int m_entry_id; + QByteArray m_vertex_code; + QByteArray m_fragment_code; + QOpenGLFunctions* glFuncs; +}; + +class SimpleMaterialData : public ImageMaterialData {}; +class SimpleMaterial : public QSGSimpleMaterialShader +{ + QSG_DECLARE_SIMPLE_SHADER(SimpleMaterial, SimpleMaterialData) + +public: + SimpleMaterial() + { + m_vertex_code = QByteArray(SHADER_DEFINES) + + vertexShaderCode; + + m_fragment_code = QByteArray(SHADER_DEFINES) + + fragmentShaderCode; + + Q_ASSERT(!m_vertex_code.isNull()); + Q_ASSERT(!m_fragment_code.isNull()); + } + + const char *vertexShader() const { return m_vertex_code.constData(); } + const char *fragmentShader() const { return m_fragment_code.constData(); } + + void activate() { + QSGSimpleMaterialShader::activate(); +#if !defined(QT_OPENGL_ES_2) && !defined(Q_OS_WIN) + glEnable(GL_POINT_SPRITE); + glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); +#endif + } + + void deactivate() { + QSGSimpleMaterialShader::deactivate(); +#if !defined(QT_OPENGL_ES_2) && !defined(Q_OS_WIN) + glDisable(GL_POINT_SPRITE); + glDisable(GL_VERTEX_PROGRAM_POINT_SIZE); +#endif + } + + QList attributes() const { + return QList() << "vPos" << "vData" << "vVec"; + } + + void initialize() { + QSGSimpleMaterialShader::initialize(); + program()->bind(); + program()->setUniformValue("texture", 0); + glFuncs = QOpenGLContext::currentContext()->functions(); + m_timestamp_id = program()->uniformLocation("timestamp"); + m_entry_id = program()->uniformLocation("entry"); + } + + void updateState(const SimpleMaterialData* d, const SimpleMaterialData*) { + glFuncs->glActiveTexture(GL_TEXTURE0); + d->texture->bind(); + + program()->setUniformValue(m_timestamp_id, (float) d->timestamp); + program()->setUniformValue(m_entry_id, (float) d->entry); + } + + int m_timestamp_id; + int m_entry_id; + QByteArray m_vertex_code; + QByteArray m_fragment_code; + QOpenGLFunctions* glFuncs; +}; + +void fillUniformArrayFromImage(float* array, const QImage& img, int size) +{ + if (img.isNull()){ + for (int i=0; i QtQuick.Particles2::ImageParticle::sprites + + The sprite or sprites used to draw this particle. + + Note that the sprite image will be scaled to a square based on the size of + the particle being rendered. +*/ +/*! + \qmlproperty url QtQuick.Particles2::ImageParticle::colorTable + + An image whose color will be used as a 1D texture to determine color over life. E.g. when + the particle is halfway through its lifetime, it will have the color specified halfway + across the image. + + This color is blended with the color property and the color of the source image. +*/ +/*! + \qmlproperty url QtQuick.Particles2::ImageParticle::sizeTable + + An image whose opacity will be used as a 1D texture to determine size over life. + + This property is expected to be removed shortly, in favor of custom easing curves to determine size over life. +*/ +/*! + \qmlproperty url QtQuick.Particles2::ImageParticle::opacityTable + + An image whose opacity will be used as a 1D texture to determine size over life. + + This property is expected to be removed shortly, in favor of custom easing curves to determine opacity over life. +*/ +/*! + \qmlproperty color QtQuick.Particles2::ImageParticle::color + + If a color is specified, the provided image will be colorized with it. + + Default is white (no change). +*/ +/*! + \qmlproperty real QtQuick.Particles2::ImageParticle::colorVariation + + This number represents the color variation applied to individual particles. + Setting colorVariation is the same as setting redVariation, greenVariation, + and blueVariation to the same number. + + Each channel can vary between particle by up to colorVariation from its usual color. + + Color is measured, per channel, from 0.0 to 1.0. + + Default is 0.0 +*/ +/*! + \qmlproperty real QtQuick.Particles2::ImageParticle::redVariation + The variation in the red color channel between particles. + + Color is measured, per channel, from 0.0 to 1.0. + + Default is 0.0 +*/ +/*! + \qmlproperty real QtQuick.Particles2::ImageParticle::greenVariation + The variation in the green color channel between particles. + + Color is measured, per channel, from 0.0 to 1.0. + + Default is 0.0 +*/ +/*! + \qmlproperty real QtQuick.Particles2::ImageParticle::blueVariation + The variation in the blue color channel between particles. + + Color is measured, per channel, from 0.0 to 1.0. + + Default is 0.0 +*/ +/*! + \qmlproperty real QtQuick.Particles2::ImageParticle::alpha + An alpha to be applied to the image. This value is multiplied by the value in + the image, and the value in the color property. + + Particles have additive blending, so lower alpha on single particles leads + to stronger effects when multiple particles overlap. + + Alpha is measured from 0.0 to 1.0. + + Default is 1.0 +*/ +/*! + \qmlproperty real QtQuick.Particles2::ImageParticle::alphaVariation + The variation in the alpha channel between particles. + + Alpha is measured from 0.0 to 1.0. + + Default is 0.0 +*/ +/*! + \qmlproperty real QtQuick.Particles2::ImageParticle::rotation + + If set the image will be rotated by this many degrees before it is drawn. + + The particle coordinates are not transformed. +*/ +/*! + \qmlproperty real QtQuick.Particles2::ImageParticle::rotationVariation + + If set the rotation of individual particles will vary by up to this much + between particles. + +*/ +/*! + \qmlproperty real QtQuick.Particles2::ImageParticle::rotationSpeed + + If set particles will rotate at this speed in degrees/second. +*/ +/*! + \qmlproperty real QtQuick.Particles2::ImageParticle::rotationSpeedVariation + + If set the rotationSpeed of individual particles will vary by up to this much + between particles. + +*/ +/*! + \qmlproperty bool QtQuick.Particles2::ImageParticle::autoRotation + + If set to true then a rotation will be applied on top of the particles rotation, so + that it faces the direction of travel. So to face away from the direction of travel, + set autoRotation to true and rotation to 180. + + Default is false +*/ +/*! + \qmlproperty StochasticDirection QtQuick.Particles2::ImageParticle::xVector + + Allows you to deform the particle image when drawn. The rectangular image will + be deformed so that the horizontal sides are in the shape of this vector instead + of (1,0). +*/ +/*! + \qmlproperty StochasticDirection QtQuick.Particles2::ImageParticle::yVector + + Allows you to deform the particle image when drawn. The rectangular image will + be deformed so that the vertical sides are in the shape of this vector instead + of (0,1). +*/ +/*! + \qmlproperty EntryEffect QtQuick.Particles2::ImageParticle::entryEffect + + This property provides basic and cheap entrance and exit effects for the particles. + For fine-grained control, see sizeTable and opacityTable. + + Acceptable values are + \list + \li ImageParticle.None: Particles just appear and disappear. + \li ImageParticle.Fade: Particles fade in from 0 opacity at the start of their life, and fade out to 0 at the end. + \li ImageParticle.Scale: Particles scale in from 0 size at the start of their life, and scale back to 0 at the end. + \endlist + + Default value is Fade. +*/ +/*! + \qmlproperty bool QtQuick.Particles2::ImageParticle::spritesInterpolate + + If set to true, sprite particles will interpolate between sprite frames each rendered frame, making + the sprites look smoother. + + Default is true. +*/ + +/*! + \qmlproperty Status QtQuick.Particles2::ImageParticle::status + + The status of loading the image. +*/ + + +QQuickImageParticle::QQuickImageParticle(QQuickItem* parent) + : QQuickParticlePainter(parent) + , m_image(0) + , m_colorTable(0) + , m_sizeTable(0) + , m_opacityTable(0) + , m_color_variation(0.0) + , m_rootNode(0) + , m_material(0) + , m_alphaVariation(0.0) + , m_alpha(1.0) + , m_redVariation(0.0) + , m_greenVariation(0.0) + , m_blueVariation(0.0) + , m_rotation(0) + , m_rotationVariation(0) + , m_rotationSpeed(0) + , m_rotationSpeedVariation(0) + , m_autoRotation(false) + , m_xVector(0) + , m_yVector(0) + , m_spriteEngine(0) + , m_spritesInterpolate(true) + , m_explicitColor(false) + , m_explicitRotation(false) + , m_explicitDeformation(false) + , m_explicitAnimation(false) + , m_bypassOptimizations(false) + , perfLevel(Unknown) + , m_lastLevel(Unknown) + , m_debugMode(false) + , m_entryEffect(Fade) + , m_buildingNodes(false) +{ + setFlag(ItemHasContents); +} + +QQuickImageParticle::~QQuickImageParticle() +{ +} + +QQmlListProperty QQuickImageParticle::sprites() +{ + return QQmlListProperty(this, &m_sprites, spriteAppend, spriteCount, spriteAt, spriteClear); +} + +void QQuickImageParticle::sceneGraphInvalidated() +{ + m_nodes.clear(); + m_rootNode = 0; + m_material = 0; +} + +void QQuickImageParticle::setImage(const QUrl &image) +{ + if (image.isEmpty()){ + if (m_image) { + delete m_image; + emit imageChanged(); + } + return; + } + + if (!m_image) + m_image = new ImageData; + if (image == m_image->source) + return; + m_image->source = image; + emit imageChanged(); + reset(); +} + + +void QQuickImageParticle::setColortable(const QUrl &table) +{ + if (table.isEmpty()){ + if (m_colorTable) { + delete m_colorTable; + emit colortableChanged(); + } + return; + } + + if (!m_colorTable) + m_colorTable = new ImageData; + if (table == m_colorTable->source) + return; + m_colorTable->source = table; + emit colortableChanged(); + reset(); +} + +void QQuickImageParticle::setSizetable(const QUrl &table) +{ + if (table.isEmpty()){ + if (m_sizeTable) { + delete m_sizeTable; + emit sizetableChanged(); + } + return; + } + + if (!m_sizeTable) + m_sizeTable = new ImageData; + if (table == m_sizeTable->source) + return; + m_sizeTable->source = table; + emit sizetableChanged(); + reset(); +} + +void QQuickImageParticle::setOpacitytable(const QUrl &table) +{ + if (table.isEmpty()){ + if (m_opacityTable) { + delete m_opacityTable; + emit opacitytableChanged(); + } + return; + } + + if (!m_opacityTable) + m_opacityTable = new ImageData; + if (table == m_opacityTable->source) + return; + m_opacityTable->source = table; + emit opacitytableChanged(); + reset(); +} + +void QQuickImageParticle::setColor(const QColor &color) +{ + if (color == m_color) + return; + m_color = color; + emit colorChanged(); + m_explicitColor = true; + if (perfLevel < Colored) + reset(); +} + +void QQuickImageParticle::setColorVariation(qreal var) +{ + if (var == m_color_variation) + return; + m_color_variation = var; + emit colorVariationChanged(); + m_explicitColor = true; + if (perfLevel < Colored) + reset(); +} + +void QQuickImageParticle::setAlphaVariation(qreal arg) +{ + if (m_alphaVariation != arg) { + m_alphaVariation = arg; + emit alphaVariationChanged(arg); + } + m_explicitColor = true; + if (perfLevel < Colored) + reset(); +} + +void QQuickImageParticle::setAlpha(qreal arg) +{ + if (m_alpha != arg) { + m_alpha = arg; + emit alphaChanged(arg); + } + m_explicitColor = true; + if (perfLevel < Colored) + reset(); +} + +void QQuickImageParticle::setRedVariation(qreal arg) +{ + if (m_redVariation != arg) { + m_redVariation = arg; + emit redVariationChanged(arg); + } + m_explicitColor = true; + if (perfLevel < Colored) + reset(); +} + +void QQuickImageParticle::setGreenVariation(qreal arg) +{ + if (m_greenVariation != arg) { + m_greenVariation = arg; + emit greenVariationChanged(arg); + } + m_explicitColor = true; + if (perfLevel < Colored) + reset(); +} + +void QQuickImageParticle::setBlueVariation(qreal arg) +{ + if (m_blueVariation != arg) { + m_blueVariation = arg; + emit blueVariationChanged(arg); + } + m_explicitColor = true; + if (perfLevel < Colored) + reset(); +} + +void QQuickImageParticle::setRotation(qreal arg) +{ + if (m_rotation != arg) { + m_rotation = arg; + emit rotationChanged(arg); + } + m_explicitRotation = true; + if (perfLevel < Deformable) + reset(); +} + +void QQuickImageParticle::setRotationVariation(qreal arg) +{ + if (m_rotationVariation != arg) { + m_rotationVariation = arg; + emit rotationVariationChanged(arg); + } + m_explicitRotation = true; + if (perfLevel < Deformable) + reset(); +} + +void QQuickImageParticle::setRotationSpeed(qreal arg) +{ + if (m_rotationSpeed != arg) { + m_rotationSpeed = arg; + emit rotationSpeedChanged(arg); + } + m_explicitRotation = true; + if (perfLevel < Deformable) + reset(); +} + +void QQuickImageParticle::setRotationSpeedVariation(qreal arg) +{ + if (m_rotationSpeedVariation != arg) { + m_rotationSpeedVariation = arg; + emit rotationSpeedVariationChanged(arg); + } + m_explicitRotation = true; + if (perfLevel < Deformable) + reset(); +} + +void QQuickImageParticle::setAutoRotation(bool arg) +{ + if (m_autoRotation != arg) { + m_autoRotation = arg; + emit autoRotationChanged(arg); + } + m_explicitRotation = true; + if (perfLevel < Deformable) + reset(); +} + +void QQuickImageParticle::setXVector(QQuickDirection* arg) +{ + if (m_xVector != arg) { + m_xVector = arg; + emit xVectorChanged(arg); + } + m_explicitDeformation = true; + if (perfLevel < Deformable) + reset(); +} + +void QQuickImageParticle::setYVector(QQuickDirection* arg) +{ + if (m_yVector != arg) { + m_yVector = arg; + emit yVectorChanged(arg); + } + m_explicitDeformation = true; + if (perfLevel < Deformable) + reset(); +} + +void QQuickImageParticle::setSpritesInterpolate(bool arg) +{ + if (m_spritesInterpolate != arg) { + m_spritesInterpolate = arg; + emit spritesInterpolateChanged(arg); + } +} + +void QQuickImageParticle::setBypassOptimizations(bool arg) +{ + if (m_bypassOptimizations != arg) { + m_bypassOptimizations = arg; + emit bypassOptimizationsChanged(arg); + } + if (perfLevel < 9999) + reset(); +} + +void QQuickImageParticle::setEntryEffect(EntryEffect arg) +{ + if (m_entryEffect != arg) { + m_entryEffect = arg; + if (m_material) + getState(m_material)->entry = (qreal) m_entryEffect; + emit entryEffectChanged(arg); + } +} + +void QQuickImageParticle::resetColor() +{ + m_explicitColor = false; + foreach (const QString &str, m_groups) + foreach (QQuickParticleData* d, m_system->groupData[m_system->groupIds[str]]->data) + if (d->colorOwner == this) + d->colorOwner = 0; + m_color = QColor(); + m_color_variation = 0.0f; + m_redVariation = 0.0f; + m_blueVariation = 0.0f; + m_greenVariation = 0.0f; + m_alpha = 1.0f; + m_alphaVariation = 0.0f; +} + +void QQuickImageParticle::resetRotation() +{ + m_explicitRotation = false; + foreach (const QString &str, m_groups) + foreach (QQuickParticleData* d, m_system->groupData[m_system->groupIds[str]]->data) + if (d->rotationOwner == this) + d->rotationOwner = 0; + m_rotation = 0; + m_rotationVariation = 0; + m_rotationSpeed = 0; + m_rotationSpeedVariation = 0; + m_autoRotation = false; +} + +void QQuickImageParticle::resetDeformation() +{ + m_explicitDeformation = false; + foreach (const QString &str, m_groups) + foreach (QQuickParticleData* d, m_system->groupData[m_system->groupIds[str]]->data) + if (d->deformationOwner == this) + d->deformationOwner = 0; + if (m_xVector) + delete m_xVector; + if (m_yVector) + delete m_yVector; + m_xVector = 0; + m_yVector = 0; +} + +void QQuickImageParticle::reset() +{ + QQuickParticlePainter::reset(); + m_pleaseReset = true; + update(); +} + +void QQuickImageParticle::createEngine() +{ + if (m_spriteEngine) + delete m_spriteEngine; + if (m_sprites.count()) { + m_spriteEngine = new QQuickSpriteEngine(m_sprites, this); + connect(m_spriteEngine, SIGNAL(stateChanged(int)), + this, SLOT(spriteAdvance(int)), Qt::DirectConnection); + m_explicitAnimation = true; + } else { + m_spriteEngine = 0; + m_explicitAnimation = false; + } + reset(); +} + +static QSGGeometry::Attribute SimpleParticle_Attributes[] = { + QSGGeometry::Attribute::create(0, 2, GL_FLOAT, true), // Position + QSGGeometry::Attribute::create(1, 4, GL_FLOAT), // Data + QSGGeometry::Attribute::create(2, 4, GL_FLOAT) // Vectors +}; + +static QSGGeometry::AttributeSet SimpleParticle_AttributeSet = +{ + 3, // Attribute Count + ( 2 + 4 + 4 ) * sizeof(float), + SimpleParticle_Attributes +}; + +static QSGGeometry::Attribute ColoredParticle_Attributes[] = { + QSGGeometry::Attribute::create(0, 2, GL_FLOAT, true), // Position + QSGGeometry::Attribute::create(1, 4, GL_FLOAT), // Data + QSGGeometry::Attribute::create(2, 4, GL_FLOAT), // Vectors + QSGGeometry::Attribute::create(3, 4, GL_UNSIGNED_BYTE), // Colors +}; + +static QSGGeometry::AttributeSet ColoredParticle_AttributeSet = +{ + 4, // Attribute Count + ( 2 + 4 + 4 ) * sizeof(float) + 4 * sizeof(uchar), + ColoredParticle_Attributes +}; + +static QSGGeometry::Attribute DeformableParticle_Attributes[] = { + QSGGeometry::Attribute::create(0, 4, GL_FLOAT), // Position & TexCoord + QSGGeometry::Attribute::create(1, 4, GL_FLOAT), // Data + QSGGeometry::Attribute::create(2, 4, GL_FLOAT), // Vectors + QSGGeometry::Attribute::create(3, 4, GL_UNSIGNED_BYTE), // Colors + QSGGeometry::Attribute::create(4, 4, GL_FLOAT), // DeformationVectors + QSGGeometry::Attribute::create(5, 3, GL_FLOAT), // Rotation +}; + +static QSGGeometry::AttributeSet DeformableParticle_AttributeSet = +{ + 6, // Attribute Count + (4 + 4 + 4 + 4 + 3) * sizeof(float) + 4 * sizeof(uchar), + DeformableParticle_Attributes +}; + +static QSGGeometry::Attribute SpriteParticle_Attributes[] = { + QSGGeometry::Attribute::create(0, 4, GL_FLOAT), // Position & TexCoord + QSGGeometry::Attribute::create(1, 4, GL_FLOAT), // Data + QSGGeometry::Attribute::create(2, 4, GL_FLOAT), // Vectors + QSGGeometry::Attribute::create(3, 4, GL_UNSIGNED_BYTE), // Colors + QSGGeometry::Attribute::create(4, 4, GL_FLOAT), // DeformationVectors + QSGGeometry::Attribute::create(5, 3, GL_FLOAT), // Rotation + QSGGeometry::Attribute::create(6, 3, GL_FLOAT), // Anim Data + QSGGeometry::Attribute::create(7, 4, GL_FLOAT) // Anim Pos +}; + +static QSGGeometry::AttributeSet SpriteParticle_AttributeSet = +{ + 8, // Attribute Count + (4 + 4 + 4 + 4 + 3 + 3 + 4) * sizeof(float) + 4 * sizeof(uchar), + SpriteParticle_Attributes +}; + +void QQuickImageParticle::clearShadows() +{ + foreach (const QVector data, m_shadowData) + qDeleteAll(data); + m_shadowData.clear(); +} + +//Only call if you need to, may initialize the whole array first time +QQuickParticleData* QQuickImageParticle::getShadowDatum(QQuickParticleData* datum) +{ + //Will return datum if the datum is a sentinel or uninitialized, to centralize that one check + if (datum->systemIndex == -1) + return datum; + QQuickParticleGroupData* gd = m_system->groupData[datum->group]; + if (!m_shadowData.contains(datum->group)) { + QVector data; + for (int i=0; isize(); i++){ + QQuickParticleData* datum = new QQuickParticleData(m_system); + *datum = *(gd->data[i]); + data << datum; + } + m_shadowData.insert(datum->group, data); + } + //### If dynamic resize is added, remember to potentially resize the shadow data on out-of-bounds access request + + return m_shadowData[datum->group][datum->index]; +} + +bool QQuickImageParticle::loadingSomething() +{ + return (m_image && m_image->pix.isLoading()) + || (m_colorTable && m_colorTable->pix.isLoading()) + || (m_sizeTable && m_sizeTable->pix.isLoading()) + || (m_opacityTable && m_opacityTable->pix.isLoading()) + || (m_spriteEngine && m_spriteEngine->isLoading()); +} + +void QQuickImageParticle::buildParticleNodes()//Starts async parts, like loading images. +{ + if (m_rootNode || loadingSomething()) + return; + + if (!m_buildingNodes) { + if (m_image) {//ImageData created on setSource + m_image->pix.clear(this); + m_image->pix.load(qmlEngine(this), m_image->source); + } + + if (m_spriteEngine) + m_spriteEngine->startAssemblingImage(); + + if (m_colorTable) + m_colorTable->pix.load(qmlEngine(this), m_colorTable->source); + + if (m_sizeTable) + m_sizeTable->pix.load(qmlEngine(this), m_sizeTable->source); + + if (m_opacityTable) + m_opacityTable->pix.load(qmlEngine(this), m_opacityTable->source); + + m_buildingNodes = true; + if (loadingSomething()) + return; + } + finishBuildParticleNodes(); +} + +void QQuickImageParticle::finishBuildParticleNodes() +{ + m_buildingNodes = false; +#ifdef QT_OPENGL_ES_2 + if (m_count * 4 > 0xffff) { + printf("ImageParticle: Too many particles - maximum 16,000 per ImageParticle.\n");//ES 2 vertex count limit is ushort + return; + } +#endif + + if (count() <= 0) + return; + + m_debugMode = m_system->m_debugMode; + + if (m_sprites.count() || m_bypassOptimizations) { + perfLevel = Sprites; + } else if (m_colorTable || m_sizeTable || m_opacityTable) { + perfLevel = Tabled; + } else if (m_autoRotation || m_rotation || m_rotationVariation + || m_rotationSpeed || m_rotationSpeedVariation + || m_xVector || m_yVector) { + perfLevel = Deformable; + } else if (m_alphaVariation || m_alpha != 1.0 || m_color.isValid() || m_color_variation + || m_redVariation || m_blueVariation || m_greenVariation) { + perfLevel = Colored; + } else { + perfLevel = Simple; + } + + foreach (const QString &str, m_groups){//For sharing higher levels, need to have highest used so it renders + int gIdx = m_system->groupIds[str]; + foreach (QQuickParticlePainter* p, m_system->groupData[gIdx]->painters){ + QQuickImageParticle* other = qobject_cast(p); + if (other){ + if (other->perfLevel > perfLevel) { + if (other->perfLevel >= Tabled){//Deformable is the highest level needed for this, anything higher isn't shared (or requires your own sprite) + if (perfLevel < Deformable) + perfLevel = Deformable; + } else { + perfLevel = other->perfLevel; + } + } else if (other->perfLevel < perfLevel) { + other->reset(); + } + } + } + } +#ifdef Q_OS_WIN + if (perfLevel < Deformable) //QTBUG-24540 , point sprite 'extension' isn't working on windows. + perfLevel = Deformable; +#endif + + if (perfLevel >= Colored && !m_color.isValid()) + m_color = QColor(Qt::white);//Hidden default, but different from unset + + clearShadows(); + if (m_material) + m_material = 0; + + //Setup material + QImage colortable; + QImage sizetable; + QImage opacitytable; + QImage image; + bool imageLoaded = false; + switch (perfLevel) {//Fallthrough intended + case Sprites: + if (!m_spriteEngine) { + qWarning() << "ImageParticle: No sprite engine..."; + //Sprite performance mode with static image is supported, but not advised + //Note that in this case it always uses shadow data + } else { + image = m_spriteEngine->assembledImage(); + if (image.isNull())//Warning is printed in engine + return; + imageLoaded = true; + } + m_material = SpriteMaterial::createMaterial(); + if (imageLoaded) + getState(m_material)->texture = QSGPlainTexture::fromImage(image); + getState(m_material)->animSheetSize = QSizeF(image.size()); + if (m_spriteEngine) + m_spriteEngine->setCount(m_count); + case Tabled: + if (!m_material) + m_material = TabledMaterial::createMaterial(); + + if (m_colorTable) { + if (m_colorTable->pix.isReady()) + colortable = m_colorTable->pix.image(); + else + qmlInfo(this) << "Error loading color table: " << m_colorTable->pix.error(); + } + + if (m_sizeTable) { + if (m_sizeTable->pix.isReady()) + sizetable = m_sizeTable->pix.image(); + else + qmlInfo(this) << "Error loading size table: " << m_sizeTable->pix.error(); + } + + if (m_opacityTable) { + if (m_opacityTable->pix.isReady()) + opacitytable = m_opacityTable->pix.image(); + else + qmlInfo(this) << "Error loading opacity table: " << m_opacityTable->pix.error(); + } + + if (colortable.isNull()){//###Goes through image just for this + colortable = QImage(1,1,QImage::Format_ARGB32_Premultiplied); + colortable.fill(Qt::white); + } + getState(m_material)->colorTable = QSGPlainTexture::fromImage(colortable); + fillUniformArrayFromImage(getState(m_material)->sizeTable, sizetable, UNIFORM_ARRAY_SIZE); + fillUniformArrayFromImage(getState(m_material)->opacityTable, opacitytable, UNIFORM_ARRAY_SIZE); + case Deformable: + if (!m_material) + m_material = DeformableMaterial::createMaterial(); + case Colored: + if (!m_material) + m_material = ColoredMaterial::createMaterial(); + default://Also Simple + if (!m_material) + m_material = SimpleMaterial::createMaterial(); + if (!imageLoaded) { + if (!m_image->pix.isReady()) { + qmlInfo(this) << m_image->pix.error(); + delete m_material; + return; + } + //getState(m_material)->texture //TODO: Shouldn't this be better? But not crash? + // = QQuickItemPrivate::get(this)->sceneGraphContext()->textureForFactory(m_imagePix.textureFactory()); + getState(m_material)->texture = QSGPlainTexture::fromImage(m_image->pix.image()); + } + getState(m_material)->texture->setFiltering(QSGTexture::Linear); + getState(m_material)->entry = (qreal) m_entryEffect; + m_material->setFlag(QSGMaterial::Blending); + } + + m_nodes.clear(); + foreach (const QString &str, m_groups){ + int gIdx = m_system->groupIds[str]; + int count = m_system->groupData[gIdx]->size(); + QSGGeometryNode* node = new QSGGeometryNode(); + node->setMaterial(m_material); + node->markDirty(QSGNode::DirtyMaterial); + + m_nodes.insert(gIdx, node); + m_idxStarts.insert(gIdx, m_lastIdxStart); + m_startsIdx.append(qMakePair(m_lastIdxStart, gIdx)); + m_lastIdxStart += count; + + //Create Particle Geometry + int vCount = count * 4; + int iCount = count * 6; + + QSGGeometry *g; + if (perfLevel == Sprites) + g = new QSGGeometry(SpriteParticle_AttributeSet, vCount, iCount); + else if (perfLevel == Tabled) + g = new QSGGeometry(DeformableParticle_AttributeSet, vCount, iCount); + else if (perfLevel == Deformable) + g = new QSGGeometry(DeformableParticle_AttributeSet, vCount, iCount); + else if (perfLevel == Colored) + g = new QSGGeometry(ColoredParticle_AttributeSet, count, 0); + else //Simple + g = new QSGGeometry(SimpleParticle_AttributeSet, count, 0); + + node->setGeometry(g); + if (perfLevel <= Colored){ + g->setDrawingMode(GL_POINTS); + if (m_debugMode){ + GLfloat pointSizeRange[2]; + glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, pointSizeRange); + qDebug() << "Using point sprites, GL_ALIASED_POINT_SIZE_RANGE " <setDrawingMode(GL_TRIANGLES); + + for (int p=0; p < count; ++p) + commit(gIdx, p);//commit sets geometry for the node, has its own perfLevel switch + + if (perfLevel == Sprites) + initTexCoords((SpriteVertex*)g->vertexData(), vCount); + else if (perfLevel == Tabled) + initTexCoords((DeformableVertex*)g->vertexData(), vCount); + else if (perfLevel == Deformable) + initTexCoords((DeformableVertex*)g->vertexData(), vCount); + + if (perfLevel > Colored){ + quint16 *indices = g->indexDataAsUShort(); + for (int i=0; i < count; ++i) { + int o = i * 4; + indices[0] = o; + indices[1] = o + 1; + indices[2] = o + 2; + indices[3] = o + 1; + indices[4] = o + 3; + indices[5] = o + 2; + indices += 6; + } + } + } + + if (perfLevel == Sprites) + spritesUpdate();//Gives all vertexes the initial sprite data, then maintained per frame + + foreach (QSGGeometryNode* node, m_nodes){ + if (node == *(m_nodes.begin())) + node->setFlag(QSGGeometryNode::OwnsMaterial);//Root node owns the material for memory management purposes + else + (*(m_nodes.begin()))->appendChildNode(node); + } + + m_rootNode = *(m_nodes.begin()); + update(); +} + +QSGNode *QQuickImageParticle::updatePaintNode(QSGNode *, UpdatePaintNodeData *) +{ + if (m_pleaseReset){ + m_lastLevel = perfLevel; + + delete m_rootNode;//Automatically deletes children, and SG manages material lifetime + m_rootNode = 0; + m_nodes.clear(); + + m_idxStarts.clear(); + m_startsIdx.clear(); + m_lastIdxStart = 0; + + m_material = 0; + + m_pleaseReset = false; + m_buildingNodes = false;//Cancel a part-way build + } + + if (m_system && m_system->isRunning() && !m_system->isPaused()){ + prepareNextFrame(); + if (m_rootNode) { + update(); + foreach (QSGGeometryNode* node, m_nodes) + node->markDirty(QSGNode::DirtyGeometry); + } else if (m_buildingNodes) { + update();//To call prepareNextFrame() again from the renderThread + } + } + + return m_rootNode; +} + +void QQuickImageParticle::prepareNextFrame() +{ + if (m_rootNode == 0){//TODO: Staggered loading (as emitted) + buildParticleNodes(); + if (m_debugMode) { + qDebug() << "QQuickImageParticle Feature level: " << perfLevel; + qDebug() << "QQuickImageParticle Nodes: "; + int count = 0; + foreach (int i, m_nodes.keys()) { + qDebug() << "Group " << i << " (" << m_system->groupData[i]->size() << " particles)"; + count += m_system->groupData[i]->size(); + } + qDebug() << "Total count: " << count; + } + if (m_rootNode == 0) + return; + } + qint64 timeStamp = m_system->systemSync(this); + + qreal time = timeStamp / 1000.; + + switch (perfLevel){//Fall-through intended + case Sprites: + //Advance State + if (m_spriteEngine) + m_spriteEngine->updateSprites(timeStamp);//fires signals if anim changed + spritesUpdate(time); + case Tabled: + case Deformable: + case Colored: + case Simple: + default: //Also Simple + getState(m_material)->timestamp = time; + break; + } + foreach (QSGGeometryNode* node, m_nodes) + node->markDirty(QSGNode::DirtyMaterial); +} + +void QQuickImageParticle::spritesUpdate(qreal time) +{ + // Sprite progression handled CPU side, so as to have per-frame control. + foreach (const QString &str, m_groups) { + int gIdx = m_system->groupIds[str]; + foreach (QQuickParticleData* mainDatum, m_system->groupData[gIdx]->data) { + QSGGeometryNode *node = m_nodes[gIdx]; + if (!node) + continue; + //TODO: Interpolate between two different animations if it's going to transition next frame + // This is particularly important for cut-up sprites. + QQuickParticleData* datum = (mainDatum->animationOwner == this ? mainDatum : getShadowDatum(mainDatum)); + int spriteIdx = 0; + for (int i = 0; iindex; + break; + } + } + + double frameAt; + qreal progress = 0; + + if (datum->frameDuration > 0) { + qreal frame = (time - datum->animT)/(datum->frameDuration / 1000.0); + frame = qBound((qreal)0.0, frame, (qreal)((qreal)datum->frameCount - 1.0));//Stop at count-1 frames until we have between anim interpolation + if (m_spritesInterpolate) + progress = modf(frame,&frameAt); + else + modf(frame,&frameAt); + } else { + datum->frameAt++; + if (datum->frameAt >= datum->frameCount){ + datum->frameAt = 0; + m_spriteEngine->advance(spriteIdx); + } + frameAt = datum->frameAt; + } + if (m_spriteEngine->sprite(spriteIdx)->reverse())//### Store this in datum too? + frameAt = (datum->frameCount - 1) - frameAt; + QSizeF sheetSize = getState(m_material)->animSheetSize; + qreal y = datum->animY / sheetSize.height(); + qreal w = datum->animWidth / sheetSize.width(); + qreal h = datum->animHeight / sheetSize.height(); + qreal x1 = datum->animX / sheetSize.width(); + x1 += frameAt * w; + qreal x2 = x1; + if (frameAt < (datum->frameCount-1)) + x2 += w; + + node->setFlag(QSGNode::OwnsGeometry, false); + SpriteVertex *spriteVertices = (SpriteVertex *) node->geometry()->vertexData(); + spriteVertices += datum->index*4; + for (int i=0; i<4; i++) { + spriteVertices[i].animX1 = x1; + spriteVertices[i].animY1 = y; + spriteVertices[i].animX2 = x2; + spriteVertices[i].animY2 = y; + spriteVertices[i].animW = w; + spriteVertices[i].animH = h; + spriteVertices[i].animProgress = progress; + } + node->setFlag(QSGNode::OwnsGeometry, true); + } + } +} + +void QQuickImageParticle::spriteAdvance(int spriteIdx) +{ + if (!m_startsIdx.count())//Probably overly defensive + return; + + int gIdx = -1; + int i; + for (i = 0; igroupData[gIdx]->data[pIdx]; + QQuickParticleData* datum = (mainDatum->animationOwner == this ? mainDatum : getShadowDatum(mainDatum)); + + datum->animIdx = m_spriteEngine->spriteState(spriteIdx); + datum->animT = m_spriteEngine->spriteStart(spriteIdx)/1000.0; + datum->frameCount = m_spriteEngine->spriteFrames(spriteIdx); + datum->frameDuration = m_spriteEngine->spriteDuration(spriteIdx) / datum->frameCount; + datum->animX = m_spriteEngine->spriteX(spriteIdx); + datum->animY = m_spriteEngine->spriteY(spriteIdx); + datum->animWidth = m_spriteEngine->spriteWidth(spriteIdx); + datum->animHeight = m_spriteEngine->spriteHeight(spriteIdx); +} + +void QQuickImageParticle::reloadColor(const Color4ub &c, QQuickParticleData* d) +{ + d->color = c; + //TODO: get index for reload - or make function take an index +} + +void QQuickImageParticle::initialize(int gIdx, int pIdx) +{ + Color4ub color; + QQuickParticleData* datum = m_system->groupData[gIdx]->data[pIdx]; + qreal redVariation = m_color_variation + m_redVariation; + qreal greenVariation = m_color_variation + m_greenVariation; + qreal blueVariation = m_color_variation + m_blueVariation; + int spriteIdx = 0; + if (m_spriteEngine) { + spriteIdx = m_idxStarts[gIdx] + datum->index; + if (spriteIdx >= m_spriteEngine->count()) + m_spriteEngine->setCount(spriteIdx+1); + } + + float rotation; + float rotationSpeed; + float autoRotate; + switch (perfLevel){//Fall-through is intended on all of them + case Sprites: + // Initial Sprite State + if (m_explicitAnimation && m_spriteEngine){ + if (!datum->animationOwner) + datum->animationOwner = this; + QQuickParticleData* writeTo = (datum->animationOwner == this ? datum : getShadowDatum(datum)); + writeTo->animT = writeTo->t; + //writeTo->animInterpolate = m_spritesInterpolate; + if (m_spriteEngine){ + m_spriteEngine->start(spriteIdx); + writeTo->frameCount = m_spriteEngine->spriteFrames(spriteIdx); + writeTo->frameDuration = m_spriteEngine->spriteDuration(spriteIdx) / writeTo->frameCount; + writeTo->animIdx = 0;//Always starts at 0 + writeTo->frameAt = -1; + writeTo->animX = m_spriteEngine->spriteX(spriteIdx); + writeTo->animY = m_spriteEngine->spriteY(spriteIdx); + writeTo->animWidth = m_spriteEngine->spriteWidth(spriteIdx); + writeTo->animHeight = m_spriteEngine->spriteHeight(spriteIdx); + } + } else { + QQuickParticleData* writeTo = getShadowDatum(datum); + writeTo->animT = datum->t; + writeTo->frameCount = 1; + writeTo->frameDuration = 60000000.0; + writeTo->frameAt = -1; + writeTo->animIdx = 0; + writeTo->animT = 0; + writeTo->animX = writeTo->animY = 0; + writeTo->animWidth = getState(m_material)->animSheetSize.width(); + writeTo->animHeight = getState(m_material)->animSheetSize.height(); + } + case Tabled: + case Deformable: + //Initial Rotation + if (m_explicitDeformation){ + if (!datum->deformationOwner) + datum->deformationOwner = this; + if (m_xVector){ + const QPointF &ret = m_xVector->sample(QPointF(datum->x, datum->y)); + if (datum->deformationOwner == this) { + datum->xx = ret.x(); + datum->xy = ret.y(); + } else { + getShadowDatum(datum)->xx = ret.x(); + getShadowDatum(datum)->xy = ret.y(); + } + } + if (m_yVector){ + const QPointF &ret = m_yVector->sample(QPointF(datum->x, datum->y)); + if (datum->deformationOwner == this) { + datum->yx = ret.x(); + datum->yy = ret.y(); + } else { + getShadowDatum(datum)->yx = ret.x(); + getShadowDatum(datum)->yy = ret.y(); + } + } + } + + if (m_explicitRotation){ + if (!datum->rotationOwner) + datum->rotationOwner = this; + rotation = + (m_rotation + (m_rotationVariation - 2*((qreal)rand()/RAND_MAX)*m_rotationVariation) ) * CONV; + rotationSpeed = + (m_rotationSpeed + (m_rotationSpeedVariation - 2*((qreal)rand()/RAND_MAX)*m_rotationSpeedVariation) ) * CONV; + autoRotate = m_autoRotation?1.0:0.0; + if (datum->rotationOwner == this) { + datum->rotation = rotation; + datum->rotationSpeed = rotationSpeed; + datum->autoRotate = autoRotate; + } else { + getShadowDatum(datum)->rotation = rotation; + getShadowDatum(datum)->rotationSpeed = rotationSpeed; + getShadowDatum(datum)->autoRotate = autoRotate; + } + } + case Colored: + //Color initialization + // Particle color + if (m_explicitColor) { + if (!datum->colorOwner) + datum->colorOwner = this; + color.r = m_color.red() * (1 - redVariation) + rand() % 256 * redVariation; + color.g = m_color.green() * (1 - greenVariation) + rand() % 256 * greenVariation; + color.b = m_color.blue() * (1 - blueVariation) + rand() % 256 * blueVariation; + color.a = m_alpha * m_color.alpha() * (1 - m_alphaVariation) + rand() % 256 * m_alphaVariation; + if (datum->colorOwner == this) + datum->color = color; + else + getShadowDatum(datum)->color = color; + } + default: + break; + } +} + +void QQuickImageParticle::commit(int gIdx, int pIdx) +{ + if (m_pleaseReset) + return; + QSGGeometryNode *node = m_nodes[gIdx]; + if (!node) + return; + QQuickParticleData* datum = m_system->groupData[gIdx]->data[pIdx]; + node->setFlag(QSGNode::OwnsGeometry, false); + SpriteVertex *spriteVertices = (SpriteVertex *) node->geometry()->vertexData(); + DeformableVertex *deformableVertices = (DeformableVertex *) node->geometry()->vertexData(); + ColoredVertex *coloredVertices = (ColoredVertex *) node->geometry()->vertexData(); + SimpleVertex *simpleVertices = (SimpleVertex *) node->geometry()->vertexData(); + switch (perfLevel){//No automatic fall through intended on this one + case Sprites: + spriteVertices += pIdx*4; + for (int i=0; i<4; i++){ + spriteVertices[i].x = datum->x - m_systemOffset.x(); + spriteVertices[i].y = datum->y - m_systemOffset.y(); + spriteVertices[i].t = datum->t; + spriteVertices[i].lifeSpan = datum->lifeSpan; + spriteVertices[i].size = datum->size; + spriteVertices[i].endSize = datum->endSize; + spriteVertices[i].vx = datum->vx; + spriteVertices[i].vy = datum->vy; + spriteVertices[i].ax = datum->ax; + spriteVertices[i].ay = datum->ay; + if (m_explicitDeformation && datum->deformationOwner != this) { + QQuickParticleData* shadow = getShadowDatum(datum); + spriteVertices[i].xx = shadow->xx; + spriteVertices[i].xy = shadow->xy; + spriteVertices[i].yx = shadow->yx; + spriteVertices[i].yy = shadow->yy; + } else { + spriteVertices[i].xx = datum->xx; + spriteVertices[i].xy = datum->xy; + spriteVertices[i].yx = datum->yx; + spriteVertices[i].yy = datum->yy; + } + if (m_explicitRotation && datum->rotationOwner != this) { + QQuickParticleData* shadow = getShadowDatum(datum); + spriteVertices[i].rotation = shadow->rotation; + spriteVertices[i].rotationSpeed = shadow->rotationSpeed; + spriteVertices[i].autoRotate = shadow->autoRotate; + } else { + spriteVertices[i].rotation = datum->rotation; + spriteVertices[i].rotationSpeed = datum->rotationSpeed; + spriteVertices[i].autoRotate = datum->autoRotate; + } + //Sprite-related vertices updated per-frame in spritesUpdate(), not on demand + if (m_explicitColor && datum->colorOwner != this) { + QQuickParticleData* shadow = getShadowDatum(datum); + spriteVertices[i].color.r = shadow->color.r; + spriteVertices[i].color.g = shadow->color.g; + spriteVertices[i].color.b = shadow->color.b; + spriteVertices[i].color.a = shadow->color.a; + } else { + spriteVertices[i].color.r = datum->color.r; + spriteVertices[i].color.g = datum->color.g; + spriteVertices[i].color.b = datum->color.b; + spriteVertices[i].color.a = datum->color.a; + } + } + break; + case Tabled: //Fall through until it has its own vertex class + case Deformable: + deformableVertices += pIdx*4; + for (int i=0; i<4; i++){ + deformableVertices[i].x = datum->x - m_systemOffset.x(); + deformableVertices[i].y = datum->y - m_systemOffset.y(); + deformableVertices[i].t = datum->t; + deformableVertices[i].lifeSpan = datum->lifeSpan; + deformableVertices[i].size = datum->size; + deformableVertices[i].endSize = datum->endSize; + deformableVertices[i].vx = datum->vx; + deformableVertices[i].vy = datum->vy; + deformableVertices[i].ax = datum->ax; + deformableVertices[i].ay = datum->ay; + if (m_explicitDeformation && datum->deformationOwner != this) { + QQuickParticleData* shadow = getShadowDatum(datum); + deformableVertices[i].xx = shadow->xx; + deformableVertices[i].xy = shadow->xy; + deformableVertices[i].yx = shadow->yx; + deformableVertices[i].yy = shadow->yy; + } else { + deformableVertices[i].xx = datum->xx; + deformableVertices[i].xy = datum->xy; + deformableVertices[i].yx = datum->yx; + deformableVertices[i].yy = datum->yy; + } + if (m_explicitRotation && datum->rotationOwner != this) { + QQuickParticleData* shadow = getShadowDatum(datum); + deformableVertices[i].rotation = shadow->rotation; + deformableVertices[i].rotationSpeed = shadow->rotationSpeed; + deformableVertices[i].autoRotate = shadow->autoRotate; + } else { + deformableVertices[i].rotation = datum->rotation; + deformableVertices[i].rotationSpeed = datum->rotationSpeed; + deformableVertices[i].autoRotate = datum->autoRotate; + } + if (m_explicitColor && datum->colorOwner != this) { + QQuickParticleData* shadow = getShadowDatum(datum); + deformableVertices[i].color.r = shadow->color.r; + deformableVertices[i].color.g = shadow->color.g; + deformableVertices[i].color.b = shadow->color.b; + deformableVertices[i].color.a = shadow->color.a; + } else { + deformableVertices[i].color.r = datum->color.r; + deformableVertices[i].color.g = datum->color.g; + deformableVertices[i].color.b = datum->color.b; + deformableVertices[i].color.a = datum->color.a; + } + } + break; + case Colored: + coloredVertices += pIdx*1; + for (int i=0; i<1; i++){ + coloredVertices[i].x = datum->x - m_systemOffset.x(); + coloredVertices[i].y = datum->y - m_systemOffset.y(); + coloredVertices[i].t = datum->t; + coloredVertices[i].lifeSpan = datum->lifeSpan; + coloredVertices[i].size = datum->size; + coloredVertices[i].endSize = datum->endSize; + coloredVertices[i].vx = datum->vx; + coloredVertices[i].vy = datum->vy; + coloredVertices[i].ax = datum->ax; + coloredVertices[i].ay = datum->ay; + if (m_explicitColor && datum->colorOwner != this) { + QQuickParticleData* shadow = getShadowDatum(datum); + coloredVertices[i].color.r = shadow->color.r; + coloredVertices[i].color.g = shadow->color.g; + coloredVertices[i].color.b = shadow->color.b; + coloredVertices[i].color.a = shadow->color.a; + } else { + coloredVertices[i].color.r = datum->color.r; + coloredVertices[i].color.g = datum->color.g; + coloredVertices[i].color.b = datum->color.b; + coloredVertices[i].color.a = datum->color.a; + } + } + break; + case Simple: + simpleVertices += pIdx*1; + for (int i=0; i<1; i++){ + simpleVertices[i].x = datum->x - m_systemOffset.x(); + simpleVertices[i].y = datum->y - m_systemOffset.y(); + simpleVertices[i].t = datum->t; + simpleVertices[i].lifeSpan = datum->lifeSpan; + simpleVertices[i].size = datum->size; + simpleVertices[i].endSize = datum->endSize; + simpleVertices[i].vx = datum->vx; + simpleVertices[i].vy = datum->vy; + simpleVertices[i].ax = datum->ax; + simpleVertices[i].ay = datum->ay; + } + break; + default: + break; + } + + node->setFlag(QSGNode::OwnsGeometry, true); +} + + + +QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquickimageparticle_p.h qt5-declarative-0.1~git20120423/src/particles/qquickimageparticle_p.h --- qt5-declarative-0.1~git20120402/src/particles/qquickimageparticle_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquickimageparticle_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,446 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef ULTRAPARTICLE_H +#define ULTRAPARTICLE_H +#include "qquickparticlepainter_p.h" +#include "qquickdirection_p.h" +#include +#include +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class ImageMaterialData; +class QSGGeometryNode; + +class QQuickSprite; +class QQuickStochasticEngine; + +struct SimpleVertex { + float x; + float y; + float t; + float lifeSpan; + float size; + float endSize; + float vx; + float vy; + float ax; + float ay; +}; + +struct ColoredVertex { + float x; + float y; + float t; + float lifeSpan; + float size; + float endSize; + float vx; + float vy; + float ax; + float ay; + Color4ub color; +}; + +struct DeformableVertex { + float x; + float y; + float tx; + float ty; + float t; + float lifeSpan; + float size; + float endSize; + float vx; + float vy; + float ax; + float ay; + Color4ub color; + float xx; + float xy; + float yx; + float yy; + float rotation; + float rotationSpeed; + float autoRotate;//Assumed that GPUs prefer floats to bools +}; + +struct SpriteVertex { + float x; + float y; + float tx; + float ty; + float t; + float lifeSpan; + float size; + float endSize; + float vx; + float vy; + float ax; + float ay; + Color4ub color; + float xx; + float xy; + float yx; + float yy; + float rotation; + float rotationSpeed; + float autoRotate;//Assumed that GPUs prefer floats to bools + float animW; + float animH; + float animProgress; + float animX1; + float animY1; + float animX2; + float animY2; +}; + +template +struct Vertices { + Vertex v1; + Vertex v2; + Vertex v3; + Vertex v4; +}; + +class QQuickImageParticle : public QQuickParticlePainter +{ + Q_OBJECT + Q_PROPERTY(QUrl source READ image WRITE setImage NOTIFY imageChanged) + Q_PROPERTY(QQmlListProperty sprites READ sprites) + Q_PROPERTY(Status status READ status NOTIFY statusChanged) + //### Is it worth having progress like Image has? + //Q_PROPERTY(qreal progress READ progress NOTIFY progressChanged) + + Q_PROPERTY(QUrl colorTable READ colortable WRITE setColortable NOTIFY colortableChanged) + Q_PROPERTY(QUrl sizeTable READ sizetable WRITE setSizetable NOTIFY sizetableChanged) + Q_PROPERTY(QUrl opacityTable READ opacitytable WRITE setOpacitytable NOTIFY opacitytableChanged) + + //###Now just colorize - add a flag for 'solid' color particles(where the img is just a mask?)? + Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged RESET resetColor) + //Stacks (added) with individual colorVariations + Q_PROPERTY(qreal colorVariation READ colorVariation WRITE setColorVariation NOTIFY colorVariationChanged RESET resetColor) + Q_PROPERTY(qreal redVariation READ redVariation WRITE setRedVariation NOTIFY redVariationChanged RESET resetColor) + Q_PROPERTY(qreal greenVariation READ greenVariation WRITE setGreenVariation NOTIFY greenVariationChanged RESET resetColor) + Q_PROPERTY(qreal blueVariation READ blueVariation WRITE setBlueVariation NOTIFY blueVariationChanged RESET resetColor) + //Stacks (multiplies) with the Alpha in the color, mostly here so you can use svg color names (which have full alpha) + Q_PROPERTY(qreal alpha READ alpha WRITE setAlpha NOTIFY alphaChanged RESET resetColor) + Q_PROPERTY(qreal alphaVariation READ alphaVariation WRITE setAlphaVariation NOTIFY alphaVariationChanged RESET resetColor) + + Q_PROPERTY(qreal rotation READ rotation WRITE setRotation NOTIFY rotationChanged RESET resetRotation) + Q_PROPERTY(qreal rotationVariation READ rotationVariation WRITE setRotationVariation NOTIFY rotationVariationChanged RESET resetRotation) + Q_PROPERTY(qreal rotationSpeed READ rotationSpeed WRITE setRotationSpeed NOTIFY rotationSpeedChanged RESET resetRotation) + Q_PROPERTY(qreal rotationSpeedVariation READ rotationSpeedVariation WRITE setRotationSpeedVariation NOTIFY rotationSpeedVariationChanged RESET resetRotation) + //If true, then will face the direction of motion. Stacks with rotation, e.g. setting rotation + //to 180 will lead to facing away from the direction of motion + Q_PROPERTY(bool autoRotation READ autoRotation WRITE setAutoRotation NOTIFY autoRotationChanged RESET resetRotation) + + //xVector is the vector from the top-left point to the top-right point, and is multiplied by current size + Q_PROPERTY(QQuickDirection* xVector READ xVector WRITE setXVector NOTIFY xVectorChanged RESET resetDeformation) + //yVector is the same, but top-left to bottom-left. The particle is always a parallelogram. + Q_PROPERTY(QQuickDirection* yVector READ yVector WRITE setYVector NOTIFY yVectorChanged RESET resetDeformation) + Q_PROPERTY(bool spritesInterpolate READ spritesInterpolate WRITE setSpritesInterpolate NOTIFY spritesInterpolateChanged) + + Q_PROPERTY(EntryEffect entryEffect READ entryEffect WRITE setEntryEffect NOTIFY entryEffectChanged) + Q_ENUMS(EntryEffect) + Q_ENUMS(Status) +public: + explicit QQuickImageParticle(QQuickItem *parent = 0); + virtual ~QQuickImageParticle(); + + enum Status { Null, Ready, Loading, Error }; + + QQmlListProperty sprites(); + QQuickStochasticEngine* spriteEngine() {return m_spriteEngine;} + + enum EntryEffect { + None = 0, + Fade = 1, + Scale = 2 + }; + + enum PerformanceLevel{//TODO: Expose? + Unknown = 0, + Simple, + Colored, + Deformable, + Tabled, + Sprites + }; + + QUrl image() const { return m_image ? m_image->source : QUrl(); } + void setImage(const QUrl &image); + + QUrl colortable() const { return m_colorTable ? m_colorTable->source : QUrl(); } + void setColortable(const QUrl &table); + + QUrl sizetable() const { return m_sizeTable ? m_sizeTable->source : QUrl(); } + void setSizetable (const QUrl &table); + + QUrl opacitytable() const { return m_opacityTable ? m_opacityTable->source : QUrl(); } + void setOpacitytable(const QUrl &table); + + QColor color() const { return m_color; } + void setColor(const QColor &color); + + qreal colorVariation() const { return m_color_variation; } + void setColorVariation(qreal var); + + qreal alphaVariation() const { return m_alphaVariation; } + + qreal alpha() const { return m_alpha; } + + qreal redVariation() const { return m_redVariation; } + + qreal greenVariation() const { return m_greenVariation; } + + qreal blueVariation() const { return m_blueVariation; } + + qreal rotation() const { return m_rotation; } + + qreal rotationVariation() const { return m_rotationVariation; } + + qreal rotationSpeed() const { return m_rotationSpeed; } + + qreal rotationSpeedVariation() const { return m_rotationSpeedVariation; } + + bool autoRotation() const { return m_autoRotation; } + + QQuickDirection* xVector() const { return m_xVector; } + + QQuickDirection* yVector() const { return m_yVector; } + + bool spritesInterpolate() const { return m_spritesInterpolate; } + + bool bypassOptimizations() const { return m_bypassOptimizations; } + + EntryEffect entryEffect() const { return m_entryEffect; } + + Status status() const { return m_status; } + + void resetColor(); + void resetRotation(); + void resetDeformation(); + +signals: + + void imageChanged(); + void colortableChanged(); + void sizetableChanged(); + void opacitytableChanged(); + + void colorChanged(); + void colorVariationChanged(); + + void alphaVariationChanged(qreal arg); + + void alphaChanged(qreal arg); + + void redVariationChanged(qreal arg); + + void greenVariationChanged(qreal arg); + + void blueVariationChanged(qreal arg); + + void rotationChanged(qreal arg); + + void rotationVariationChanged(qreal arg); + + void rotationSpeedChanged(qreal arg); + + void rotationSpeedVariationChanged(qreal arg); + + void autoRotationChanged(bool arg); + + void xVectorChanged(QQuickDirection* arg); + + void yVectorChanged(QQuickDirection* arg); + + void spritesInterpolateChanged(bool arg); + + void bypassOptimizationsChanged(bool arg); + + void entryEffectChanged(EntryEffect arg); + + void statusChanged(Status arg); + +public slots: + void reloadColor(const Color4ub &c, QQuickParticleData* d); + void setAlphaVariation(qreal arg); + + void setAlpha(qreal arg); + + void setRedVariation(qreal arg); + + void setGreenVariation(qreal arg); + + void setBlueVariation(qreal arg); + + void setRotation(qreal arg); + + void setRotationVariation(qreal arg); + + void setRotationSpeed(qreal arg); + + void setRotationSpeedVariation(qreal arg); + + void setAutoRotation(bool arg); + + void setXVector(QQuickDirection* arg); + + void setYVector(QQuickDirection* arg); + + void setSpritesInterpolate(bool arg); + + void setBypassOptimizations(bool arg); + + void setEntryEffect(EntryEffect arg); + +protected: + void reset(); + virtual void initialize(int gIdx, int pIdx); + virtual void commit(int gIdx, int pIdx); + + QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *); + void prepareNextFrame(); + void buildParticleNodes(); + + void sceneGraphInvalidated(); + +private slots: + void createEngine(); //### method invoked by sprite list changing (in engine.h) - pretty nasty + + void spriteAdvance(int spriteIndex); + void spritesUpdate(qreal time = 0 ); + void finishBuildParticleNodes(); +private: + struct ImageData { + QUrl source; + QQuickPixmap pix; + }; + ImageData *m_image; + ImageData *m_colorTable; + ImageData *m_sizeTable; + ImageData *m_opacityTable; + bool loadingSomething(); + + + QColor m_color; + qreal m_color_variation; + + QSGGeometryNode *m_rootNode; + QHash m_nodes; + QHash m_idxStarts;//TODO: Proper resizing will lead to needing a spriteEngine per particle - do this after sprite engine gains transparent sharing? + QList > m_startsIdx;//Same data, optimized for alternate retrieval + + int m_lastIdxStart; + QSGMaterial *m_material; + + // derived values... + + qreal m_alphaVariation; + qreal m_alpha; + qreal m_redVariation; + qreal m_greenVariation; + qreal m_blueVariation; + qreal m_rotation; + qreal m_rotationVariation; + qreal m_rotationSpeed; + qreal m_rotationSpeedVariation; + bool m_autoRotation; + QQuickDirection* m_xVector; + QQuickDirection* m_yVector; + + QList m_sprites; + QQuickSpriteEngine* m_spriteEngine; + bool m_spritesInterpolate; + + bool m_explicitColor; + bool m_explicitRotation; + bool m_explicitDeformation; + bool m_explicitAnimation; + QHash > m_shadowData; + void clearShadows(); + QQuickParticleData* getShadowDatum(QQuickParticleData* datum); + + bool m_bypassOptimizations; + PerformanceLevel perfLevel; + + PerformanceLevel m_lastLevel; + bool m_debugMode; + + template + void initTexCoords(Vertex* v, int count){ + Vertex* end = v + count; + while (v < end){ + v[0].tx = 0; + v[0].ty = 0; + + v[1].tx = 1; + v[1].ty = 0; + + v[2].tx = 0; + v[2].ty = 1; + + v[3].tx = 1; + v[3].ty = 1; + + v += 4; + } + } + + template + MaterialData* getState(QSGMaterial* m){ + return static_cast *>(m)->state(); + } + EntryEffect m_entryEffect; + Status m_status; + bool m_buildingNodes; +}; + +QT_END_NAMESPACE +QT_END_HEADER +#endif // ULTRAPARTICLE_H diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquickitemparticle.cpp qt5-declarative-0.1~git20120423/src/particles/qquickitemparticle.cpp --- qt5-declarative-0.1~git20120402/src/particles/qquickitemparticle.cpp 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquickitemparticle.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,277 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickitemparticle_p.h" +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +/*! + \qmlclass ItemParticle QQuickItemParticle + \inqmlmodule QtQuick.Particles 2 + \inherits ParticlePainter + \brief The ItemParticle element allows you to specify your own delegate to paint particles. + +*/ + + +/*! + \qmlmethod void QtQuick.Particles2::ItemParticle::freeze(Item item) + + Suspends the flow of time for the logical particle which item represents, allowing you to control its movement. +*/ + +/*! + \qmlmethod void QtQuick.Particles2::ItemParticle::unfreeze(Item item) + + Restarts the flow of time for the logical particle which item represents, allowing it to be moved by the particle system again. +*/ + +/*! + \qmlmethod void QtQuick.Particles2::ItemParticle::take(Item item, bool prioritize) + + Asks the ItemParticle to take over control of item. It will be emitted when there is a logical particle available. + + By default items form a queue when waiting for a logical particle, but if prioritize is true then it will go immediately to the + head of the queue. +*/ +/*! + \qmlmethod void QtQuick.Particles2::ItemParticle::give(Item item) + + Orders the ItemParticle to give you control of the item. It will cease controlling it and the item will lose its association to the logical particle. +*/ + +/*! + \qmlproperty bool QtQuick.Particles2::ItemParticle::fade + + If true, the item will automatically be faded in and out + at the ends of its lifetime. If false, you will have to + implement any entry effect yourself. + + Default is true. +*/ +/*! + \qmlproperty Component QtQuick.Particles2::ItemParticle::delegate + + An instance of the delegate will be created for every logical + particle, and moved along with it. +*/ + +QQuickItemParticle::QQuickItemParticle(QQuickItem *parent) : + QQuickParticlePainter(parent), m_fade(true), m_delegate(0) +{ + setFlag(QQuickItem::ItemHasContents); + clock = new Clock(this); + clock->start(); +} + +QQuickItemParticle::~QQuickItemParticle() +{ + delete clock; +} + +void QQuickItemParticle::freeze(QQuickItem* item) +{ + m_stasis << item; +} + + +void QQuickItemParticle::unfreeze(QQuickItem* item) +{ + m_stasis.remove(item); +} + +void QQuickItemParticle::take(QQuickItem *item, bool prioritize) +{ + if (prioritize) + m_pendingItems.push_front(item); + else + m_pendingItems.push_back(item); +} + +void QQuickItemParticle::give(QQuickItem *item) +{ + //TODO: This + Q_UNUSED(item); +} + +void QQuickItemParticle::initialize(int gIdx, int pIdx) +{ + m_loadables << m_system->groupData[gIdx]->data[pIdx];//defer to other thread +} + +void QQuickItemParticle::commit(int, int) +{ +} + +void QQuickItemParticle::tick(int time) +{ + Q_UNUSED(time);//only needed because QTickAnimationProxy expects one + foreach (QQuickItem* item, m_deletables){ + if (m_fade) + item->setOpacity(0.); + item->setVisible(false); + QQuickItemParticleAttached* mpa; + if ((mpa = qobject_cast(qmlAttachedPropertiesObject(item)))) + mpa->detach();//reparent as well? + //TODO: Delete iff we created it + m_activeCount--; + } + m_deletables.clear(); + + foreach (QQuickParticleData* d, m_loadables){ + if (m_stasis.contains(d->delegate)) + qWarning() << "Current model particles prefers overwrite:false"; + //remove old item from the particle that is dying to make room for this one + if (d->delegate) + m_deletables << d->delegate; + d->delegate = 0; + if (!m_pendingItems.isEmpty()){ + d->delegate = m_pendingItems.front(); + m_pendingItems.pop_front(); + }else if (m_delegate){ + d->delegate = qobject_cast(m_delegate->create(qmlContext(this))); + } + if (d->delegate && d){//###Data can be zero if creating an item leads to a reset - this screws things up. + d->delegate->setX(d->curX() - d->delegate->width()/2);//TODO: adjust for system? + d->delegate->setY(d->curY() - d->delegate->height()/2); + QQuickItemParticleAttached* mpa = qobject_cast(qmlAttachedPropertiesObject(d->delegate)); + if (mpa){ + mpa->m_mp = this; + mpa->attach(); + } + d->delegate->setParentItem(this); + if (m_fade) + d->delegate->setOpacity(0.); + d->delegate->setVisible(false);//Will be set to true when we prepare the next frame + m_activeCount++; + } + } + m_loadables.clear(); +} + +void QQuickItemParticle::reset() +{ + QQuickParticlePainter::reset(); + m_loadables.clear(); + //TODO: Cleanup items? + //deletables? +} + + +QSGNode* QQuickItemParticle::updatePaintNode(QSGNode* n, UpdatePaintNodeData* d) +{ + //Dummy update just to get painting tick + if (m_pleaseReset){ + m_pleaseReset = false; + //Refill loadables, delayed here so as to only happen once per frame max + //### Constant resetting might lead to m_loadables never being populated when tick() occurs + foreach (const QString group, m_groups){ + int gIdx = m_system->groupIds[group]; + foreach (QQuickParticleData* d, m_system->groupData[gIdx]->data) + if (!d->delegate && d->t != -1 && d->stillAlive()) + m_loadables << d; + } + } + prepareNextFrame(); + + update();//Get called again + if (n) + n->markDirty(QSGNode::DirtyMaterial); + return QQuickItem::updatePaintNode(n,d); +} + +void QQuickItemParticle::prepareNextFrame() +{ + if (!m_system) + return; + qint64 timeStamp = m_system->systemSync(this); + qreal curT = timeStamp/1000.0; + qreal dt = curT - m_lastT; + m_lastT = curT; + if (!m_activeCount) + return; + + //TODO: Size, better fade? + foreach (const QString &str, m_groups){ + int gIdx = m_system->groupIds[str]; + int count = m_system->groupData[gIdx]->size(); + + for (int i=0; igroupData[gIdx]->data[i]; + QQuickItem* item = data->delegate; + if (!item) + continue; + qreal t = ((timeStamp/1000.0) - data->t) / data->lifeSpan; + if (m_stasis.contains(item)) { + data->t += dt;//Stasis effect + continue; + } + if (t >= 1.0){//Usually happens from load + m_deletables << item; + data->delegate = 0; + }else{//Fade + data->delegate->setVisible(true); + if (m_fade){ + qreal o = 1.; + if (t<0.2) + o = t*5; + if (t>0.8) + o = (1-t)*5; + item->setOpacity(o); + } + } + item->setX(data->curX() - item->width()/2 - m_systemOffset.x()); + item->setY(data->curY() - item->height()/2 - m_systemOffset.y()); + } + } +} + +QQuickItemParticleAttached *QQuickItemParticle::qmlAttachedProperties(QObject *object) +{ + return new QQuickItemParticleAttached(object); +} + +QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquickitemparticle_p.h qt5-declarative-0.1~git20120423/src/particles/qquickitemparticle_p.h --- qt5-declarative-0.1~git20120402/src/particles/qquickitemparticle_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquickitemparticle_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,141 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef ITEMPARTICLE_H +#define ITEMPARTICLE_H +#include "qquickparticlepainter_p.h" +#include +#include +#include +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QQuickVisualDataModel; +class QQuickItemParticleAttached; + +class QQuickItemParticle : public QQuickParticlePainter +{ + Q_OBJECT + Q_PROPERTY(bool fade READ fade WRITE setFade NOTIFY fadeChanged) + Q_PROPERTY(QQmlComponent* delegate READ delegate WRITE setDelegate NOTIFY delegateChanged) +public: + explicit QQuickItemParticle(QQuickItem *parent = 0); + ~QQuickItemParticle(); + + bool fade() const { return m_fade; } + + virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *); + + static QQuickItemParticleAttached *qmlAttachedProperties(QObject *object); + QQmlComponent* delegate() const + { + return m_delegate; + } + +signals: + void fadeChanged(); + + void delegateChanged(QQmlComponent* arg); + +public slots: + //TODO: Add a follow mode, where moving the delegate causes the logical particle to go with it? + void freeze(QQuickItem* item); + void unfreeze(QQuickItem* item); + void take(QQuickItem* item,bool prioritize=false);//take by modelparticle + void give(QQuickItem* item);//give from modelparticle + + void setFade(bool arg){if (arg == m_fade) return; m_fade = arg; emit fadeChanged();} + void setDelegate(QQmlComponent* arg) + { + if (m_delegate != arg) { + m_delegate = arg; + emit delegateChanged(arg); + } + } + +protected: + virtual void reset(); + virtual void commit(int gIdx, int pIdx); + virtual void initialize(int gIdx, int pIdx); + void prepareNextFrame(); +private: + void tick(int time = 0); + QList m_deletables; + QList< QQuickParticleData* > m_loadables; + bool m_fade; + + QList m_pendingItems; + QList m_available; + QSet m_stasis; + qreal m_lastT; + int m_activeCount; + QQmlComponent* m_delegate; + + typedef QTickAnimationProxy Clock; + Clock *clock; +}; + +class QQuickItemParticleAttached : public QObject +{ + Q_OBJECT + Q_PROPERTY(QQuickItemParticle* particle READ particle CONSTANT); +public: + QQuickItemParticleAttached(QObject* parent) + : QObject(parent), m_mp(0) + {;} + QQuickItemParticle* particle() {return m_mp;} + void detach(){emit detached();} + void attach(){emit attached();} +private: + QQuickItemParticle* m_mp; + friend class QQuickItemParticle; +Q_SIGNALS: + void detached(); + void attached(); +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPEINFO(QQuickItemParticle, QML_HAS_ATTACHED_PROPERTIES) + +QT_END_HEADER +#endif // ITEMPARTICLE_H diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquicklineextruder.cpp qt5-declarative-0.1~git20120423/src/particles/qquicklineextruder.cpp --- qt5-declarative-0.1~git20120402/src/particles/qquicklineextruder.cpp 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquicklineextruder.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "qquicklineextruder_p.h" +#include +#include + +/*! + \qmlclass LineShape QQuickLineExtruder + \inqmlmodule QtQuick.Particles 2 + \inherits Shape + \brief The LineShape represents a line to Affectors and Emitter + +*/ + +/*! + \qmlproperty bool QtQuick.Particles2::LineShape::mirrored + + By default, the line goes from (0,0) to (width, height) of the item that + this shape is being applied to. + + If mirrored is set to true, this will be mirrored along the y axis. + The line will then go from (0,height) to (width, 0). +*/ + +QQuickLineExtruder::QQuickLineExtruder(QObject *parent) : + QQuickParticleExtruder(parent), m_mirrored(false) +{ +} + +QPointF QQuickLineExtruder::extrude(const QRectF &r) +{ + qreal x,y; + if (!r.height()){ + x = r.width() * ((qreal)rand())/RAND_MAX; + y = 0; + }else{ + y = r.height() * ((qreal)rand())/RAND_MAX; + if (!r.width()){ + x = 0; + }else{ + x = r.width()/r.height() * y; + if (m_mirrored) + x = r.width() - x; + } + } + return QPointF(x,y); +} diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquicklineextruder_p.h qt5-declarative-0.1~git20120423/src/particles/qquicklineextruder_p.h --- qt5-declarative-0.1~git20120402/src/particles/qquicklineextruder_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquicklineextruder_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef LINEEXTRUDER_H +#define LINEEXTRUDER_H +#include "qquickparticleextruder_p.h" + +class QQuickLineExtruder : public QQuickParticleExtruder +{ + Q_OBJECT + //Default is topleft to bottom right. Flipped makes it topright to bottom left + Q_PROPERTY(bool mirrored READ mirrored WRITE setmirrored NOTIFY mirroredChanged) + +public: + explicit QQuickLineExtruder(QObject *parent = 0); + virtual QPointF extrude(const QRectF &); + bool mirrored() const + { + return m_mirrored; + } + +signals: + + void mirroredChanged(bool arg); + +public slots: + + void setmirrored(bool arg) + { + if (m_mirrored != arg) { + m_mirrored = arg; + emit mirroredChanged(arg); + } + } +private: + bool m_mirrored; +}; + +#endif // LINEEXTRUDER_H diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquickmaskextruder.cpp qt5-declarative-0.1~git20120423/src/particles/qquickmaskextruder.cpp --- qt5-declarative-0.1~git20120402/src/particles/qquickmaskextruder.cpp 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquickmaskextruder.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,141 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickmaskextruder_p.h" +#include +#include +#include +#include +QT_BEGIN_NAMESPACE +/*! + \qmlclass MaskShape QQuickMaskExtruder + \inqmlmodule QtQuick.Particles 2 + \inherits Shape + \brief The MaskShape element allows you to represent an image as a shape to affectors and emitters. + +*/ +/*! + \qmlproperty url QtQuick.Particles2::MaskShape::source + + The image to use as the mask. Areas with non-zero opacity + will be considered inside the shape. +*/ + + +QQuickMaskExtruder::QQuickMaskExtruder(QObject *parent) : + QQuickParticleExtruder(parent) + , m_lastWidth(-1) + , m_lastHeight(-1) +{ +} + +void QQuickMaskExtruder::setSource(QUrl arg) +{ + if (m_source != arg) { + m_source = arg; + + m_lastHeight = -1;//Trigger reset + m_lastWidth = -1; + emit sourceChanged(arg); + startMaskLoading(); + } +} + +void QQuickMaskExtruder::startMaskLoading() +{ + m_pix.clear(this); + if (m_source.isEmpty()) + return; + m_pix.load(qmlEngine(this), m_source); + if (m_pix.isLoading()) + m_pix.connectFinished(this, SLOT(finishMaskLoading())); + else + finishMaskLoading(); +} + +void QQuickMaskExtruder::finishMaskLoading() +{ + if (m_pix.isError()) + qmlInfo(this) << m_pix.error(); +} + +QPointF QQuickMaskExtruder::extrude(const QRectF &r) +{ + ensureInitialized(r); + if (!m_mask.count() || m_img.isNull()) + return r.topLeft(); + const QPointF p = m_mask[rand() % m_mask.count()]; + //### Should random sub-pixel positioning be added? + return p + r.topLeft(); +} + +bool QQuickMaskExtruder::contains(const QRectF &bounds, const QPointF &point) +{ + ensureInitialized(bounds);//###Current usage patterns WILL lead to different bounds/r calls. Separate list? + if (m_img.isNull()) + return false; + QPoint p = point.toPoint() - bounds.topLeft().toPoint(); + return m_img.rect().contains(p) && (bool)m_img.pixelIndex(p); +} + +void QQuickMaskExtruder::ensureInitialized(const QRectF &r) +{ + if (m_lastWidth == r.width() && m_lastHeight == r.height()) + return;//Same as before + if (!m_pix.isReady()) + return; + m_lastWidth = r.width(); + m_lastHeight = r.height(); + + m_mask.clear(); + + m_img = m_pix.image().createAlphaMask(); + m_pix.clear(); + m_img = m_img.convertToFormat(QImage::Format_Mono);//Else LSB, but I think that's easier + m_img = m_img.scaled(r.size().toSize());//TODO: Do they need aspect ratio stuff? Or tiling? + for (int i=0; i +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QQuickMaskExtruder : public QQuickParticleExtruder +{ + Q_OBJECT + Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged) +public: + explicit QQuickMaskExtruder(QObject *parent = 0); + virtual QPointF extrude(const QRectF &); + virtual bool contains(const QRectF &bounds, const QPointF &point); + + QUrl source() const + { + return m_source; + } + +signals: + + void sourceChanged(QUrl arg); + +public slots: + void setSource(QUrl arg); + +private slots: + void startMaskLoading(); + void finishMaskLoading(); + +private: + QUrl m_source; + + void ensureInitialized(const QRectF &r); + int m_lastWidth; + int m_lastHeight; + QQuickPixmap m_pix; + QImage m_img; + QList m_mask;//TODO: More memory efficient datastructures + //Perhaps just the mask for the largest bounds is stored, and interpolate up +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // MASKEXTRUDER_H diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquickparticleaffector.cpp qt5-declarative-0.1~git20120423/src/particles/qquickparticleaffector.cpp --- qt5-declarative-0.1~git20120402/src/particles/qquickparticleaffector.cpp 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquickparticleaffector.cpp 2012-04-23 11:44:59.000000000 +0000 @@ -0,0 +1,279 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickparticleaffector_p.h" +#include +QT_BEGIN_NAMESPACE + +/*! + \qmlclass Affector QQuickParticleAffector + \inqmlmodule QtQuick.Particles 2 + \brief Affector elements can alter the attributes of logical particles at any point in their lifetime. + + The base Affector does not alter any attributes, but can be used to emit a signal + when a particle meets certain conditions. + + If an affector has a defined size, then it will only affect particles within its size and position on screen. + + Affectors have different performance characteristics to the other particle system elements. In particular, + they have some simplifications to try to maintain a simulation at real-time or faster. When running a system + with Affectors, irregular frame timings that grow too large ( > one second per frame) will cause the Affectors + to try and cut corners with a faster but less accurate simulation. If the system has multiple affectors the order + in which they are applied is not guaranteed, and when simulating larger time shifts they will simulate the whole + shift each, which can lead to different results compared to smaller time shifts. + + Accurate simulation for large numbers of particles (hundreds) with multiple affectors may be possible on some hardware, + but on less capable hardware you should expect small irregularties in the simulation as simulates with worse granularity. +*/ +/*! + \qmlproperty ParticleSystem QtQuick.Particles2::Affector::system + This is the system which will be affected by the element. + If the Affector is a direct child of a ParticleSystem, it will automatically be associated with it. +*/ +/*! + \qmlproperty list QtQuick.Particles2::Affector::groups + Which logical particle groups will be affected. + + If empty, it will affect all particles. +*/ +/*! + \qmlproperty list QtQuick.Particles2::Affector::whenCollidingWith + If any logical particle groups are specified here, then the affector + will only be triggered if the particle being examined intersects with + a particle of one of these groups. + + This is different from the groups property. The groups property selects which + particles might be examined, and if they meet other criteria (including being + within the bounds of the Affector, modified by shape) then they will be tested + again to see if they intersect with a particles from one of the particle groups + in whenCollidingWith. + + By default, no groups are specified. +*/ +/*! + \qmlproperty bool QtQuick.Particles2::Affector::enabled + If enabled is set to false, this affector will not affect any particles. + + Usually this is used to conditionally turn an affector on or off. + + Default value is true. +*/ +/*! + \qmlproperty bool QtQuick.Particles2::Affector::once + If once is set to true, this affector will only affect each particle + once in their lifetimes. If the affector normally simulates a continuous + effect over time, then it will simulate the effect of one second of time + the one instant it affects the particle. + + Default value is false. +*/ +/*! + \qmlproperty Shape QtQuick.Particles2::Affector::shape + If a size has been defined, the shape property can be used to affect a + non-rectangular area. +*/ +/*! + \qmlsignal QtQuick.Particles2::Affector::onAffected(x, y) + + This signal is emitted each time the affector actually affects a particle. + + x,y are the coordinates of the affected particle, relative to the ParticleSystem. + +*/ + +/*! + \qmlsignal QtQuick.Particles2::Affector::affectParticle(particle particle, real dt) + + This handler is called when particles are selected to be affected. + + dt is the time since the last time it was affected. Use dt to normalize + trajectory manipulations to real time. + + Note that JS is slower to execute, so it is not recommended to use this in + high-volume particle systems. +*/ +/*! + \qmlsignal QtQuick.Particles2::Affector::affected(real x, real y) + + This handler is called when a particle is selected to be affected. It will + only be called if signal is set to true. + + x,y is the particles current position. +*/ +QQuickParticleAffector::QQuickParticleAffector(QQuickItem *parent) : + QQuickItem(parent), m_needsReset(false), m_ignoresTime(false), m_onceOff(false), m_enabled(true) + , m_system(0), m_updateIntSet(false), m_shape(new QQuickParticleExtruder(this)) +{ +} + +bool QQuickParticleAffector::isAffectedConnected() +{ + static int idx = QObjectPrivate::get(this)->signalIndex("affected(qreal,qreal)"); + return QObjectPrivate::get(this)->isSignalConnected(idx); +} + + +void QQuickParticleAffector::componentComplete() +{ + if (!m_system && qobject_cast(parentItem())) + setSystem(qobject_cast(parentItem())); + QQuickItem::componentComplete(); +} + +bool QQuickParticleAffector::activeGroup(int g) { + if (m_updateIntSet){ //This can occur before group ids are properly assigned, but that resets the flag + m_groupIds.clear(); + foreach (const QString &p, m_groups) + m_groupIds << m_system->groupIds[p]; + m_updateIntSet = false; + } + return m_groupIds.isEmpty() || m_groupIds.contains(g); +} + +bool QQuickParticleAffector::shouldAffect(QQuickParticleData* d) +{ + if (!d) + return false; + if (activeGroup(d->group)){ + if ((m_onceOff && m_onceOffed.contains(qMakePair(d->group, d->index))) + || !d->stillAlive()) + return false; + //Need to have previous location for affected anyways + if (width() == 0 || height() == 0 + || m_shape->contains(QRectF(m_offset.x(), m_offset.y(), width(), height()), QPointF(d->curX(), d->curY()))){ + if (m_whenCollidingWith.isEmpty() || isColliding(d)){ + return true; + } + } + } + return false; + +} + +void QQuickParticleAffector::postAffect(QQuickParticleData* d) +{ + m_system->needsReset << d; + if (m_onceOff) + m_onceOffed << qMakePair(d->group, d->index); + if (isAffectedConnected()) + emit affected(d->curX(), d->curY()); +} + +const qreal QQuickParticleAffector::simulationDelta = 0.020; +const qreal QQuickParticleAffector::simulationCutoff = 1.000;//If this goes above 1.0, then m_once behaviour needs special codepath + +void QQuickParticleAffector::affectSystem(qreal dt) +{ + if (!m_enabled) + return; + //If not reimplemented, calls affectParticle per particle + //But only on particles in targeted system/area + updateOffsets();//### Needed if an ancestor is transformed. + if (m_onceOff) + dt = 1.0; + foreach (QQuickParticleGroupData* gd, m_system->groupData) { + if (activeGroup(m_system->groupData.key(gd))) { + foreach (QQuickParticleData* d, gd->data) { + if (shouldAffect(d)) { + bool affected = false; + qreal myDt = dt; + if (!m_ignoresTime && myDt < simulationCutoff) { + int realTime = m_system->timeInt; + m_system->timeInt -= myDt * 1000.0; + while (myDt > simulationDelta) { + m_system->timeInt += simulationDelta * 1000.0; + if (d->alive())//Only affect during the parts it was alive for + affected = affectParticle(d, simulationDelta) || affected; + myDt -= simulationDelta; + } + m_system->timeInt = realTime; + } + if (myDt > 0.0) + affected = affectParticle(d, myDt) || affected; + if (affected) + postAffect(d); + } + } + } + } +} + +bool QQuickParticleAffector::affectParticle(QQuickParticleData *, qreal ) +{ + return true; +} + +void QQuickParticleAffector::reset(QQuickParticleData* pd) +{//TODO: This, among other ones, should be restructured so they don't all need to remember to call the superclass + if (m_onceOff) + if (activeGroup(pd->group)) + m_onceOffed.remove(qMakePair(pd->group, pd->index)); +} + +void QQuickParticleAffector::updateOffsets() +{ + if (m_system) + m_offset = m_system->mapFromItem(this, QPointF(0, 0)); +} + +bool QQuickParticleAffector::isColliding(QQuickParticleData *d) +{ + qreal myCurX = d->curX(); + qreal myCurY = d->curY(); + qreal myCurSize = d->curSize()/2; + foreach (const QString &group, m_whenCollidingWith){ + foreach (QQuickParticleData* other, m_system->groupData[m_system->groupIds[group]]->data){ + if (!other->stillAlive()) + continue; + qreal otherCurX = other->curX(); + qreal otherCurY = other->curY(); + qreal otherCurSize = other->curSize()/2; + if ((myCurX + myCurSize > otherCurX - otherCurSize + && myCurX - myCurSize < otherCurX + otherCurSize) + && (myCurY + myCurSize > otherCurY - otherCurSize + && myCurY - myCurSize < otherCurY + otherCurSize)) + return true; + } + } + return false; +} + +QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquickparticleaffector_p.h qt5-declarative-0.1~git20120423/src/particles/qquickparticleaffector_p.h --- qt5-declarative-0.1~git20120402/src/particles/qquickparticleaffector_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquickparticleaffector_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,199 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PARTICLEAFFECTOR_H +#define PARTICLEAFFECTOR_H + +#include +#include "qquickparticlesystem_p.h" +#include "qquickparticleextruder_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QQuickParticleAffector : public QQuickItem +{ + Q_OBJECT + Q_PROPERTY(QQuickParticleSystem* system READ system WRITE setSystem NOTIFY systemChanged) + Q_PROPERTY(QStringList groups READ groups WRITE setGroups NOTIFY groupsChanged) + Q_PROPERTY(QStringList whenCollidingWith READ whenCollidingWith WRITE setWhenCollidingWith NOTIFY whenCollidingWithChanged) + Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged) + Q_PROPERTY(bool once READ onceOff WRITE setOnceOff NOTIFY onceChanged) + Q_PROPERTY(QQuickParticleExtruder* shape READ shape WRITE setShape NOTIFY shapeChanged) + +public: + explicit QQuickParticleAffector(QQuickItem *parent = 0); + virtual void affectSystem(qreal dt); + virtual void reset(QQuickParticleData*);//As some store their own data per particle? + QQuickParticleSystem* system() const + { + return m_system; + } + + QStringList groups() const + { + return m_groups; + } + + bool enabled() const + { + return m_enabled; + } + + bool onceOff() const + { + return m_onceOff; + } + + QQuickParticleExtruder* shape() const + { + return m_shape; + } + + QStringList whenCollidingWith() const + { + return m_whenCollidingWith; + } + +signals: + + void systemChanged(QQuickParticleSystem* arg); + + void groupsChanged(QStringList arg); + + void enabledChanged(bool arg); + + void onceChanged(bool arg); + + void shapeChanged(QQuickParticleExtruder* arg); + + void affected(qreal x, qreal y); + + void whenCollidingWithChanged(QStringList arg); + +public slots: +void setSystem(QQuickParticleSystem* arg) +{ + if (m_system != arg) { + m_system = arg; + m_system->registerParticleAffector(this); + emit systemChanged(arg); + } +} + +void setGroups(QStringList arg) +{ + if (m_groups != arg) { + m_groups = arg; + m_updateIntSet = true; + emit groupsChanged(arg); + } +} + +void setEnabled(bool arg) +{ + if (m_enabled != arg) { + m_enabled = arg; + emit enabledChanged(arg); + } +} + +void setOnceOff(bool arg) +{ + if (m_onceOff != arg) { + m_onceOff = arg; + m_needsReset = true; + emit onceChanged(arg); + } +} + +void setShape(QQuickParticleExtruder* arg) +{ + if (m_shape != arg) { + m_shape = arg; + emit shapeChanged(arg); + } +} + +void setWhenCollidingWith(QStringList arg) +{ + if (m_whenCollidingWith != arg) { + m_whenCollidingWith = arg; + emit whenCollidingWithChanged(arg); + } +} +public slots: + void updateOffsets(); + +protected: + friend class QQuickParticleSystem; + virtual bool affectParticle(QQuickParticleData *d, qreal dt); + bool m_needsReset:1;//### What is this really saving? + bool m_ignoresTime:1; + bool m_onceOff:1; + bool m_enabled:1; + + QQuickParticleSystem* m_system; + QStringList m_groups; + bool activeGroup(int g); + bool shouldAffect(QQuickParticleData* datum);//Call to do the logic on whether it is affecting that datum + void postAffect(QQuickParticleData* datum);//Call to do the post-affect logic on particles which WERE affected(once off, needs reset, affected signal) + virtual void componentComplete(); + QPointF m_offset; + bool isAffectedConnected(); + static const qreal simulationDelta; + static const qreal simulationCutoff; +private: + QSet m_groupIds; + QSet > m_onceOffed; + bool m_updateIntSet; + + QQuickParticleExtruder* m_shape; + + QStringList m_whenCollidingWith; + + bool isColliding(QQuickParticleData* d); +}; + +QT_END_NAMESPACE +QT_END_HEADER +#endif // PARTICLEAFFECTOR_H diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquickparticleemitter.cpp qt5-declarative-0.1~git20120423/src/particles/qquickparticleemitter.cpp --- qt5-declarative-0.1~git20120402/src/particles/qquickparticleemitter.cpp 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquickparticleemitter.cpp 2012-04-23 11:44:59.000000000 +0000 @@ -0,0 +1,495 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickparticleemitter_p.h" +#include +QT_BEGIN_NAMESPACE + + +/*! + \qmlclass Emitter QQuickParticleEmitter + \inqmlmodule QtQuick.Particles 2 + \brief The Emitter element allows you to emit logical particles. + + This element emits logical particles into the ParticleSystem, with the + given starting attributes. + + Note that logical particles are not + automatically rendered, you will need to have one or more + ParticlePainter elements visualizing them. + + Note that the given starting attributes can be modified at any point + in the particle's lifetime by any Affector element in the same + ParticleSystem. This includes attributes like lifespan. +*/ + + +/*! + \qmlproperty ParticleSystem QtQuick.Particles2::Emitter::system + + This is the Particle system that the Emitter will emit into. + This can be omitted if the Emitter is a direct child of the ParticleSystem +*/ +/*! + \qmlproperty string QtQuick.Particles2::Emitter::group + + This is the logical particle group which it will emit into. + + Default value is "" (empty string). +*/ +/*! + \qmlproperty Shape QtQuick.Particles2::Emitter::shape + + This shape is applied with the size of the Emitter. Particles will be emitted + randomly from any area covered by the shape. + + The default shape is a filled in rectangle, which corresponds to the full bounding + box of the Emitter. +*/ +/*! + \qmlproperty bool QtQuick.Particles2::Emitter::emitting + + If set to false, the emitter will cease emissions until it is set to true. + + Default value is true. +*/ +/*! + \qmlproperty real QtQuick.Particles2::Emitter::emitRate + + Number of particles emitted per second. + + Default value is 10 particles per second. +*/ +/*! + \qmlproperty int QtQuick.Particles2::Emitter::lifeSpan + + The time in milliseconds each emitted particle should last for. + + If you do not want particles to automatically die after a time, for example if + you wish to dispose of them manually, set lifeSpan to Emitter.InfiniteLife. + + lifeSpans greater than or equal to 600000 (10 minutes) will be treated as infinite. + Particles with lifeSpans less than or equal to 0 will start out dead. + + Default value is 1000 (one second). +*/ +/*! + \qmlproperty int QtQuick.Particles2::Emitter::lifeSpanVariation + + Particle lifespans will vary by up to this much in either direction. + + Default value is 0. +*/ + +/*! + \qmlproperty int QtQuick.Particles2::Emitter::maximumEmitted + + The maximum number of particles at a time that this emitter will have alive. + + This can be set as a performance optimization (when using burst and pulse) or + to stagger emissions. + + If this is set to a number below zero, then there is no maximum limit on the number + of particles this emitter can have alive. + + The default value is -1. +*/ +/*! + \qmlproperty int QtQuick.Particles2::Emitter::startTime + + If this value is set when the emitter is loaded, then it will emit particles from the + past, up to startTime milliseconds ago. These will simulate as if they were emitted then, + but will not have any affectors applied to them. Affectors will take effect from the present time. +*/ +/*! + \qmlproperty real QtQuick.Particles2::Emitter::size + + The size in pixels of the particles at the start of their life. + + Default value is 16. +*/ +/*! + \qmlproperty real QtQuick.Particles2::Emitter::endSize + + The size in pixels of the particles at the end of their life. Size will + be linearly interpolated during the life of the particle from this value and + size. If endSize is -1, then the size of the particle will remain constant at + the starting size. + + Default value is -1. +*/ +/*! + \qmlproperty real QtQuick.Particles2::Emitter::sizeVariation + + The size of a particle can vary by this much up or down from size/endSize. The same + random addition is made to both size and endSize for a single particle. + + Default value is 0. +*/ +/*! + \qmlproperty StochasticDirection QtQuick.Particles2::Emitter::speed + + The starting speed of the particles emitted. +*/ +/*! + \qmlproperty StochasticDirection QtQuick.Particles2::Emitter::acceleration + + The starting acceleraton of the particles emitted. +*/ +/*! + \qmlproperty qreal QtQuick.Particles2::Emitter::speedFromMovement + + If this value is non-zero, then any movement of the emitter will provide additional + starting velocity to the particles based on the movement. The additional vector will be the + same angle as the emitter's movement, with a magnitude that is the magnitude of the emitters + movement multiplied by speedFromMovement. + + Default value is 0. +*/ + +/*! + \qmlsignal QtQuick.Particles2::Emitter::onEmitParticles(Array particles) + + This handler is called when particles are emitted. particles is a javascript + array of Particle objects. You can modify particle attributes directly within the handler. + + Note that JS is slower to execute, so it is not recommended to use this in + high-volume particle systems. +*/ + +/*! \qmlmethod QtQuick.Particles2::Emitter::burst(int count) + + Emits count particles from this emitter immediately. +*/ + +/*! \qmlmethod QtQuick.Particles2::Emitter::burst(int x, int y, int count) + + Emits count particles from this emitter immediately. The particles are emitted + as if the Emitter was positioned at x,y but all other properties are the same. +*/ + +/*! \qmlmethod QtQuick.Particles2::Emitter::pulse(int duration) + + If the emitter is not enabled, enables it for duration milliseconds and then switches + it back off. +*/ + +QQuickParticleEmitter::QQuickParticleEmitter(QQuickItem *parent) : + QQuickItem(parent) + , m_particlesPerSecond(10) + , m_particleDuration(1000) + , m_particleDurationVariation(0) + , m_enabled(true) + , m_system(0) + , m_extruder(0) + , m_defaultExtruder(0) + , m_speed(&m_nullVector) + , m_acceleration(&m_nullVector) + , m_particleSize(16) + , m_particleEndSize(-1) + , m_particleSizeVariation(0) + , m_startTime(0) + , m_overwrite(true) + , m_pulseLeft(0) + , m_maxParticleCount(-1) + , m_speed_from_movement(0) + , m_reset_last(true) + , m_last_timestamp(-1) + , m_last_emission(0) + +{ + //TODO: Reset speed/acc back to null vector? Or allow null pointer? + connect(this, SIGNAL(maximumEmittedChanged(int)), + this, SIGNAL(particleCountChanged())); + connect(this, SIGNAL(particlesPerSecondChanged(qreal)), + this, SIGNAL(particleCountChanged())); + connect(this, SIGNAL(particleDurationChanged(int)), + this, SIGNAL(particleCountChanged())); +} + +QQuickParticleEmitter::~QQuickParticleEmitter() +{ + if (m_defaultExtruder) + delete m_defaultExtruder; +} + +bool QQuickParticleEmitter::isEmitConnected() +{ + static int idx = QObjectPrivate::get(this)->signalIndex("emitParticles(QQmlV8Handle)"); + return QObjectPrivate::get(this)->isSignalConnected(idx); +} + +void QQuickParticleEmitter::componentComplete() +{ + if (!m_system && qobject_cast(parentItem())) + setSystem(qobject_cast(parentItem())); + QQuickItem::componentComplete(); +} + +void QQuickParticleEmitter::setEnabled(bool arg) +{ + if (m_enabled != arg) { + m_enabled = arg; + emit enabledChanged(arg); + } +} + + +QQuickParticleExtruder* QQuickParticleEmitter::effectiveExtruder() +{ + if (m_extruder) + return m_extruder; + if (!m_defaultExtruder) + m_defaultExtruder = new QQuickParticleExtruder; + return m_defaultExtruder; +} + +void QQuickParticleEmitter::pulse(int milliseconds) +{ + if (!m_enabled) + m_pulseLeft = milliseconds; +} + +void QQuickParticleEmitter::burst(int num) +{ + m_burstQueue << qMakePair(num, QPointF(x(), y())); +} + +void QQuickParticleEmitter::burst(int num, qreal x, qreal y) +{ + m_burstQueue << qMakePair(num, QPointF(x, y)); +} + +void QQuickParticleEmitter::setMaxParticleCount(int arg) +{ + if (m_maxParticleCount != arg) { + if (arg < 0 && m_maxParticleCount >= 0){ + connect(this, SIGNAL(particlesPerSecondChanged(qreal)), + this, SIGNAL(particleCountChanged())); + connect(this, SIGNAL(particleDurationChanged(int)), + this, SIGNAL(particleCountChanged())); + }else if (arg >= 0 && m_maxParticleCount < 0){ + disconnect(this, SIGNAL(particlesPerSecondChanged(qreal)), + this, SIGNAL(particleCountChanged())); + disconnect(this, SIGNAL(particleDurationChanged(int)), + this, SIGNAL(particleCountChanged())); + } + m_overwrite = arg < 0; + m_maxParticleCount = arg; + emit maximumEmittedChanged(arg); + } +} + +int QQuickParticleEmitter::particleCount() const +{ + if (m_maxParticleCount >= 0) + return m_maxParticleCount; + return m_particlesPerSecond*((m_particleDuration+m_particleDurationVariation)/1000.0); +} + +void QQuickParticleEmitter::setSpeedFromMovement(qreal t) +{ + if (t == m_speed_from_movement) + return; + m_speed_from_movement = t; + emit speedFromMovementChanged(); +} + +void QQuickParticleEmitter::reset() +{ + m_reset_last = true; +} + +void QQuickParticleEmitter::emitWindow(int timeStamp) +{ + if (m_system == 0) + return; + if ((!m_enabled || !m_particlesPerSecond)&& !m_pulseLeft && m_burstQueue.isEmpty()){ + m_reset_last = true; + return; + } + + if (m_reset_last) { + m_last_emitter = m_last_last_emitter = QPointF(x(), y()); + if (m_last_timestamp == -1) + m_last_timestamp = (timeStamp - m_startTime)/1000.; + else + m_last_timestamp = timeStamp/1000.; + m_last_emission = m_last_timestamp; + m_reset_last = false; + m_emitCap = particleCount(); + } + + if (m_pulseLeft){ + m_pulseLeft -= timeStamp - m_last_timestamp * 1000.; + if (m_pulseLeft < 0){ + if (!m_enabled) + timeStamp += m_pulseLeft; + m_pulseLeft = 0; + } + } + qreal time = timeStamp / 1000.; + qreal particleRatio = 1. / m_particlesPerSecond; + qreal pt = m_last_emission; + qreal maxLife = (m_particleDuration + m_particleDurationVariation)/1000.0; + if (pt + maxLife < time)//We missed so much, that we should skip emiting particles that are dead by now + pt = time - maxLife; + + qreal opt = pt; // original particle time + qreal dt = time - m_last_timestamp; // timestamp delta... + if (!dt) + dt = 0.000001; + + // emitter difference since last... + qreal dex = (x() - m_last_emitter.x()); + qreal dey = (y() - m_last_emitter.y()); + + qreal ax = (m_last_last_emitter.x() + m_last_emitter.x()) / 2; + qreal bx = m_last_emitter.x(); + qreal cx = (x() + m_last_emitter.x()) / 2; + qreal ay = (m_last_last_emitter.y() + m_last_emitter.y()) / 2; + qreal by = m_last_emitter.y(); + qreal cy = (y() + m_last_emitter.y()) / 2; + + qreal sizeAtEnd = m_particleEndSize >= 0 ? m_particleEndSize : m_particleSize; + qreal emitter_x_offset = m_last_emitter.x() - x(); + qreal emitter_y_offset = m_last_emitter.y() - y(); + if (!m_burstQueue.isEmpty() && !m_pulseLeft && !m_enabled)//'outside time' emissions only + pt = time; + + QList toEmit; + + while ((pt < time && m_emitCap) || !m_burstQueue.isEmpty()) { + //int pos = m_last_particle % m_particle_count; + QQuickParticleData* datum = m_system->newDatum(m_system->groupIds[m_group], !m_overwrite); + if (datum){//actually emit(otherwise we've been asked to skip this one) + datum->e = this;//###useful? + qreal t = 1 - (pt - opt) / dt; + qreal vx = + - 2 * ax * (1 - t) + + 2 * bx * (1 - 2 * t) + + 2 * cx * t; + qreal vy = + - 2 * ay * (1 - t) + + 2 * by * (1 - 2 * t) + + 2 * cy * t; + + + // Particle timestamp + datum->t = pt; + datum->lifeSpan = + (m_particleDuration + + ((rand() % ((m_particleDurationVariation*2) + 1)) - m_particleDurationVariation)) + / 1000.0; + + if (datum->lifeSpan >= m_system->maxLife){ + datum->lifeSpan = m_system->maxLife; + m_emitCap--;//emitCap keeps us from reemitting 'infinite' particles after their life. Unless you reset the emitter. + } + + // Particle position + QRectF boundsRect; + if (!m_burstQueue.isEmpty()){ + boundsRect = QRectF(m_burstQueue.first().second.x() - x(), m_burstQueue.first().second.y() - y(), + width(), height()); + } else { + boundsRect = QRectF(emitter_x_offset + dex * (pt - opt) / dt, emitter_y_offset + dey * (pt - opt) / dt + , width(), height()); + } + QPointF newPos = effectiveExtruder()->extrude(boundsRect); + datum->x = newPos.x(); + datum->y = newPos.y(); + + // Particle speed + const QPointF &speed = m_speed->sample(newPos); + datum->vx = speed.x() + + m_speed_from_movement * vx; + datum->vy = speed.y() + + m_speed_from_movement * vy; + + // Particle acceleration + const QPointF &accel = m_acceleration->sample(newPos); + datum->ax = accel.x(); + datum->ay = accel.y(); + + // Particle size + float sizeVariation = -m_particleSizeVariation + + rand() / float(RAND_MAX) * m_particleSizeVariation * 2; + + float size = qMax((qreal)0.0 , m_particleSize + sizeVariation); + float endSize = qMax((qreal)0.0 , sizeAtEnd + sizeVariation); + + datum->size = size;// * float(m_emitting); + datum->endSize = endSize;// * float(m_emitting); + + toEmit << datum; + } + if (m_burstQueue.isEmpty()){ + pt += particleRatio; + }else{ + m_burstQueue.first().first--; + if (m_burstQueue.first().first <= 0) + m_burstQueue.pop_front(); + } + } + + if (isEmitConnected()) { + v8::HandleScope handle_scope; + v8::Context::Scope scope(QQmlEnginePrivate::getV8Engine(qmlEngine(this))->context()); + v8::Handle array = v8::Array::New(toEmit.size()); + for (int i=0; iSet(i, toEmit[i]->v8Value().toHandle()); + + emitParticles(QQmlV8Handle::fromHandle(array));//A chance for arbitrary JS changes + } + foreach (QQuickParticleData* d, toEmit) + m_system->emitParticle(d); + + m_last_emission = pt; + + m_last_last_last_emitter = m_last_last_emitter; + m_last_last_emitter = m_last_emitter; + m_last_emitter = QPointF(x(), y()); + m_last_timestamp = time; +} + + +QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquickparticleemitter_p.h qt5-declarative-0.1~git20120423/src/particles/qquickparticleemitter_p.h --- qt5-declarative-0.1~git20120402/src/particles/qquickparticleemitter_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquickparticleemitter_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,350 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PARTICLEEMITTER_H +#define PARTICLEEMITTER_H + +#include +#include +#include "qquickparticlesystem_p.h" +#include "qquickparticleextruder_p.h" +#include "qquickdirection_p.h" + +#include +#include +#include +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QQuickParticleEmitter : public QQuickItem +{ + Q_OBJECT + Q_PROPERTY(QQuickParticleSystem* system READ system WRITE setSystem NOTIFY systemChanged) + Q_PROPERTY(QString group READ group WRITE setGroup NOTIFY groupChanged) + Q_PROPERTY(QQuickParticleExtruder* shape READ extruder WRITE setExtruder NOTIFY extruderChanged) + Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged) + Q_PROPERTY(int startTime READ startTime WRITE setStartTime NOTIFY startTimeChanged) + + Q_PROPERTY(qreal emitRate READ particlesPerSecond WRITE setParticlesPerSecond NOTIFY particlesPerSecondChanged) + Q_PROPERTY(int lifeSpan READ particleDuration WRITE setParticleDuration NOTIFY particleDurationChanged) + Q_PROPERTY(int lifeSpanVariation READ particleDurationVariation WRITE setParticleDurationVariation NOTIFY particleDurationVariationChanged) + Q_PROPERTY(int maximumEmitted READ maxParticleCount WRITE setMaxParticleCount NOTIFY maximumEmittedChanged) + + Q_PROPERTY(qreal size READ particleSize WRITE setParticleSize NOTIFY particleSizeChanged) + Q_PROPERTY(qreal endSize READ particleEndSize WRITE setParticleEndSize NOTIFY particleEndSizeChanged) + Q_PROPERTY(qreal sizeVariation READ particleSizeVariation WRITE setParticleSizeVariation NOTIFY particleSizeVariationChanged) + + Q_PROPERTY(QQuickDirection *speed READ speed WRITE setSpeed NOTIFY speedChanged) + Q_PROPERTY(QQuickDirection *acceleration READ acceleration WRITE setAcceleration NOTIFY accelerationChanged) + Q_PROPERTY(qreal speedFromMovement READ speedFromMovement WRITE setSpeedFromMovement NOTIFY speedFromMovementChanged) + + Q_ENUMS(Lifetime) +public: + explicit QQuickParticleEmitter(QQuickItem *parent = 0); + virtual ~QQuickParticleEmitter(); + virtual void emitWindow(int timeStamp); + + enum Lifetime { + InfiniteLife = QQuickParticleSystem::maxLife + }; + + bool enabled() const + { + return m_enabled; + } + + qreal particlesPerSecond() const + { + return m_particlesPerSecond; + } + + int particleDuration() const + { + return m_particleDuration; + } + + QQuickParticleSystem* system() const + { + return m_system; + } + + QString group() const + { + return m_group; + } + + int particleDurationVariation() const + { + return m_particleDurationVariation; + } + + qreal speedFromMovement() const { return m_speed_from_movement; } + void setSpeedFromMovement(qreal s); + virtual void componentComplete(); +signals: + void emitParticles(QQmlV8Handle particles); + void particlesPerSecondChanged(qreal); + void particleDurationChanged(int); + void enabledChanged(bool); + + void systemChanged(QQuickParticleSystem* arg); + + void groupChanged(QString arg); + + void particleDurationVariationChanged(int arg); + + void extruderChanged(QQuickParticleExtruder* arg); + + void particleSizeChanged(qreal arg); + + void particleEndSizeChanged(qreal arg); + + void particleSizeVariationChanged(qreal arg); + + void speedChanged(QQuickDirection * arg); + + void accelerationChanged(QQuickDirection * arg); + + void maximumEmittedChanged(int arg); + void particleCountChanged(); + + void speedFromMovementChanged(); + + void startTimeChanged(int arg); + +public slots: + void pulse(int milliseconds); + void burst(int num); + void burst(int num, qreal x, qreal y); + + void setEnabled(bool arg); + + void setParticlesPerSecond(qreal arg) + { + if (m_particlesPerSecond != arg) { + m_particlesPerSecond = arg; + emit particlesPerSecondChanged(arg); + } + } + + void setParticleDuration(int arg) + { + if (m_particleDuration != arg) { + m_particleDuration = arg; + emit particleDurationChanged(arg); + } + } + + void setSystem(QQuickParticleSystem* arg) + { + if (m_system != arg) { + m_system = arg; + if (m_system) + m_system->registerParticleEmitter(this); + emit systemChanged(arg); + } + } + + void setGroup(QString arg) + { + if (m_group != arg) { + m_group = arg; + emit groupChanged(arg); + } + } + + void setParticleDurationVariation(int arg) + { + if (m_particleDurationVariation != arg) { + m_particleDurationVariation = arg; + emit particleDurationVariationChanged(arg); + } + } + void setExtruder(QQuickParticleExtruder* arg) + { + if (m_extruder != arg) { + m_extruder = arg; + emit extruderChanged(arg); + } + } + + void setParticleSize(qreal arg) + { + if (m_particleSize != arg) { + m_particleSize = arg; + emit particleSizeChanged(arg); + } + } + + void setParticleEndSize(qreal arg) + { + if (m_particleEndSize != arg) { + m_particleEndSize = arg; + emit particleEndSizeChanged(arg); + } + } + + void setParticleSizeVariation(qreal arg) + { + if (m_particleSizeVariation != arg) { + m_particleSizeVariation = arg; + emit particleSizeVariationChanged(arg); + } + } + + void setSpeed(QQuickDirection * arg) + { + if (m_speed != arg) { + m_speed = arg; + emit speedChanged(arg); + } + } + + void setAcceleration(QQuickDirection * arg) + { + if (m_acceleration != arg) { + m_acceleration = arg; + emit accelerationChanged(arg); + } + } + + void setMaxParticleCount(int arg); + + void setStartTime(int arg) + { + if (m_startTime != arg) { + m_startTime = arg; + emit startTimeChanged(arg); + } + } + + virtual void reset(); +public: + int particleCount() const; + + QQuickParticleExtruder* extruder() const + { + return m_extruder; + } + + qreal particleSize() const + { + return m_particleSize; + } + + qreal particleEndSize() const + { + return m_particleEndSize; + } + + qreal particleSizeVariation() const + { + return m_particleSizeVariation; + } + + QQuickDirection * speed() const + { + return m_speed; + } + + QQuickDirection * acceleration() const + { + return m_acceleration; + } + + int maxParticleCount() const + { + return m_maxParticleCount; + } + + int startTime() const + { + return m_startTime; + } + +protected: + qreal m_particlesPerSecond; + int m_particleDuration; + int m_particleDurationVariation; + bool m_enabled; + QQuickParticleSystem* m_system; + QString m_group; + QQuickParticleExtruder* m_extruder; + QQuickParticleExtruder* m_defaultExtruder; + QQuickParticleExtruder* effectiveExtruder(); + QQuickDirection * m_speed; + QQuickDirection * m_acceleration; + qreal m_particleSize; + qreal m_particleEndSize; + qreal m_particleSizeVariation; + + qreal m_speedFromMovement; + int m_startTime; + bool m_overwrite; + + int m_pulseLeft; + QList > m_burstQueue; + int m_maxParticleCount; + + //Used in default implementation, but might be useful + qreal m_speed_from_movement; + + int m_emitCap; + bool m_reset_last; + qreal m_last_timestamp; + qreal m_last_emission; + + QPointF m_last_emitter; + QPointF m_last_last_emitter; + QPointF m_last_last_last_emitter; + + bool isEmitConnected(); +private: + QQuickDirection m_nullVector; + +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // PARTICLEEMITTER_H diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquickparticleextruder.cpp qt5-declarative-0.1~git20120423/src/particles/qquickparticleextruder.cpp --- qt5-declarative-0.1~git20120402/src/particles/qquickparticleextruder.cpp 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquickparticleextruder.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickparticleextruder_p.h" +#include + +QT_BEGIN_NAMESPACE + +/*! + \qmlclass Shape QQuickParticleExtruder + \inqmlmodule QtQuick.Particles 2 + \brief The Shape element allows you to specify an area for affectors and emitter. + + The base class is just a rectangle. +*/ + +QQuickParticleExtruder::QQuickParticleExtruder(QObject *parent) : + QObject(parent) +{ +} + +QPointF QQuickParticleExtruder::extrude(const QRectF &rect) +{ + return QPointF(((qreal)rand() / RAND_MAX) * rect.width() + rect.x(), + ((qreal)rand() / RAND_MAX) * rect.height() + rect.y()); +} + +bool QQuickParticleExtruder::contains(const QRectF &bounds, const QPointF &point) +{ + return bounds.contains(point); +} + +QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquickparticleextruder_p.h qt5-declarative-0.1~git20120423/src/particles/qquickparticleextruder_p.h --- qt5-declarative-0.1~git20120402/src/particles/qquickparticleextruder_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquickparticleextruder_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PARTICLEEXTRUDER_H +#define PARTICLEEXTRUDER_H + +#include +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QQuickParticleExtruder : public QObject +{ + Q_OBJECT + +public: + explicit QQuickParticleExtruder(QObject *parent = 0); + virtual QPointF extrude(const QRectF &); + virtual bool contains(const QRectF &bounds, const QPointF &point); + +signals: +public slots: +protected: +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // PARTICLEEXTRUDER_H diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquickparticlegroup.cpp qt5-declarative-0.1~git20120423/src/particles/qquickparticlegroup.cpp --- qt5-declarative-0.1~git20120402/src/particles/qquickparticlegroup.cpp 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquickparticlegroup.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,143 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickparticlegroup_p.h" + +/*! + \qmlclass ParticleGroup QQuickParticleGroup + \inqmlmodule QtQuick.Particles 2 + \brief ParticleGroup elements allow you to set attributes on a logical particle group. + + This element allows you to set timed transitions on particle groups. + + You can also use this element to group particle system elements related to the logical + particle group. Emitters, Affectors and Painters set as direct children of a ParticleGroup + will automatically apply to that logical particle group. TrailEmitters will automatically follow + the group. + + If a ParticleGroup element is not defined for a group, the group will function normally as if + none of the transition properties were set. +*/ +/*! + \qmlproperty ParticleSystem QtQuick.Particles2::ParticleGroup::system + This is the system which will contain the group. + + If the ParticleGroup is a direct child of a ParticleSystem, it will automatically be associated with it. +*/ +/*! + \qmlproperty string QtQuick.Particles2::ParticleGroup::name + This is the name of the particle group, and how it is generally referred to by other elements. + + If elements refer to a name which does not have an explicit ParticleGroup created, it will + work normally (with no transitions specified for the group). If you do not need to assign + duration based transitions to a group, you do not need to create a ParticleGroup with that name (although you may). +*/ +/*! + \qmlproperty int QtQuick.Particles2::ParticleGroup::duration + The time in milliseconds before the group will attempt to transition. + +*/ +/*! + \qmlproperty ParticleSystem QtQuick.Particles2::ParticleGroup::durationVariation + The maximum number of milliseconds that the duration of the transition cycle varies per particle in the group. + + Default value is zero. +*/ +/*! + \qmlproperty ParticleSystem QtQuick.Particles2::ParticleGroup::to + The weighted list of transitions valid for this group. + + If the chosen transition stays in this group, another duration (+/- up to durationVariation) + milliseconds will occur before another transition is attempted. +*/ + +QQuickParticleGroup::QQuickParticleGroup(QObject* parent) + : QQuickStochasticState(parent) + , m_system(0) +{ + +} + +void delayedRedirect(QQmlListProperty *prop, QObject *value) +{ + QQuickParticleGroup* pg = qobject_cast(prop->object); + if (pg) + pg->delayRedirect(value); +} + +QQmlListProperty QQuickParticleGroup::particleChildren() +{ + QQuickParticleSystem* system = qobject_cast(parent()); + if (system) + return QQmlListProperty(this, 0, &QQuickParticleSystem::statePropertyRedirect); + else + return QQmlListProperty(this, 0, &delayedRedirect); +} + +void QQuickParticleGroup::setSystem(QQuickParticleSystem* arg) +{ + if (m_system != arg) { + m_system = arg; + m_system->registerParticleGroup(this); + performDelayedRedirects(); + emit systemChanged(arg); + } +} + +void QQuickParticleGroup::delayRedirect(QObject *obj) +{ + m_delayedRedirects << obj; +} + +void QQuickParticleGroup::performDelayedRedirects() +{ + if (!m_system) + return; + foreach (QObject* obj, m_delayedRedirects) + m_system->stateRedirect(this, m_system, obj); + + m_delayedRedirects.clear(); +} + +void QQuickParticleGroup::componentComplete(){ + if (!m_system && qobject_cast(parent())) + setSystem(qobject_cast(parent())); +} diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquickparticlegroup_p.h qt5-declarative-0.1~git20120423/src/particles/qquickparticlegroup_p.h --- qt5-declarative-0.1~git20120402/src/particles/qquickparticlegroup_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquickparticlegroup_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,112 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QQuickPARTICLEGROUP +#define QQuickPARTICLEGROUP +#include +#include "qquickparticlesystem_p.h" +#include "qqmlparserstatus.h" + +QT_BEGIN_NAMESPACE + +class QQuickParticleGroup : public QQuickStochasticState, public QQmlParserStatus +{ + Q_OBJECT + //### Would setting limits per group be useful? Or clutter the API? + //Q_PROPERTY(int maximumAlive READ maximumAlive WRITE setMaximumAlive NOTIFY maximumAliveChanged) + + Q_PROPERTY(QQuickParticleSystem* system READ system WRITE setSystem NOTIFY systemChanged) + + //Intercept children requests and assign to the group & system + Q_PROPERTY(QQmlListProperty particleChildren READ particleChildren DESIGNABLE false)//### Hidden property for in-state system definitions - ought not to be used in actual "Sprite" states + Q_CLASSINFO("DefaultProperty", "particleChildren") + Q_INTERFACES(QQmlParserStatus) + +public: + explicit QQuickParticleGroup(QObject* parent = 0); + + QQmlListProperty particleChildren(); + + int maximumAlive() const + { + return m_maximumAlive; + } + + QQuickParticleSystem* system() const + { + return m_system; + } + +public slots: + + void setMaximumAlive(int arg) + { + if (m_maximumAlive != arg) { + m_maximumAlive = arg; + emit maximumAliveChanged(arg); + } + } + + void setSystem(QQuickParticleSystem* arg); + + void delayRedirect(QObject* obj); + +signals: + + void maximumAliveChanged(int arg); + + void systemChanged(QQuickParticleSystem* arg); + +protected: + virtual void componentComplete(); + virtual void classBegin(){;} + +private: + + void performDelayedRedirects(); + + int m_maximumAlive; + QQuickParticleSystem* m_system; + QList m_delayedRedirects; +}; + +QT_END_NAMESPACE + +#endif diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquickparticlepainter.cpp qt5-declarative-0.1~git20120423/src/particles/qquickparticlepainter.cpp --- qt5-declarative-0.1~git20120402/src/particles/qquickparticlepainter.cpp 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquickparticlepainter.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,165 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickparticlepainter_p.h" +#include +#include +QT_BEGIN_NAMESPACE +/*! + \qmlclass ParticlePainter QQuickParticlePainter + \inqmlmodule QtQuick.Particles 2 + \inherits ParticlePainter + \brief ParticlePainter elements allow you to specify how to paint particles. + + The default implementation paints nothing. See the subclasses if you want to + paint something visible. + +*/ +/*! + \qmlproperty ParticleSystem QtQuick.Particles2::ParticlePainter::system + This is the system whose particles can be painted by the element. + If the ParticlePainter is a direct child of a ParticleSystem, it will automatically be associated with it. +*/ +/*! + \qmlproperty list QtQuick.Particles2::ParticlePainter::groups + Which logical particle groups will be painted. + + If empty, it will paint the default particle group (""). +*/ +QQuickParticlePainter::QQuickParticlePainter(QQuickItem *parent) : + QQuickItem(parent), + m_system(0), m_count(0), m_pleaseReset(true), m_canvas(0) +{ +} + +void QQuickParticlePainter::itemChange(ItemChange change, const ItemChangeData &data) +{ + if (change == QQuickItem::ItemSceneChange) { + if (m_canvas) + disconnect(m_canvas, SIGNAL(sceneGraphInvalidated()), this, SLOT(sceneGraphInvalidated())); + m_canvas = data.canvas; + if (m_canvas) + connect(m_canvas, SIGNAL(sceneGraphInvalidated()), this, SLOT(sceneGraphInvalidated()), Qt::DirectConnection); + + } +} + +void QQuickParticlePainter::componentComplete() +{ + if (!m_system && qobject_cast(parentItem())) + setSystem(qobject_cast(parentItem())); + QQuickItem::componentComplete(); +} + + +void QQuickParticlePainter::setSystem(QQuickParticleSystem *arg) +{ + if (m_system != arg) { + m_system = arg; + if (m_system){ + m_system->registerParticlePainter(this); + reset(); + } + emit systemChanged(arg); + } +} + +void QQuickParticlePainter::load(QQuickParticleData* d) +{ + initialize(d->group, d->index); + if (m_pleaseReset) + return; + m_pendingCommits << qMakePair(d->group, d->index); +} + +void QQuickParticlePainter::reload(QQuickParticleData* d) +{ + if (m_pleaseReset) + return; + m_pendingCommits << qMakePair(d->group, d->index); +} + +void QQuickParticlePainter::reset() +{ + m_pendingCommits.clear(); + m_pleaseReset = true; +} + +void QQuickParticlePainter::setCount(int c)//### TODO: some resizeing so that particles can reallocate on size change instead of recreate +{ + Q_ASSERT(c >= 0); //XXX + if (c == m_count) + return; + m_count = c; + emit countChanged(); + reset(); +} + +int QQuickParticlePainter::count() +{ + return m_count; +} + +void QQuickParticlePainter::calcSystemOffset(bool resetPending) +{ + if (!m_system || !parentItem()) + return; + QPointF lastOffset = m_systemOffset; + m_systemOffset = -1 * this->mapFromItem(m_system, QPointF(0.0, 0.0)); + if (lastOffset != m_systemOffset && !resetPending){ + //Reload all particles//TODO: Necessary? + foreach (const QString &g, m_groups){ + int gId = m_system->groupIds[g]; + foreach (QQuickParticleData* d, m_system->groupData[gId]->data) + reload(d); + } + } +} +typedef QPair intPair; +void QQuickParticlePainter::performPendingCommits() +{ + calcSystemOffset(); + foreach (intPair p, m_pendingCommits) + commit(p.first, p.second); + m_pendingCommits.clear(); +} + +QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquickparticlepainter_p.h qt5-declarative-0.1~git20120423/src/particles/qquickparticlepainter_p.h --- qt5-declarative-0.1~git20120402/src/particles/qquickparticlepainter_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquickparticlepainter_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,137 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PARTICLE_H +#define PARTICLE_H + +#include +#include +#include +#include "qquickparticlesystem_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QQuickParticlePainter : public QQuickItem +{ + Q_OBJECT + Q_PROPERTY(QQuickParticleSystem* system READ system WRITE setSystem NOTIFY systemChanged) + Q_PROPERTY(QStringList groups READ groups WRITE setGroups NOTIFY groupsChanged) + +public: + explicit QQuickParticlePainter(QQuickItem *parent = 0); + //Data Interface to system + void load(QQuickParticleData*); + void reload(QQuickParticleData*); + void setCount(int c); + int count(); + void performPendingCommits();//Called from updatePaintNode + QQuickParticleSystem* system() const + { + return m_system; + } + + + QStringList groups() const + { + return m_groups; + } + + void itemChange(ItemChange, const ItemChangeData &); + +signals: + void countChanged(); + void systemChanged(QQuickParticleSystem* arg); + + void groupsChanged(QStringList arg); + +public slots: + void setSystem(QQuickParticleSystem* arg); + + void setGroups(QStringList arg) + { + if (m_groups != arg) { + m_groups = arg; + //Note: The system watches this as it has to recalc things when groups change. It will request a reset if necessary + emit groupsChanged(arg); + } + } + + void calcSystemOffset(bool resetPending = false); + +private slots: + virtual void sceneGraphInvalidated() {} + +protected: + /* Reset resets all your internal data structures. But anything attached to a particle should + be in attached data. So reset + reloads should have no visible effect. + ###Hunt down all cases where we do a complete reset for convenience and be more targeted + */ + virtual void reset(); + + virtual void componentComplete(); + virtual void initialize(int gIdx, int pIdx){//Called from main thread + Q_UNUSED(gIdx); + Q_UNUSED(pIdx); + } + virtual void commit(int gIdx, int pIdx){//Called in Render Thread + //###If you need to do something on size changed, check m_data size in this? Or we reset you every time? + Q_UNUSED(gIdx); + Q_UNUSED(pIdx); + } + + QQuickParticleSystem* m_system; + friend class QQuickParticleSystem; + int m_count; + bool m_pleaseReset;//Used by subclasses, but it's a nice optimization to know when stuff isn't going to matter. + QStringList m_groups; + QPointF m_systemOffset; + + QQuickCanvas *m_canvas; + +private: + QSet > m_pendingCommits; +}; + +QT_END_NAMESPACE +QT_END_HEADER +#endif // PARTICLE_H diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquickparticlesmodule.cpp qt5-declarative-0.1~git20120423/src/particles/qquickparticlesmodule.cpp --- qt5-declarative-0.1~git20120402/src/particles/qquickparticlesmodule.cpp 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquickparticlesmodule.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,120 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickangledirection_p.h" +#include "qquickcustomparticle_p.h" +#include "qquickellipseextruder_p.h" +#include "qquicktrailemitter_p.h" +#include "qquickfriction_p.h" +#include "qquickgravity_p.h" +#include "qquickimageparticle_p.h" +#include "qquickitemparticle_p.h" +#include "qquickage_p.h" +#include "qquicklineextruder_p.h" +#include "qquickmaskextruder_p.h" +#include "qquickparticleaffector_p.h" +#include "qquickparticleemitter_p.h" +#include "qquickparticleextruder_p.h" +#include "qquickparticlepainter_p.h" +#include "qquickparticlesmodule_p.h" +#include "qquickparticlesystem_p.h" +#include "qquickpointattractor_p.h" +#include "qquickpointdirection_p.h" +#include "qquickspritegoal_p.h" +#include "qquickdirection_p.h" +#include "qquicktargetdirection_p.h" +#include "qquickturbulence_p.h" +#include "qquickwander_p.h" +#include "qquickcumulativedirection_p.h" +#include "qquickcustomaffector_p.h" +#include "qquickrectangleextruder_p.h" +#include "qquickparticlegroup_p.h" +#include "qquickgroupgoal_p.h" + +QT_BEGIN_NAMESPACE + +void QQuickParticlesModule::defineModule() +{ + const char* uri = "QtQuick.Particles"; + + qmlRegisterType(uri, 2, 0, "ParticleSystem"); + qmlRegisterType(uri, 2, 0, "ParticleGroup"); + + qmlRegisterType(uri, 2, 0, "ImageParticle"); + qmlRegisterType(uri, 2, 0, "CustomParticle"); + qmlRegisterType(uri, 2, 0, "ItemParticle"); + + qmlRegisterType(uri, 2, 0, "Emitter"); + qmlRegisterType(uri, 2, 0, "TrailEmitter"); + + qmlRegisterType(uri, 2, 0, "EllipseShape"); + qmlRegisterType(uri, 2, 0, "RectangleShape"); + qmlRegisterType(uri, 2, 0, "LineShape"); + qmlRegisterType(uri, 2, 0, "MaskShape"); + + qmlRegisterType(uri, 2, 0, "PointDirection"); + qmlRegisterType(uri, 2, 0, "AngleDirection"); + qmlRegisterType(uri, 2, 0, "TargetDirection"); + qmlRegisterType(uri, 2, 0, "CumulativeDirection"); + + qmlRegisterType(uri, 2, 0, "Affector"); + qmlRegisterType(uri, 2, 0, "Wander"); + qmlRegisterType(uri, 2, 0, "Friction"); + qmlRegisterType(uri, 2, 0, "Attractor"); + qmlRegisterType(uri, 2, 0, "Gravity"); + qmlRegisterType(uri, 2, 0, "Age"); + qmlRegisterType(uri, 2, 0, "SpriteGoal"); + qmlRegisterType(uri, 2, 0, "GroupGoal"); + qmlRegisterType(uri, 2, 0 , "Turbulence"); + + //Exposed just for completeness + qmlRegisterUncreatableType(uri, 2, 0, "ParticleAffector", + QStringLiteral("Abstract type. Use one of the inheriting types instead.")); + qmlRegisterUncreatableType(uri, 2, 0, "ParticlePainter", + QStringLiteral("Abstract type. Use one of the inheriting types instead.")); + qmlRegisterUncreatableType(uri, 2, 0, "ParticleExtruder", + QStringLiteral("Abstract type. Use one of the inheriting types instead.")); + qmlRegisterUncreatableType(uri, 2, 0, "NullVector", + QStringLiteral("Abstract type. Use one of the inheriting types instead.")); +} + +QT_END_NAMESPACE + diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquickparticlesmodule_p.h qt5-declarative-0.1~git20120423/src/particles/qquickparticlesmodule_p.h --- qt5-declarative-0.1~git20120402/src/particles/qquickparticlesmodule_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquickparticlesmodule_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKPARTICLESMODULE_H +#define QQUICKPARTICLESMODULE_H + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class Q_QUICKPARTICLES_PRIVATE_EXPORT QQuickParticlesModule +{ +public: + static void defineModule(); +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QQUICKPARTICLESMODULE_H diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquickparticlesystem.cpp qt5-declarative-0.1~git20120423/src/particles/qquickparticlesystem.cpp --- qt5-declarative-0.1~git20120402/src/particles/qquickparticlesystem.cpp 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquickparticlesystem.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,1164 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickparticlesystem_p.h" +#include +#include "qquickparticleemitter_p.h" +#include "qquickparticleaffector_p.h" +#include "qquickparticlepainter_p.h" +#include +#include +#include "qquickv8particledata_p.h" +#include "qquickparticlegroup_p.h" + +#include "qquicktrailemitter_p.h"//###For auto-follow on states, perhaps should be in emitter? +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE +//###Switch to define later, for now user-friendly (no compilation) debugging is worth it +DEFINE_BOOL_CONFIG_OPTION(qmlParticlesDebug, QML_PARTICLES_DEBUG) + + +/* \internal ParticleSystem internals documentation + + Affectors, Painters, Emitters and Groups all register themselves on construction as a callback + from their setSystem (or componentComplete if they have a system from a parent). + + Particle data is stored by group, They have a group index (used by the particle system almost + everywhere) and a global index (used by the Stochastic state engine powering stochastic group + transitions). Each group has a recycling list/heap that stores the particle data. + + The recycling list/heap is a heap of particle data sorted by when they're expected to die. If + they die prematurely then they are marked as reusable (and will probably still be alive when + they exit the heap). If they have their life extended, then they aren't dead when expected. + If this happens, they go back in the heap with the new estimate. If they have died on schedule, + then the indexes are marked as reusable. If no indexes are reusable when new particles are + requested, then the list is extended. This relatively complex datastructure is because memory + allocation and deallocation on this scale proved to be a significant performance cost. In order + to reuse the indexes validly (even when particles can have their life extended or cut short + dynamically, or particle counts grow) this seemed to be the most efficient option for keeping + track of which indices could be reused. + + When a new particle is emitted, the emitter gets a new datum from the group (through the + system), and sets properties on it. Then it's passed back to the group briefly so that it can + now guess when the particle will die. Then the painters get a change to initialize properties + as well, since particle data includes shared data from painters as well as logical particle + data. + + Every animation advance, the simulation advances by running all emitters for the elapsed + duration, then running all affectors, then telling all particle painters to update changed + particles. The ParticlePainter superclass stores these changes, and they are implemented + when the painter is called to paint in the render thread. + + Particle group changes move the particle from one group to another by killing the old particle + and then creating a new one with the same data in the new group. + + Note that currently groups only grow. Given that data is stored in vectors, it is non-trivial + to pluck out the unused indexes when the count goes down. Given the dynamic nature of the + system, it is difficult to tell if those unused data instances will be used again. Still, + some form of garbage collection is on the long term plan. +*/ + +/*! + \qmlclass ParticleSystem QQuickParticleSystem + \inqmlmodule QtQuick.Particles 2 + \brief The ParticleSystem brings together ParticlePainter, Emitter and Affector elements. + +*/ + +/*! + \qmlproperty bool QtQuick.Particles2::ParticleSystem::running + + If running is set to false, the particle system will stop the simulation. All particles + will be destroyed when the system is set to running again. + + It can also be controlled with the start() and stop() methods. +*/ + + +/*! + \qmlproperty bool QtQuick.Particles2::ParticleSystem::paused + + If paused is set to true, the particle system will not advance the simulation. When + paused is set to false again, the simulation will resume from the same point it was + paused. + + The simulation will automatically pause if it detects that there are no live particles + left, and unpause when new live particles are added. + + It can also be controlled with the pause() and resume() methods. +*/ + +/*! + \qmlproperty bool QtQuick.Particles2::ParticleSystem::empty + + empty is set to true when there are no live particles left in the system. + + You can use this to pause the system, keeping it from spending any time updating, + but you will need to resume it in order for additional particles to be generated + by the system. + + To kill all the particles in the system, use a Kill affector. +*/ + +/*! + \qmlproperty list QtQuick.Particles2::ParticleSystem::particleStates + + You can define a sub-set of particle groups in this property in order to provide them + with stochastic state transitions. + + Each QtQuick2::Sprite in this list is interpreted as corresponding to the particle group + with ths same name. Any transitions defined in these sprites will take effect on the particle + groups as well. Additionally TrailEmitters, Affectors and ParticlePainters definined + inside one of these sprites are automatically associated with the corresponding particle group. +*/ + +/*! + \qmlmethod void QtQuick.Particles2::ParticleSystem::pause + + Pauses the simulation if it is running. + + \sa resume, paused +*/ + +/*! + \qmlmethod void QtQuick.Particles2::ParticleSystem::resume + + Resumes the simulation if it is paused. + + \sa pause, paused +*/ + +/*! + \qmlmethod void QtQuick.Particles2::ParticleSystem::start + + Starts the simulation if it has not already running. + + \sa stop, restart, running +*/ + +/*! + \qmlmethod void QtQuick.Particles2::ParticleSystem::stop + + Stops the simulation if it is running. + + \sa start, restart, running +*/ + +/*! + \qmlmethod void QtQuick.Particles2::ParticleSystem::restart + + Stops the simulation if it is running, and then starts it. + + \sa stop, restart, running +*/ +/*! + \qmlmethod void QtQuick.Particles2::ParticleSystem::reset + + Discards all currently existing particles. + +*/ +const qreal EPSILON = 0.001; +//Utility functions for when within 1ms is close enough +bool timeEqualOrGreater(qreal a, qreal b) +{ + return (a+EPSILON >= b); +} + +bool timeLess(qreal a, qreal b) +{ + return (a-EPSILON < b); +} + +bool timeEqual(qreal a, qreal b) +{ + return (a+EPSILON > b) && (a-EPSILON < b); +} + +int roundedTime(qreal a) +{// in ms + return (int)qRound(a*1000.0); +} + +QQuickParticleDataHeap::QQuickParticleDataHeap() + : m_data(0) +{ + m_data.reserve(1000); + clear(); +} + +void QQuickParticleDataHeap::grow() //###Consider automatic growth vs resize() calls from GroupData +{ + m_data.resize(1 << ++m_size); +} + +void QQuickParticleDataHeap::insert(QQuickParticleData* data) +{ + insertTimed(data, roundedTime(data->t + data->lifeSpan)); +} + +void QQuickParticleDataHeap::insertTimed(QQuickParticleData* data, int time) +{ + //TODO: Optimize 0 lifespan (or already dead) case + if (m_lookups.contains(time)) { + m_data[m_lookups[time]].data << data; + return; + } + if (m_end == (1 << m_size)) + grow(); + m_data[m_end].time = time; + m_data[m_end].data.clear(); + m_data[m_end].data.insert(data); + m_lookups.insert(time, m_end); + bubbleUp(m_end++); +} + +int QQuickParticleDataHeap::top() +{ + if (m_end == 0) + return 1 << 30; + return m_data[0].time; +} + +QSet QQuickParticleDataHeap::pop() +{ + if (!m_end) + return QSet (); + QSet ret = m_data[0].data; + m_lookups.remove(m_data[0].time); + if (m_end == 1) { + --m_end; + } else { + m_data[0] = m_data[--m_end]; + bubbleDown(0); + } + return ret; +} + +void QQuickParticleDataHeap::clear() +{ + m_size = 0; + m_end = 0; + //m_size is in powers of two. So to start at 0 we have one allocated + m_data.resize(1); + m_lookups.clear(); +} + +bool QQuickParticleDataHeap::contains(QQuickParticleData* d) +{ + for (int i=0; i= m_end) + return; + int lesser = left; + int right = idx*2 + 2; + if (right < m_end) { + if (m_data[left].time > m_data[right].time) + lesser = right; + } + if (m_data[idx].time > m_data[lesser].time) { + swap(idx, lesser); + bubbleDown(lesser); + } +} + +QQuickParticleGroupData::QQuickParticleGroupData(int id, QQuickParticleSystem* sys):index(id),m_size(0),m_system(sys) +{ + initList(); +} + +QQuickParticleGroupData::~QQuickParticleGroupData() +{ + foreach (QQuickParticleData* d, data) + delete d; +} + +int QQuickParticleGroupData::size() +{ + return m_size; +} + +QString QQuickParticleGroupData::name()//### Worth caching as well? +{ + return m_system->groupIds.key(index); +} + +void QQuickParticleGroupData::setSize(int newSize) +{ + if (newSize == m_size) + return; + Q_ASSERT(newSize > m_size);//XXX allow shrinking + data.resize(newSize); + for (int i=m_size; igroup = index; + data[i]->index = i; + reusableIndexes << i; + } + int delta = newSize - m_size; + m_size = newSize; + foreach (QQuickParticlePainter* p, painters) + p->setCount(p->count() + delta); +} + +void QQuickParticleGroupData::initList() +{ + dataHeap.clear(); +} + +void QQuickParticleGroupData::kill(QQuickParticleData* d) +{ + Q_ASSERT(d->group == index); + d->lifeSpan = 0;//Kill off + foreach (QQuickParticlePainter* p, painters) + p->reload(d); + reusableIndexes << d->index; +} + +QQuickParticleData* QQuickParticleGroupData::newDatum(bool respectsLimits) +{ + //recycle();//Extra recycler round to be sure? + + while (!reusableIndexes.empty()) { + int idx = *(reusableIndexes.begin()); + reusableIndexes.remove(idx); + if (data[idx]->stillAlive()) {// ### This means resurrection of 'dead' particles. Is that allowed? + prepareRecycler(data[idx]); + continue; + } + return data[idx]; + } + if (respectsLimits) + return 0; + + int oldSize = m_size; + setSize(oldSize + 10);//###+1,10%,+10? Choose something non-arbitrarily + reusableIndexes.remove(oldSize); + return data[oldSize]; +} + +bool QQuickParticleGroupData::recycle() +{ + while (dataHeap.top() <= m_system->timeInt) { + foreach (QQuickParticleData* datum, dataHeap.pop()) { + if (!datum->stillAlive()) { + reusableIndexes << datum->index; + } else { + prepareRecycler(datum); //ttl has been altered mid-way, put it back + } + } + } + + //TODO: If the data is clear, gc (consider shrinking stack size)? + return reusableIndexes.count() == m_size; +} + +void QQuickParticleGroupData::prepareRecycler(QQuickParticleData* d) +{ + if (d->lifeSpan*1000 < m_system->maxLife) { + dataHeap.insert(d); + } else { + while ((roundedTime(d->t) + 2*m_system->maxLife/3) <= m_system->timeInt) + d->extendLife(m_system->maxLife/3000.0); + dataHeap.insertTimed(d, roundedTime(d->t) + 2*m_system->maxLife/3); + } +} + +QQuickParticleData::QQuickParticleData(QQuickParticleSystem* sys) + : group(0) + , e(0) + , system(sys) + , index(0) + , systemIndex(-1) + , colorOwner(0) + , rotationOwner(0) + , deformationOwner(0) + , animationOwner(0) + , v8Datum(0) +{ + x = 0; + y = 0; + t = -1; + lifeSpan = 0; + size = 0; + endSize = 0; + vx = 0; + vy = 0; + ax = 0; + ay = 0; + xx = 1; + xy = 0; + yx = 0; + yy = 1; + rotation = 0; + rotationSpeed = 0; + autoRotate = 0; + animIdx = 0; + frameDuration = 1; + frameAt = -1; + frameCount = 1; + animT = -1; + animX = 0; + animY = 0; + animWidth = 1; + animHeight = 1; + color.r = 255; + color.g = 255; + color.b = 255; + color.a = 255; + r = 0; + delegate = 0; + modelIndex = -1; +} + +QQuickParticleData::~QQuickParticleData() +{ + delete v8Datum; +} + +void QQuickParticleData::clone(const QQuickParticleData& other) +{ + x = other.x; + y = other.y; + t = other.t; + lifeSpan = other.lifeSpan; + size = other.size; + endSize = other.endSize; + vx = other.vx; + vy = other.vy; + ax = other.ax; + ay = other.ay; + xx = other.xx; + xy = other.xy; + yx = other.yx; + yy = other.yy; + rotation = other.rotation; + rotationSpeed = other.rotationSpeed; + autoRotate = other.autoRotate; + animIdx = other.animIdx; + frameDuration = other.frameDuration; + frameCount = other.frameCount; + animT = other.animT; + animX = other.animX; + animY = other.animY; + animWidth = other.animWidth; + animHeight = other.animHeight; + color.r = other.color.r; + color.g = other.color.g; + color.b = other.color.b; + color.a = other.color.a; + r = other.r; + delegate = other.delegate; + modelIndex = other.modelIndex; + + colorOwner = other.colorOwner; + rotationOwner = other.rotationOwner; + deformationOwner = other.deformationOwner; + animationOwner = other.animationOwner; +} + +QQmlV8Handle QQuickParticleData::v8Value() +{ + if (!v8Datum) + v8Datum = new QQuickV8ParticleData(QQmlEnginePrivate::getV8Engine(qmlEngine(system)), this); + return v8Datum->v8Value(); +} +//sets the x accleration without affecting the instantaneous x velocity or position +void QQuickParticleData::setInstantaneousAX(qreal ax) +{ + qreal t = (system->timeInt / 1000.0) - this->t; + qreal vx = (this->vx + t*this->ax) - t*ax; + qreal ex = this->x + this->vx * t + 0.5 * this->ax * t * t; + qreal x = ex - t*vx - 0.5 * t*t*ax; + + this->ax = ax; + this->vx = vx; + this->x = x; +} + +//sets the x velocity without affecting the instantaneous x postion +void QQuickParticleData::setInstantaneousVX(qreal vx) +{ + qreal t = (system->timeInt / 1000.0) - this->t; + qreal evx = vx - t*this->ax; + qreal ex = this->x + this->vx * t + 0.5 * this->ax * t * t; + qreal x = ex - t*evx - 0.5 * t*t*this->ax; + + this->vx = evx; + this->x = x; +} + +//sets the instantaneous x postion +void QQuickParticleData::setInstantaneousX(qreal x) +{ + qreal t = (system->timeInt / 1000.0) - this->t; + this->x = x - t*this->vx - 0.5 * t*t*this->ax; +} + +//sets the y accleration without affecting the instantaneous y velocity or position +void QQuickParticleData::setInstantaneousAY(qreal ay) +{ + qreal t = (system->timeInt / 1000.0) - this->t; + qreal vy = (this->vy + t*this->ay) - t*ay; + qreal ey = this->y + this->vy * t + 0.5 * this->ay * t * t; + qreal y = ey - t*vy - 0.5 * t*t*ay; + + this->ay = ay; + this->vy = vy; + this->y = y; +} + +//sets the y velocity without affecting the instantaneous y position +void QQuickParticleData::setInstantaneousVY(qreal vy) +{ + qreal t = (system->timeInt / 1000.0) - this->t; + qreal evy = vy - t*this->ay; + qreal ey = this->y + this->vy * t + 0.5 * this->ay * t * t; + qreal y = ey - t*evy - 0.5 * t*t*this->ay; + + this->vy = evy; + this->y = y; +} + +//sets the instantaneous Y position +void QQuickParticleData::setInstantaneousY(qreal y) +{ + qreal t = (system->timeInt / 1000.0) - this->t; + this->y = y - t*this->vy - 0.5 * t*t*this->ay; +} + +qreal QQuickParticleData::curX() const +{ + qreal t = (system->timeInt / 1000.0) - this->t; + return this->x + this->vx * t + 0.5 * this->ax * t * t; +} + +qreal QQuickParticleData::curVX() const +{ + qreal t = (system->timeInt / 1000.0) - this->t; + return this->vx + t*this->ax; +} + +qreal QQuickParticleData::curY() const +{ + qreal t = (system->timeInt / 1000.0) - this->t; + return y + vy * t + 0.5 * ay * t * t; +} + +qreal QQuickParticleData::curVY() const +{ + qreal t = (system->timeInt / 1000.0) - this->t; + return vy + t*ay; +} + +void QQuickParticleData::debugDump() +{ + qDebug() << "Particle" << systemIndex << group << "/" << index << stillAlive() + << "Pos: " << x << "," << y + << "Vel: " << vx << "," << vy + << "Acc: " << ax << "," << ay + << "Size: " << size << "," << endSize + << "Time: " << t << "," <timeInt / 1000.0) ; +} + +bool QQuickParticleData::stillAlive() +{ + if (!system) + return false; + return (t + lifeSpan - EPSILON) > ((qreal)system->timeInt/1000.0); +} + +bool QQuickParticleData::alive() +{ + if (!system) + return false; + qreal st = ((qreal)system->timeInt/1000.0); + return (t + EPSILON) < st && (t + lifeSpan - EPSILON) > st; +} + +float QQuickParticleData::curSize() +{ + if (!system || !lifeSpan) + return 0.0f; + return size + (endSize - size) * (1 - (lifeLeft() / lifeSpan)); +} + +float QQuickParticleData::lifeLeft() +{ + if (!system) + return 0.0f; + return (t + lifeSpan) - (system->timeInt/1000.0); +} + +void QQuickParticleData::extendLife(float time) +{ + qreal newX = curX(); + qreal newY = curY(); + qreal newVX = curVX(); + qreal newVY = curVY(); + + t += time; + animT += time; + + qreal elapsed = (system->timeInt / 1000.0) - t; + qreal evy = newVY - elapsed*ay; + qreal ey = newY - elapsed*evy - 0.5 * elapsed*elapsed*ay; + qreal evx = newVX - elapsed*ax; + qreal ex = newX - elapsed*evx - 0.5 * elapsed*elapsed*ax; + + x = ex; + vx = evx; + y = ey; + vy = evy; +} + +QQuickParticleSystem::QQuickParticleSystem(QQuickItem *parent) : + QQuickItem(parent), + stateEngine(0), + m_animation(0), + m_running(true), + initialized(0), + particleCount(0), + m_nextIndex(0), + m_componentComplete(false), + m_paused(false), + m_empty(true) +{ + connect(&m_painterMapper, SIGNAL(mapped(QObject*)), + this, SLOT(loadPainter(QObject*))); + + m_debugMode = qmlParticlesDebug(); +} + +QQuickParticleSystem::~QQuickParticleSystem() +{ + foreach (QQuickParticleGroupData* gd, groupData) + delete gd; +} + +void QQuickParticleSystem::initGroups() +{ + m_reusableIndexes.clear(); + m_nextIndex = 0; + + qDeleteAll(groupData); + groupData.clear(); + groupIds.clear(); + + QQuickParticleGroupData* gd = new QQuickParticleGroupData(0, this);//Default group + groupData.insert(0,gd); + groupIds.insert(QString(), 0); + m_nextGroupId = 1; +} + +void QQuickParticleSystem::registerParticlePainter(QQuickParticlePainter* p) +{ + if (m_debugMode) + qDebug() << "Registering Painter" << p << "to" << this; + //TODO: a way to Unregister emitters, painters and affectors + m_painters << QPointer(p);//###Set or uniqueness checking? + connect(p, SIGNAL(groupsChanged(QStringList)), + &m_painterMapper, SLOT(map())); + loadPainter(p); +} + +void QQuickParticleSystem::registerParticleEmitter(QQuickParticleEmitter* e) +{ + if (m_debugMode) + qDebug() << "Registering Emitter" << e << "to" << this; + m_emitters << QPointer(e);//###How to get them out? + connect(e, SIGNAL(particleCountChanged()), + this, SLOT(emittersChanged())); + connect(e, SIGNAL(groupChanged(QString)), + this, SLOT(emittersChanged())); + emittersChanged(); + e->reset();//Start, so that starttime factors appropriately +} + +void QQuickParticleSystem::registerParticleAffector(QQuickParticleAffector* a) +{ + if (m_debugMode) + qDebug() << "Registering Affector" << a << "to" << this; + m_affectors << QPointer(a); +} + +void QQuickParticleSystem::registerParticleGroup(QQuickParticleGroup* g) +{ + if (m_debugMode) + qDebug() << "Registering Group" << g << "to" << this; + m_groups << QPointer(g); + createEngine(); +} + +void QQuickParticleSystem::setRunning(bool arg) +{ + if (m_running != arg) { + m_running = arg; + emit runningChanged(arg); + setPaused(false); + if (m_animation)//Not created until componentCompleted + m_running ? m_animation->start() : m_animation->stop(); + reset(); + } +} + +void QQuickParticleSystem::setPaused(bool arg) { + if (m_paused != arg) { + m_paused = arg; + if (m_animation && m_animation->state() != QAbstractAnimation::Stopped) + m_paused ? m_animation->pause() : m_animation->resume(); + if (!m_paused) { + foreach (QQuickParticlePainter *p, m_painters) + p->update(); + } + emit pausedChanged(arg); + } +} + +void QQuickParticleSystem::statePropertyRedirect(QQmlListProperty *prop, QObject *value) +{ + //Hooks up automatic state-associated stuff + QQuickParticleSystem* sys = qobject_cast(prop->object->parent()); + QQuickParticleGroup* group = qobject_cast(prop->object); + if (!group || !sys || !value) + return; + stateRedirect(group, sys, value); +} + +void QQuickParticleSystem::stateRedirect(QQuickParticleGroup* group, QQuickParticleSystem* sys, QObject *value) +{ + QStringList list; + list << group->name(); + QQuickParticleAffector* a = qobject_cast(value); + if (a) { + a->setParentItem(sys); + a->setGroups(list); + a->setSystem(sys); + return; + } + QQuickTrailEmitter* fe = qobject_cast(value); + if (fe) { + fe->setParentItem(sys); + fe->setFollow(group->name()); + fe->setSystem(sys); + return; + } + QQuickParticleEmitter* e = qobject_cast(value); + if (e) { + e->setParentItem(sys); + e->setGroup(group->name()); + e->setSystem(sys); + return; + } + QQuickParticlePainter* p = qobject_cast(value); + if (p) { + p->setParentItem(sys); + p->setGroups(list); + p->setSystem(sys); + return; + } + qWarning() << value << " was placed inside a particle system state but cannot be taken into the particle system. It will be lost."; +} + +void QQuickParticleSystem::componentComplete() + +{ + QQuickItem::componentComplete(); + m_componentComplete = true; + m_animation = new QQuickParticleSystemAnimation(this); + reset();//restarts animation as well +} + +void QQuickParticleSystem::reset() +{ + if (!m_componentComplete) + return; + + timeInt = 0; + //Clear guarded pointers which have been deleted + int cleared = 0; + cleared += m_emitters.removeAll(0); + cleared += m_painters.removeAll(0); + cleared += m_affectors.removeAll(0); + + bySysIdx.resize(0); + initGroups();//Also clears all logical particles + + if (!m_running) + return; + + foreach (QQuickParticleEmitter* e, m_emitters) + e->reset(); + + emittersChanged(); + + foreach (QQuickParticlePainter *p, m_painters) { + loadPainter(p); + p->reset(); + } + + //### Do affectors need reset too? + if (m_animation) {//Animation is explicitly disabled in benchmarks + //reset restarts animation (if running) + if ((m_animation->state() == QAbstractAnimation::Running)) + m_animation->stop(); + m_animation->start(); + if (m_paused) + m_animation->pause(); + } + + initialized = true; +} + + +void QQuickParticleSystem::loadPainter(QObject *p) +{ + if (!m_componentComplete || !p) + return; + + QQuickParticlePainter* painter = qobject_cast(p); + Q_ASSERT(painter);//XXX + foreach (QQuickParticleGroupData* sg, groupData) + sg->painters.remove(painter); + int particleCount = 0; + if (painter->groups().isEmpty()) {//Uses default particle + QStringList def; + def << QString(); + painter->setGroups(def); + particleCount += groupData[0]->size(); + groupData[0]->painters << painter; + } else { + foreach (const QString &group, painter->groups()) { + if (group != QLatin1String("") && !groupIds[group]) {//new group + int id = m_nextGroupId++; + QQuickParticleGroupData* gd = new QQuickParticleGroupData(id, this); + groupIds.insert(group, id); + groupData.insert(id, gd); + } + particleCount += groupData[groupIds[group]]->size(); + groupData[groupIds[group]]->painters << painter; + } + } + painter->setCount(particleCount); + painter->update();//Initial update here + return; +} + +void QQuickParticleSystem::emittersChanged() +{ + if (!m_componentComplete) + return; + + m_emitters.removeAll(0); + + + QList previousSizes; + QList newSizes; + for (int i=0; isize(); + newSizes << 0; + } + + foreach (QQuickParticleEmitter* e, m_emitters) {//Populate groups and set sizes. + if (!groupIds.contains(e->group()) + || (!e->group().isEmpty() && !groupIds[e->group()])) {//or it was accidentally inserted by a failed lookup earlier + int id = m_nextGroupId++; + QQuickParticleGroupData* gd = new QQuickParticleGroupData(id, this); + groupIds.insert(e->group(), id); + groupData.insert(id, gd); + previousSizes << 0; + newSizes << 0; + } + newSizes[groupIds[e->group()]] += e->particleCount(); + //###: Cull emptied groups? + } + + //TODO: Garbage collection? + particleCount = 0; + for (int i=0; isetSize(qMax(newSizes[i], previousSizes[i])); + particleCount += groupData[i]->size(); + } + + if (m_debugMode) + qDebug() << "Particle system emitters changed. New particle count: " << particleCount; + + if (particleCount > bySysIdx.size())//New datum requests haven't updated it + bySysIdx.resize(particleCount); + + foreach (QQuickParticleAffector *a, m_affectors)//Groups may have changed + a->m_updateIntSet = true; + + foreach (QQuickParticlePainter *p, m_painters) + loadPainter(p); + + if (!m_groups.isEmpty()) + createEngine(); + +} + +void QQuickParticleSystem::createEngine() +{ + if (!m_componentComplete) + return; + if (stateEngine && m_debugMode) + qDebug() << "Resetting Existing Sprite Engine..."; + //### Solve the losses if size/states go down + foreach (QQuickParticleGroup* group, m_groups) { + bool exists = false; + foreach (const QString &name, groupIds.keys()) + if (group->name() == name) + exists = true; + if (!exists) { + int id = m_nextGroupId++; + QQuickParticleGroupData* gd = new QQuickParticleGroupData(id, this); + groupIds.insert(group->name(), id); + groupData.insert(id, gd); + } + } + + if (m_groups.count()) { + //Reorder groups List so as to have the same order as groupData + QList newList; + for (int i=0; iname(); + foreach (QQuickParticleGroup* existing, m_groups) { + if (existing->name() == name) { + newList << existing; + exists = true; + } + } + if (!exists) { + newList << new QQuickParticleGroup(this); + newList.back()->setName(name); + } + } + m_groups = newList; + QList states; + foreach (QQuickParticleGroup* g, m_groups) + states << (QQuickStochasticState*)g; + + if (!stateEngine) + stateEngine = new QQuickStochasticEngine(this); + stateEngine->setCount(particleCount); + stateEngine->m_states = states; + + connect(stateEngine, SIGNAL(stateChanged(int)), + this, SLOT(particleStateChange(int))); + + } else { + if (stateEngine) + delete stateEngine; + stateEngine = 0; + } + +} + +void QQuickParticleSystem::particleStateChange(int idx) +{ + moveGroups(bySysIdx[idx], stateEngine->curState(idx)); +} + +void QQuickParticleSystem::moveGroups(QQuickParticleData *d, int newGIdx) +{ + if (!d || newGIdx == d->group) + return; + + QQuickParticleData* pd = newDatum(newGIdx, false, d->systemIndex); + if (!pd) + return; + + pd->clone(*d); + finishNewDatum(pd); + + d->systemIndex = -1; + groupData[d->group]->kill(d); +} + +int QQuickParticleSystem::nextSystemIndex() +{ + if (!m_reusableIndexes.isEmpty()) { + int ret = *(m_reusableIndexes.begin()); + m_reusableIndexes.remove(ret); + return ret; + } + if (m_nextIndex >= bySysIdx.size()) { + bySysIdx.resize(bySysIdx.size() < 10 ? 10 : bySysIdx.size()*1.1);//###+1,10%,+10? Choose something non-arbitrarily + if (stateEngine) + stateEngine->setCount(bySysIdx.size()); + + } + return m_nextIndex++; +} + +QQuickParticleData* QQuickParticleSystem::newDatum(int groupId, bool respectLimits, int sysIndex) +{ + Q_ASSERT(groupId < groupData.count());//XXX shouldn't really be an assert + + QQuickParticleData* ret = groupData[groupId]->newDatum(respectLimits); + if (!ret) { + return 0; + } + if (sysIndex == -1) { + if (ret->systemIndex == -1) + ret->systemIndex = nextSystemIndex(); + } else { + if (ret->systemIndex != -1) { + if (stateEngine) + stateEngine->stop(ret->systemIndex); + m_reusableIndexes << ret->systemIndex; + bySysIdx[ret->systemIndex] = 0; + } + ret->systemIndex = sysIndex; + } + bySysIdx[ret->systemIndex] = ret; + + if (stateEngine) + stateEngine->start(ret->systemIndex, ret->group); + + m_empty = false; + return ret; +} + +void QQuickParticleSystem::emitParticle(QQuickParticleData* pd) +{// called from prepareNextFrame()->emitWindow - enforce? + //Account for relative emitter position + QPointF offset = this->mapFromItem(pd->e, QPointF(0, 0)); + if (!offset.isNull()) { + pd->x += offset.x(); + pd->y += offset.y(); + } + + finishNewDatum(pd); +} + +void QQuickParticleSystem::finishNewDatum(QQuickParticleData *pd) +{ + Q_ASSERT(pd); + groupData[pd->group]->prepareRecycler(pd); + + foreach (QQuickParticleAffector *a, m_affectors) + if (a && a->m_needsReset) + a->reset(pd); + foreach (QQuickParticlePainter* p, groupData[pd->group]->painters) + if (p) + p->load(pd); +} + +void QQuickParticleSystem::updateCurrentTime( int currentTime ) +{ + if (!initialized) + return;//error in initialization + + //### Elapsed time never shrinks - may cause problems if left emitting for weeks at a time. + qreal dt = timeInt / 1000.; + timeInt = currentTime; + qreal time = timeInt / 1000.; + dt = time - dt; + needsReset.clear(); + + m_emitters.removeAll(0); + m_painters.removeAll(0); + m_affectors.removeAll(0); + + bool oldClear = m_empty; + m_empty = true; + foreach (QQuickParticleGroupData* gd, groupData)//Recycle all groups and see if they're out of live particles + m_empty = gd->recycle() && m_empty; + + if (stateEngine) + stateEngine->updateSprites(timeInt); + + foreach (QQuickParticleEmitter* emitter, m_emitters) + emitter->emitWindow(timeInt); + foreach (QQuickParticleAffector* a, m_affectors) + a->affectSystem(dt); + foreach (QQuickParticleData* d, needsReset) + foreach (QQuickParticlePainter* p, groupData[d->group]->painters) + p->reload(d); + + if (oldClear != m_empty) + emptyChanged(m_empty); +} + +int QQuickParticleSystem::systemSync(QQuickParticlePainter* p) +{ + if (!m_running) + return 0; + if (!initialized) + return 0;//error in initialization + p->performPendingCommits(); + return timeInt; +} + + +QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquickparticlesystem_p.h qt5-declarative-0.1~git20120423/src/particles/qquickparticlesystem_p.h --- qt5-declarative-0.1~git20120402/src/particles/qquickparticlesystem_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquickparticlesystem_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,379 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PARTICLESYSTEM_H +#define PARTICLESYSTEM_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include //For QQmlV8Handle + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QQuickParticleSystem; +class QQuickParticleAffector; +class QQuickParticleEmitter; +class QQuickParticlePainter; +class QQuickParticleData; +class QQuickParticleSystemAnimation; +class QQuickStochasticEngine; +class QQuickSprite; +class QQuickV8ParticleData; +class QQuickParticleGroup; +class QQuickImageParticle; + +struct QQuickParticleDataHeapNode{ + int time;//in ms + QSet data;//Set ptrs instead? +}; + +class QQuickParticleDataHeap { + //Idea is to do a binary heap, but which also stores a set of int,Node* so that if the int already exists, you can + //add it to the data* list. Pops return the whole list at once. +public: + QQuickParticleDataHeap(); + void insert(QQuickParticleData* data); + void insertTimed(QQuickParticleData* data, int time); + + int top(); + + QSet pop(); + + void clear(); + + bool contains(QQuickParticleData*);//O(n), for debugging purposes only +private: + void grow(); + void swap(int, int); + void bubbleUp(int); + void bubbleDown(int); + int m_size; + int m_end; + QQuickParticleDataHeapNode m_tmp; + QVector m_data; + QHash m_lookups; +}; + +class Q_AUTOTEST_EXPORT QQuickParticleGroupData { +public: + QQuickParticleGroupData(int id, QQuickParticleSystem* sys); + ~QQuickParticleGroupData(); + + int size(); + QString name(); + + void setSize(int newSize); + + int index; + QSet painters;//TODO: What if they are dynamically removed? + + //TODO: Refactor particle data list out into a separate class + QVector data; + QQuickParticleDataHeap dataHeap; + QSet reusableIndexes; + bool recycle(); //Force recycling round, returns true if all indexes are now reusable + + void initList(); + void kill(QQuickParticleData* d); + + //After calling this, initialize, then call prepareRecycler(d) + QQuickParticleData* newDatum(bool respectsLimits); + + //TODO: Find and clean up those that don't get added to the recycler (currently they get lost) + void prepareRecycler(QQuickParticleData* d); + +private: + int m_size; + QQuickParticleSystem* m_system; +}; + +struct Color4ub { + uchar r; + uchar g; + uchar b; + uchar a; +}; + +class Q_AUTOTEST_EXPORT QQuickParticleData { +public: + //TODO: QObject like memory management (without the cost, just attached to system) + QQuickParticleData(QQuickParticleSystem* sys); + ~QQuickParticleData(); + + //Convenience functions for working backwards, because parameters are from the start of particle life + //If setting multiple parameters at once, doing the conversion yourself will be faster. + + //sets the x accleration without affecting the instantaneous x velocity or position + void setInstantaneousAX(qreal ax); + //sets the x velocity without affecting the instantaneous x postion + void setInstantaneousVX(qreal vx); + //sets the instantaneous x postion + void setInstantaneousX(qreal x); + //sets the y accleration without affecting the instantaneous y velocity or position + void setInstantaneousAY(qreal ay); + //sets the y velocity without affecting the instantaneous y postion + void setInstantaneousVY(qreal vy); + //sets the instantaneous Y postion + void setInstantaneousY(qreal y); + + //TODO: Slight caching? + qreal curX() const; + qreal curVX() const; + qreal curAX() const { return ax; } + qreal curY() const; + qreal curVY() const; + qreal curAY() const { return ay; } + + int group; + QQuickParticleEmitter* e;//### Needed? + QQuickParticleSystem* system; + int index; + int systemIndex; + + //General Position Stuff + float x; + float y; + float t; + float lifeSpan; + float size; + float endSize; + float vx; + float vy; + float ax; + float ay; + + //Other stuff, now universally shared + Color4ub color; + float xx; + float xy; + float yx; + float yy; + float rotation; + float rotationSpeed; + float autoRotate;//Assume that GPUs prefer floats to bools + float animIdx; + float frameDuration; + float frameAt;//Used for duration -1 + float frameCount; + float animT; + float animX; + float animY; + float animWidth; + float animHeight; + float r; + QQuickItem* delegate; + int modelIndex; + float update;//Used by custom affectors + + //Used by image particle + QQuickImageParticle* colorOwner; + QQuickImageParticle* rotationOwner; + QQuickImageParticle* deformationOwner; + QQuickImageParticle* animationOwner; + + void debugDump(); + bool stillAlive();//Only checks end, because usually that's all you need and it's a little faster. + bool alive(); + float lifeLeft(); + float curSize(); + void clone(const QQuickParticleData& other);//Not =, leaves meta-data like index + QQmlV8Handle v8Value(); + void extendLife(float time); +private: + QQuickV8ParticleData* v8Datum; +}; + +class Q_AUTOTEST_EXPORT QQuickParticleSystem : public QQuickItem +{ + Q_OBJECT + Q_PROPERTY(bool running READ isRunning WRITE setRunning NOTIFY runningChanged) + Q_PROPERTY(bool paused READ isPaused WRITE setPaused NOTIFY pausedChanged) + Q_PROPERTY(bool empty READ isEmpty NOTIFY emptyChanged) + +public: + explicit QQuickParticleSystem(QQuickItem *parent = 0); + ~QQuickParticleSystem(); + + bool isRunning() const + { + return m_running; + } + + int count(){ return particleCount; } + + static const int maxLife = 600000; + +signals: + + void systemInitialized(); + void runningChanged(bool arg); + void pausedChanged(bool arg); + void emptyChanged(bool arg); + +public slots: + void start(){setRunning(true);} + void stop(){setRunning(false);} + void restart(){setRunning(false);setRunning(true);} + void pause(){setPaused(true);} + void resume(){setPaused(false);} + + void reset(); + void setRunning(bool arg); + void setPaused(bool arg); + + virtual int duration() const { return -1; } + + +protected: + //This one only once per frame (effectively) + void componentComplete(); + +private slots: + void emittersChanged(); + void loadPainter(QObject* p); + void createEngine(); //Not invoked by sprite engine, unlike Sprite uses + void particleStateChange(int idx); + +public: + //These can be called multiple times per frame, performance critical + void emitParticle(QQuickParticleData* p); + QQuickParticleData* newDatum(int groupId, bool respectLimits = true, int sysIdx = -1); + void finishNewDatum(QQuickParticleData*); + void moveGroups(QQuickParticleData *d, int newGIdx); + int nextSystemIndex(); + + //This one only once per painter per frame + int systemSync(QQuickParticlePainter* p); + + //Data members here for ease of related class and auto-test usage. Not "public" API. TODO: d_ptrize + QSet needsReset; + QVector bySysIdx; //Another reference to the data (data owned by group), but by sysIdx + QHash groupIds; + QHash groupData; + QQuickStochasticEngine* stateEngine; + + //Also only here for auto-test usage + void updateCurrentTime( int currentTime ); + QQuickParticleSystemAnimation* m_animation; + bool m_running; + bool m_debugMode; + + int timeInt; + bool initialized; + int particleCount; + + void registerParticlePainter(QQuickParticlePainter* p); + void registerParticleEmitter(QQuickParticleEmitter* e); + void registerParticleAffector(QQuickParticleAffector* a); + void registerParticleGroup(QQuickParticleGroup* g); + + static void statePropertyRedirect(QQmlListProperty *prop, QObject *value); + static void stateRedirect(QQuickParticleGroup* group, QQuickParticleSystem* sys, QObject *value); + bool isPaused() const + { + return m_paused; + } + + bool isEmpty() const + { + return m_empty; + } + +private: + void initializeSystem(); + void initGroups(); + QList > m_emitters; + QList > m_affectors; + QList > m_painters; + QList > m_syncList; + QList m_groups; + int m_nextGroupId; + int m_nextIndex; + QSet m_reusableIndexes; + bool m_componentComplete; + + QSignalMapper m_painterMapper; + QSignalMapper m_emitterMapper; + bool m_paused; + bool m_allDead; + bool m_empty; +}; + +// Internally, this animation drives all the timing. Painters sync up in their updatePaintNode +class QQuickParticleSystemAnimation : public QAbstractAnimation +{ + Q_OBJECT +public: + QQuickParticleSystemAnimation(QQuickParticleSystem* system) + : QAbstractAnimation(static_cast(system)), m_system(system) + { } +protected: + virtual void updateCurrentTime( int t ) + { + m_system->updateCurrentTime(t); + } + + virtual int duration() const + { + return -1; + } + +private: + QQuickParticleSystem* m_system; +}; + + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // PARTICLESYSTEM_H + + diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquickpointattractor.cpp qt5-declarative-0.1~git20120423/src/particles/qquickpointattractor.cpp --- qt5-declarative-0.1~git20120402/src/particles/qquickpointattractor.cpp 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquickpointattractor.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,162 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickpointattractor_p.h" +#include +#include +QT_BEGIN_NAMESPACE +/*! + \qmlclass Attractor QQuickAttractorAffector + \inqmlmodule QtQuick.Particles 2 + \inherits Affector + \brief The Attractor allows you to attract particles towards a specific point. + + Note that the size and position of this element affects which particles it affects. + The size of the point attracted to is always 0x0, and the location of that point + is specified by the pointX and pointY properties. + + Note that Attractor has the standard Item x,y,width and height properties. + Like other affectors, these represent the affected area. They + do not represent the 0x0 point which is the target of the attraction. +*/ + + +/*! + \qmlproperty real QtQuick.Particles2::PointAttractor::pointX + + The x coordinate of the attracting point. This is relative + to the x coordinate of the Attractor. +*/ +/*! + \qmlproperty real QtQuick.Particles2::PointAttractor::pointY + + The y coordinate of the attracting point. This is relative + to the y coordinate of the Attractor. +*/ +/*! + \qmlproperty real QtQuick.Particles2::PointAttractor::strength + + The pull, in units per second, to be exerted on an item one pixel away. + + Depending on how the attraction is proportionalToDistance this may have to + be very high or very low to have a reasonable effect on particles at a + distance. +*/ +/*! + \qmlproperty AffectableParameter QtQuick.Particles2::Attractor::affectedParameter + + What attribute of particles is directly affected. + \list + \li Attractor.Position + \li Attractor.Velocity + \li Attractor.Acceleration + \endlist +*/ +/*! + \qmlproperty Proportion QtQuick.Particles2::Attractor::proportionalToDistance + + How the distance from the particle to the point affects the strength of the attraction. + + \list + \li Attractor.Constant + \li Attractor.Linear + \li Attractor.InverseLinear + \li Attractor.Quadratic + \li Attractor.InverseQuadratic + \endlist +*/ + + +QQuickAttractorAffector::QQuickAttractorAffector(QQuickItem *parent) : + QQuickParticleAffector(parent), m_strength(0.0), m_x(0), m_y(0) + , m_physics(Velocity), m_proportionalToDistance(Linear) +{ +} + +bool QQuickAttractorAffector::affectParticle(QQuickParticleData *d, qreal dt) +{ + if (m_strength == 0.0) + return false; + qreal dx = m_x+m_offset.x() - d->curX(); + qreal dy = m_y+m_offset.y() - d->curY(); + qreal r = sqrt((dx*dx) + (dy*dy)); + qreal theta = atan2(dy,dx); + qreal ds = 0; + switch (m_proportionalToDistance){ + case InverseQuadratic: + ds = (m_strength / qMax(1.,r*r)); + break; + case InverseLinear: + ds = (m_strength / qMax(1.,r)); + break; + case Quadratic: + ds = (m_strength * qMax(1.,r*r)); + break; + case Linear: + ds = (m_strength * qMax(1.,r)); + break; + default: //also Constant + ds = m_strength; + } + ds *= dt; + dx = ds * cos(theta); + dy = ds * sin(theta); + qreal vx,vy; + switch (m_physics){ + case Position: + d->x = (d->x + dx); + d->y = (d->y + dy); + break; + case Acceleration: + d->setInstantaneousAX(d->ax + dx); + d->setInstantaneousAY(d->ay + dy); + break; + case Velocity: //also default + default: + vx = d->curVX(); + vy = d->curVY(); + d->setInstantaneousVX(vx + dx); + d->setInstantaneousVY(vy + dy); + } + + return true; +} +QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquickpointattractor_p.h qt5-declarative-0.1~git20120423/src/particles/qquickpointattractor_p.h --- qt5-declarative-0.1~git20120402/src/particles/qquickpointattractor_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquickpointattractor_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,167 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef ATTRACTORAFFECTOR_H +#define ATTRACTORAFFECTOR_H +#include "qquickparticleaffector_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QQuickAttractorAffector : public QQuickParticleAffector +{ + Q_OBJECT + Q_PROPERTY(qreal strength READ strength WRITE setStrength NOTIFY strengthChanged) + Q_PROPERTY(qreal pointX READ pointX WRITE setPointX NOTIFY pointXChanged) + Q_PROPERTY(qreal pointY READ pointY WRITE setPointY NOTIFY pointYChanged) + Q_PROPERTY(AffectableParameters affectedParameter READ affectedParameter WRITE setAffectedParameter NOTIFY affectedParameterChanged) + Q_PROPERTY(Proportion proportionalToDistance READ proportionalToDistance WRITE setProportionalToDistance NOTIFY proportionalToDistanceChanged) + Q_ENUMS(AffectableParameters) + Q_ENUMS(Proportion) + +public: + enum Proportion{ + Constant, + Linear, + Quadratic, + InverseLinear, + InverseQuadratic + }; + + enum AffectableParameters { + Position, + Velocity, + Acceleration + }; + + explicit QQuickAttractorAffector(QQuickItem *parent = 0); + + qreal strength() const + { + return m_strength; + } + + qreal pointX() const + { + return m_x; + } + + qreal pointY() const + { + return m_y; + } + + AffectableParameters affectedParameter() const + { + return m_physics; + } + + Proportion proportionalToDistance() const + { + return m_proportionalToDistance; + } + +signals: + + void strengthChanged(qreal arg); + + void pointXChanged(qreal arg); + + void pointYChanged(qreal arg); + + void affectedParameterChanged(AffectableParameters arg); + + void proportionalToDistanceChanged(Proportion arg); + +public slots: +void setStrength(qreal arg) +{ + if (m_strength != arg) { + m_strength = arg; + emit strengthChanged(arg); + } +} + +void setPointX(qreal arg) +{ + if (m_x != arg) { + m_x = arg; + emit pointXChanged(arg); + } +} + +void setPointY(qreal arg) +{ + if (m_y != arg) { + m_y = arg; + emit pointYChanged(arg); + } +} +void setAffectedParameter(AffectableParameters arg) +{ + if (m_physics != arg) { + m_physics = arg; + emit affectedParameterChanged(arg); + } +} + +void setProportionalToDistance(Proportion arg) +{ + if (m_proportionalToDistance != arg) { + m_proportionalToDistance = arg; + emit proportionalToDistanceChanged(arg); + } +} + +protected: + virtual bool affectParticle(QQuickParticleData *d, qreal dt); +private: +qreal m_strength; +qreal m_x; +qreal m_y; +AffectableParameters m_physics; +Proportion m_proportionalToDistance; +}; + +QT_END_NAMESPACE +QT_END_HEADER +#endif // ATTRACTORAFFECTOR_H diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquickpointdirection.cpp qt5-declarative-0.1~git20120423/src/particles/qquickpointdirection.cpp --- qt5-declarative-0.1~git20120402/src/particles/qquickpointdirection.cpp 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquickpointdirection.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickpointdirection_p.h" +#include + +QT_BEGIN_NAMESPACE + +/*! + \qmlclass PointDirection QQuickPointDirection + \inqmlmodule QtQuick.Particles 2 + \inherits Direction + \brief The PointDirection element allows you to specify a direction that varies in x and y components + + The PointDirection element allows both the specification of a direction by x and y components, + as well as varying the parameters by x or y component. +*/ +/*! + \qmlproperty real QtQuick.Particles2::PointDirection::x +*/ +/*! + \qmlproperty real QtQuick.Particles2::PointDirection::y +*/ +/*! + \qmlproperty real QtQuick.Particles2::PointDirection::xVariation +*/ +/*! + \qmlproperty real QtQuick.Particles2::PointDirection::yVariation +*/ + +QQuickPointDirection::QQuickPointDirection(QObject *parent) : + QQuickDirection(parent) + , m_x(0) + , m_y(0) + , m_xVariation(0) + , m_yVariation(0) +{ +} + +const QPointF QQuickPointDirection::sample(const QPointF &) +{ + QPointF ret; + ret.setX(m_x - m_xVariation + rand() / float(RAND_MAX) * m_xVariation * 2); + ret.setY(m_y - m_yVariation + rand() / float(RAND_MAX) * m_yVariation * 2); + return ret; +} + +QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquickpointdirection_p.h qt5-declarative-0.1~git20120423/src/particles/qquickpointdirection_p.h --- qt5-declarative-0.1~git20120402/src/particles/qquickpointdirection_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquickpointdirection_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,133 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef POINTVECTOR_H +#define POINTVECTOR_H +#include "qquickdirection_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QQuickPointDirection : public QQuickDirection +{ + Q_OBJECT + Q_PROPERTY(qreal x READ x WRITE setX NOTIFY xChanged) + Q_PROPERTY(qreal y READ y WRITE setY NOTIFY yChanged) + Q_PROPERTY(qreal xVariation READ xVariation WRITE setXVariation NOTIFY xVariationChanged) + Q_PROPERTY(qreal yVariation READ yVariation WRITE setYVariation NOTIFY yVariationChanged) +public: + explicit QQuickPointDirection(QObject *parent = 0); + virtual const QPointF sample(const QPointF &from); + qreal x() const + { + return m_x; + } + + qreal y() const + { + return m_y; + } + + qreal xVariation() const + { + return m_xVariation; + } + + qreal yVariation() const + { + return m_yVariation; + } + +signals: + + void xChanged(qreal arg); + + void yChanged(qreal arg); + + void xVariationChanged(qreal arg); + + void yVariationChanged(qreal arg); + +public slots: + void setX(qreal arg) + { + if (m_x != arg) { + m_x = arg; + emit xChanged(arg); + } + } + + void setY(qreal arg) + { + if (m_y != arg) { + m_y = arg; + emit yChanged(arg); + } + } + + void setXVariation(qreal arg) + { + if (m_xVariation != arg) { + m_xVariation = arg; + emit xVariationChanged(arg); + } + } + + void setYVariation(qreal arg) + { + if (m_yVariation != arg) { + m_yVariation = arg; + emit yVariationChanged(arg); + } + } + +private: + + qreal m_x; + qreal m_y; + qreal m_xVariation; + qreal m_yVariation; +}; + +QT_END_NAMESPACE +QT_END_HEADER +#endif // POINTVECTOR_H diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquickrectangleextruder.cpp qt5-declarative-0.1~git20120423/src/particles/qquickrectangleextruder.cpp --- qt5-declarative-0.1~git20120402/src/particles/qquickrectangleextruder.cpp 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquickrectangleextruder.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickrectangleextruder_p.h" +#include + +QT_BEGIN_NAMESPACE + +/*! + \qmlclass RectangleShape QQuickRectangleExtruder + \inqmlmodule QtQuick.Particles 2 + \brief The RectangleShape element allows you to specify an area for affectors and emitter. + + Just a rectangle. +*/ + +QQuickRectangleExtruder::QQuickRectangleExtruder(QObject *parent) : + QQuickParticleExtruder(parent), m_fill(true) +{ +} + +QPointF QQuickRectangleExtruder::extrude(const QRectF &rect) +{ + if (m_fill) + return QPointF(((qreal)rand() / RAND_MAX) * rect.width() + rect.x(), + ((qreal)rand() / RAND_MAX) * rect.height() + rect.y()); + int side = rand() % 4; + switch (side){//TODO: Doesn't this overlap the corners? + case 0: + return QPointF(rect.x(), + ((qreal)rand() / RAND_MAX) * rect.height() + rect.y()); + case 1: + return QPointF(rect.width() + rect.x(), + ((qreal)rand() / RAND_MAX) * rect.height() + rect.y()); + case 2: + return QPointF(((qreal)rand() / RAND_MAX) * rect.width() + rect.x(), + rect.y()); + default: + return QPointF(((qreal)rand() / RAND_MAX) * rect.width() + rect.x(), + rect.height() + rect.y()); + } +} + +bool QQuickRectangleExtruder::contains(const QRectF &bounds, const QPointF &point) +{ + return bounds.contains(point); +} + +QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquickrectangleextruder_p.h qt5-declarative-0.1~git20120423/src/particles/qquickrectangleextruder_p.h --- qt5-declarative-0.1~git20120402/src/particles/qquickrectangleextruder_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquickrectangleextruder_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef RECTANGLEEXTRUDER_H +#define RECTANGLEEXTRUDER_H + +#include "qquickparticleextruder_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QQuickRectangleExtruder : public QQuickParticleExtruder +{ + Q_OBJECT + Q_PROPERTY(bool fill READ fill WRITE setFill NOTIFY fillChanged) + +public: + explicit QQuickRectangleExtruder(QObject *parent = 0); + virtual QPointF extrude(const QRectF &); + virtual bool contains(const QRectF &bounds, const QPointF &point); + bool fill() const + { + return m_fill; + } + +signals: + + void fillChanged(bool arg); + +public slots: + + void setFill(bool arg) + { + if (m_fill != arg) { + m_fill = arg; + emit fillChanged(arg); + } + } +protected: + bool m_fill; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // RectangleEXTRUDER_H diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquickspritegoal.cpp qt5-declarative-0.1~git20120423/src/particles/qquickspritegoal.cpp --- qt5-declarative-0.1~git20120402/src/particles/qquickspritegoal.cpp 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquickspritegoal.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,153 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickspritegoal_p.h" +#include +#include +#include "qquickimageparticle_p.h" +#include + +QT_BEGIN_NAMESPACE + +/*! + \qmlclass SpriteGoal QQuickSpriteGoalAffector + \inqmlmodule QtQuick.Particles 2 + \inherits Affector + \brief The SpriteGoal Affector allows you to change the state of a sprite particle. + +*/ +/*! + \qmlproperty string QtQuick.Particles2::SpriteGoal::goalState + + The name of the Sprite which the affected particles should move to. + + Sprite states have defined durations and transitions between them, setting goalState + will cause it to disregard any path weightings (including 0) and head down the path + which will reach the goalState quickest. It will pass through intermediate states + on that path. +*/ +/*! + \qmlproperty bool QtQuick.Particles2::SpriteGoal::jump + + If true, affected sprites will jump directly to the goal state instead of taking the + the shortest valid path to get there. They will also not finish their current state, + but immediately move to the beginning of the goal state. + + Default is false. +*/ +/*! + \qmlproperty bool QtQuick.Particles2::SpriteGoal::systemStates + + deprecated, use GroupGoal instead +*/ + +QQuickSpriteGoalAffector::QQuickSpriteGoalAffector(QQuickItem *parent) : + QQuickParticleAffector(parent), + m_goalIdx(-1), + m_lastEngine(0), + m_jump(false), + m_systemStates(false), + m_notUsingEngine(false) +{ + m_ignoresTime = true; +} + +void QQuickSpriteGoalAffector::updateStateIndex(QQuickStochasticEngine* e) +{ + if (m_systemStates){ + m_goalIdx = m_system->groupIds[m_goalState]; + }else{ + m_lastEngine = e; + for (int i=0; istateCount(); i++){ + if (e->state(i)->name() == m_goalState){ + m_goalIdx = i; + return; + } + } + m_goalIdx = -1;//Can't find it + } +} + +void QQuickSpriteGoalAffector::setGoalState(QString arg) +{ + if (m_goalState != arg) { + m_goalState = arg; + emit goalStateChanged(arg); + if (m_goalState.isEmpty()) + m_goalIdx = -1; + else + m_goalIdx = -2; + } +} + +bool QQuickSpriteGoalAffector::affectParticle(QQuickParticleData *d, qreal dt) +{ + Q_UNUSED(dt); + QQuickStochasticEngine *engine = 0; + if (!m_systemStates){ + //TODO: Affect all engines + foreach (QQuickParticlePainter *p, m_system->groupData[d->group]->painters) + if (qobject_cast(p)) + engine = qobject_cast(p)->spriteEngine(); + }else{ + engine = m_system->stateEngine; + if (!engine) + m_notUsingEngine = true; + } + if (!engine && !m_notUsingEngine) + return false; + + if (m_goalIdx == -2 || engine != m_lastEngine) + updateStateIndex(engine); + int index = d->index; + if (m_systemStates) + index = d->systemIndex; + if (m_notUsingEngine){//systemStates && no stochastic states defined. So cut out the engine + //TODO: It's possible to move to a group that is intermediate and not used by painters or emitters - but right now that will redirect to the default group + m_system->moveGroups(d, m_goalIdx); + }else if (engine->curState(index) != m_goalIdx){ + engine->setGoal(m_goalIdx, index, m_jump); + return true; //Doesn't affect particle data, but necessary for onceOff + } + return false; +} + +QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquickspritegoal_p.h qt5-declarative-0.1~git20120423/src/particles/qquickspritegoal_p.h --- qt5-declarative-0.1~git20120402/src/particles/qquickspritegoal_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquickspritegoal_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,123 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SPRITEGOALAFFECTOR_H +#define SPRITEGOALAFFECTOR_H +#include "qquickparticleaffector_p.h" +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QQuickStochasticEngine; + +class QQuickSpriteGoalAffector : public QQuickParticleAffector +{ + Q_OBJECT + Q_PROPERTY(QString goalState READ goalState WRITE setGoalState NOTIFY goalStateChanged) + Q_PROPERTY(bool jump READ jump WRITE setJump NOTIFY jumpChanged) + Q_PROPERTY(bool systemStates READ systemStates WRITE setSystemStates NOTIFY systemStatesChanged) +public: + explicit QQuickSpriteGoalAffector(QQuickItem *parent = 0); + + QString goalState() const + { + return m_goalState; + } + + bool jump() const + { + return m_jump; + } + bool systemStates() const + { + return m_systemStates; + } + +protected: + virtual bool affectParticle(QQuickParticleData *d, qreal dt); +signals: + + void goalStateChanged(QString arg); + + void jumpChanged(bool arg); + + void systemStatesChanged(bool arg); + +public slots: + +void setGoalState(QString arg); + +void setJump(bool arg) +{ + if (m_jump != arg) { + m_jump = arg; + emit jumpChanged(arg); + } +} + +void setSystemStates(bool arg) +{ + if (m_systemStates != arg) { + //TODO: GroupGoal was added (and this deprecated) Oct 4 - remove it in a few weeks. + qmlInfo(this) << "systemStates is deprecated and will be removed soon. Use GroupGoal instead."; + m_systemStates = arg; + emit systemStatesChanged(arg); + } +} + +private: + void updateStateIndex(QQuickStochasticEngine* e); + QString m_goalState; + int m_goalIdx; + QQuickStochasticEngine* m_lastEngine; + bool m_jump; + bool m_systemStates; + + bool m_notUsingEngine; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // SPRITEGOALAFFECTOR_H diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquicktargetdirection.cpp qt5-declarative-0.1~git20120423/src/particles/qquicktargetdirection.cpp --- qt5-declarative-0.1~git20120402/src/particles/qquicktargetdirection.cpp 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquicktargetdirection.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,131 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquicktargetdirection_p.h" +#include "qquickparticleemitter_p.h" +#include +#include + +QT_BEGIN_NAMESPACE +/*! + \qmlclass TargetDirection QQuickTargetDirection + \inqmlmodule QtQuick.Particles 2 + \inherits Direction + \brief The TargetDirection element allows you to specify a direction towards the target point + +*/ +/*! + \qmlproperty real QtQuick.Particles2::TargetDirection::targetX +*/ +/*! + \qmlproperty real QtQuick.Particles2::TargetDirection::targetY +*/ +/*! + \qmlproperty Item QtQuick.Particles2::TargetDirection::targetItem + If specified, this will take precedence over targetX and targetY. + The targeted point will be the center of the specified Item +*/ +/*! + \qmlproperty real QtQuick.Particles2::TargetDirection::targetVariation +*/ +/*! + \qmlproperty real QtQuick.Particles2::TargetDirection::magnitude +*/ +/*! + \qmlproperty real QtQuick.Particles2::TargetDirection::magnitudeVariation +*/ +/*! + \qmlproperty bool QtQuick.Particles2::TargetDirection::proportionalMagnitude + + If true, then the value of magnitude and magnitudeVariation shall be interpreted as multiples + of the distance between the source point and the target point, per second. + + If false(default), then the value of magnitude and magnitudeVariation shall be interpreted as + pixels per second. +*/ + +QQuickTargetDirection::QQuickTargetDirection(QObject *parent) : + QQuickDirection(parent) + , m_targetX(0) + , m_targetY(0) + , m_targetVariation(0) + , m_proportionalMagnitude(false) + , m_magnitude(0) + , m_magnitudeVariation(0) + , m_targetItem(0) +{ +} + +const QPointF QQuickTargetDirection::sample(const QPointF &from) +{ + //###This approach loses interpolating the last position of the target (like we could with the emitter) is it worthwhile? + QPointF ret; + qreal targetX; + qreal targetY; + if (m_targetItem){ + QQuickParticleEmitter* parentEmitter = qobject_cast(parent()); + targetX = m_targetItem->width()/2; + targetY = m_targetItem->height()/2; + if (!parentEmitter){ + qWarning() << "Directed vector is not a child of the emitter. Mapping of target item coordinates may fail."; + targetX += m_targetItem->x(); + targetY += m_targetItem->y(); + }else{ + ret = parentEmitter->mapFromItem(m_targetItem, QPointF(targetX, targetY)); + targetX = ret.x(); + targetY = ret.y(); + } + }else{ + targetX = m_targetX; + targetY = m_targetY; + } + targetX += 0 - from.x() - m_targetVariation + rand()/(float)RAND_MAX * m_targetVariation*2; + targetY += 0 - from.y() - m_targetVariation + rand()/(float)RAND_MAX * m_targetVariation*2; + qreal theta = atan2(targetY, targetX); + qreal mag = m_magnitude + rand()/(float)RAND_MAX * m_magnitudeVariation * 2 - m_magnitudeVariation; + if (m_proportionalMagnitude) + mag *= sqrt(targetX * targetX + targetY * targetY); + ret.setX(mag * cos(theta)); + ret.setY(mag * sin(theta)); + return ret; +} + +QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquicktargetdirection_p.h qt5-declarative-0.1~git20120423/src/particles/qquicktargetdirection_p.h --- qt5-declarative-0.1~git20120402/src/particles/qquicktargetdirection_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquicktargetdirection_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,189 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DIRECTEDVECTOR_H +#define DIRECTEDVECTOR_H +#include "qquickdirection_p.h" +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QQuickItem; +class QQuickTargetDirection : public QQuickDirection +{ + Q_OBJECT + Q_PROPERTY(qreal targetX READ targetX WRITE setTargetX NOTIFY targetXChanged) + Q_PROPERTY(qreal targetY READ targetY WRITE setTargetY NOTIFY targetYChanged) + //If targetItem is set, X/Y are ignored. Aims at middle of item, use variation for variation + Q_PROPERTY(QQuickItem* targetItem READ targetItem WRITE setTargetItem NOTIFY targetItemChanged) + + Q_PROPERTY(qreal targetVariation READ targetVariation WRITE setTargetVariation NOTIFY targetVariationChanged) + + //TODO: An enum would be better + Q_PROPERTY(bool proportionalMagnitude READ proportionalMagnitude WRITE setProportionalMagnitude NOTIFY proprotionalMagnitudeChanged) + Q_PROPERTY(qreal magnitude READ magnitude WRITE setMagnitude NOTIFY magnitudeChanged) + Q_PROPERTY(qreal magnitudeVariation READ magnitudeVariation WRITE setMagnitudeVariation NOTIFY magnitudeVariationChanged) + +public: + explicit QQuickTargetDirection(QObject *parent = 0); + virtual const QPointF sample(const QPointF &from); + + qreal targetX() const + { + return m_targetX; + } + + qreal targetY() const + { + return m_targetY; + } + + qreal targetVariation() const + { + return m_targetVariation; + } + + qreal magnitude() const + { + return m_magnitude; + } + + bool proportionalMagnitude() const + { + return m_proportionalMagnitude; + } + + qreal magnitudeVariation() const + { + return m_magnitudeVariation; + } + + QQuickItem* targetItem() const + { + return m_targetItem; + } + +signals: + + void targetXChanged(qreal arg); + + void targetYChanged(qreal arg); + + void targetVariationChanged(qreal arg); + + void magnitudeChanged(qreal arg); + + void proprotionalMagnitudeChanged(bool arg); + + void magnitudeVariationChanged(qreal arg); + + void targetItemChanged(QQuickItem* arg); + +public slots: + void setTargetX(qreal arg) + { + if (m_targetX != arg) { + m_targetX = arg; + emit targetXChanged(arg); + } + } + + void setTargetY(qreal arg) + { + if (m_targetY != arg) { + m_targetY = arg; + emit targetYChanged(arg); + } + } + + void setTargetVariation(qreal arg) + { + if (m_targetVariation != arg) { + m_targetVariation = arg; + emit targetVariationChanged(arg); + } + } + + void setMagnitude(qreal arg) + { + if (m_magnitude != arg) { + m_magnitude = arg; + emit magnitudeChanged(arg); + } + } + + void setProportionalMagnitude(bool arg) + { + if (m_proportionalMagnitude != arg) { + m_proportionalMagnitude = arg; + emit proprotionalMagnitudeChanged(arg); + } + } + + void setMagnitudeVariation(qreal arg) + { + if (m_magnitudeVariation != arg) { + m_magnitudeVariation = arg; + emit magnitudeVariationChanged(arg); + } + } + + void setTargetItem(QQuickItem* arg) + { + if (m_targetItem != arg) { + m_targetItem = arg; + emit targetItemChanged(arg); + } + } + +private: + qreal m_targetX; + qreal m_targetY; + qreal m_targetVariation; + bool m_proportionalMagnitude; + qreal m_magnitude; + qreal m_magnitudeVariation; + QQuickItem *m_targetItem; +}; + +QT_END_NAMESPACE +QT_END_HEADER +#endif // DIRECTEDVECTOR_H diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquicktrailemitter.cpp qt5-declarative-0.1~git20120423/src/particles/qquicktrailemitter.cpp --- qt5-declarative-0.1~git20120402/src/particles/qquicktrailemitter.cpp 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquicktrailemitter.cpp 2012-04-23 11:44:59.000000000 +0000 @@ -0,0 +1,285 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquicktrailemitter_p.h" +#include +#include +QT_BEGIN_NAMESPACE + +/*! + \qmlclass TrailEmitter QQuickTrailEmitter + \inqmlmodule QtQuick.Particles 2 + \inherits QQuickParticleEmitter + \brief The TrailEmitter element allows you to emit logical particles from other logical particles. + + This element emits logical particles into the ParticleSystem, with the + starting positions based on those of other logical particles. +*/ +QQuickTrailEmitter::QQuickTrailEmitter(QQuickItem *parent) : + QQuickParticleEmitter(parent) + , m_particlesPerParticlePerSecond(0) + , m_lastTimeStamp(0) + , m_emitterXVariation(0) + , m_emitterYVariation(0) + , m_followCount(0) + , m_emissionExtruder(0) + , m_defaultEmissionExtruder(new QQuickParticleExtruder(this)) +{ + //TODO: If followed increased their size + connect(this, SIGNAL(followChanged(QString)), + this, SLOT(recalcParticlesPerSecond())); + connect(this, SIGNAL(particleDurationChanged(int)), + this, SLOT(recalcParticlesPerSecond())); + connect(this, SIGNAL(particlesPerParticlePerSecondChanged(int)), + this, SLOT(recalcParticlesPerSecond())); +} + +/*! + \qmlproperty string QtQuick.Particles2::TrailEmitter::follow + + The type of logical particle which this is emitting from. +*/ +/*! + \qmlproperty qreal QtQuick.Particles2::TrailEmitter::speedFromMovement + + If this value is non-zero, then any movement of the emitter will provide additional + starting velocity to the particles based on the movement. The additional vector will be the + same angle as the emitter's movement, with a magnitude that is the magnitude of the emitters + movement multiplied by speedFromMovement. + + Default value is 0. +*/ +/*! + \qmlproperty Shape QtQuick.Particles2::TrailEmitter::emitShape + + As the area of a TrailEmitter is the area it follows, a separate shape can be provided + to be the shape it emits out of. This shape has width and height specified by emitWidth + and emitHeight, and is centered on the followed particle's position. + + The default shape is a filled Rectangle. +*/ +/*! + \qmlproperty real QtQuick.Particles2::TrailEmitter::emitWidth + + The width in pixels the emitShape is scaled to. If set to TrailEmitter.ParticleSize, + the width will be the current size of the particle being followed. + + Default is 0. +*/ +/*! + \qmlproperty real QtQuick.Particles2::TrailEmitter::emitHeight + + The height in pixels the emitShape is scaled to. If set to TrailEmitter.ParticleSize, + the height will be the current size of the particle being followed. + + Default is 0. +*/ +/*! + \qmlproperty real QtQuick.Particles2::TrailEmitter::emitRatePerParticle +*/ +/*! + \qmlsignal QtQuick.Particles2::TrailEmitter::emitFollowParticles(Array particles, real followed) + + This handler is called when particles are emitted from the \a followed particle. \a particles contains an array of particle objects which can be directly manipulated. + + If you use this signal handler, emitParticles will not be emitted. + +*/ + +bool QQuickTrailEmitter::isEmitFollowConnected() +{ + static int idx = QObjectPrivate::get(this)->signalIndex("emitFollowParticles(QQmlV8Handle,QQmlV8Handle)"); + return QObjectPrivate::get(this)->isSignalConnected(idx); +} + +void QQuickTrailEmitter::recalcParticlesPerSecond(){ + if (!m_system) + return; + m_followCount = m_system->groupData[m_system->groupIds[m_follow]]->size(); + if (!m_followCount){ + setParticlesPerSecond(1);//XXX: Fix this horrendous hack, needed so they aren't turned off from start (causes crashes - test that when gone you don't crash with 0 PPPS) + }else{ + setParticlesPerSecond(m_particlesPerParticlePerSecond * m_followCount); + m_lastEmission.resize(m_followCount); + m_lastEmission.fill(m_lastTimeStamp); + } +} + +void QQuickTrailEmitter::reset() +{ + m_followCount = 0; +} + +void QQuickTrailEmitter::emitWindow(int timeStamp) +{ + if (m_system == 0) + return; + if (!m_enabled && !m_pulseLeft && m_burstQueue.isEmpty()) + return; + if (m_followCount != m_system->groupData[m_system->groupIds[m_follow]]->size()){ + qreal oldPPS = m_particlesPerSecond; + recalcParticlesPerSecond(); + if (m_particlesPerSecond != oldPPS) + return;//system may need to update + } + + if (m_pulseLeft){ + m_pulseLeft -= timeStamp - m_lastTimeStamp * 1000.; + if (m_pulseLeft < 0){ + timeStamp += m_pulseLeft; + m_pulseLeft = 0; + } + } + + //TODO: Implement startTime and speedFromMovement + qreal time = timeStamp / 1000.; + qreal particleRatio = 1. / m_particlesPerParticlePerSecond; + qreal pt; + qreal maxLife = (m_particleDuration + m_particleDurationVariation)/1000.0; + + //Have to map it into this system, because particlesystem automaps it back + QPointF offset = m_system->mapFromItem(this, QPointF(0, 0)); + qreal sizeAtEnd = m_particleEndSize >= 0 ? m_particleEndSize : m_particleSize; + + int gId = m_system->groupIds[m_follow]; + int gId2 = m_system->groupIds[m_group]; + for (int i=0; igroupData[gId]->data.count(); i++) { + QQuickParticleData *d = m_system->groupData[gId]->data[i]; + if (!d->stillAlive()){ + m_lastEmission[i] = time; //Should only start emitting when it returns to life + continue; + } + pt = m_lastEmission[i]; + if (pt < d->t) + pt = d->t; + if (pt + maxLife < time)//We missed so much, that we should skip emiting particles that are dead by now + pt = time - maxLife; + + if ((width() || height()) && !effectiveExtruder()->contains(QRectF(offset.x(), offset.y(), width(), height()),QPointF(d->curX(), d->curY()))){ + m_lastEmission[d->index] = time;//jump over this time period without emitting, because it's outside + continue; + } + + QList toEmit; + + while (pt < time || !m_burstQueue.isEmpty()){ + QQuickParticleData* datum = m_system->newDatum(gId2, !m_overwrite); + if (datum){//else, skip this emission + datum->e = this;//###useful? + + // Particle timestamp + datum->t = pt; + datum->lifeSpan = + (m_particleDuration + + ((rand() % ((m_particleDurationVariation*2) + 1)) - m_particleDurationVariation)) + / 1000.0; + + // Particle position + // Note that burst location doesn't get used for follow emitter + qreal followT = pt - d->t; + qreal followT2 = followT * followT * 0.5; + qreal eW = m_emitterXVariation < 0 ? d->curSize() : m_emitterXVariation; + qreal eH = m_emitterYVariation < 0 ? d->curSize() : m_emitterYVariation; + //Subtract offset, because PS expects this in emitter coordinates + QRectF boundsRect(d->x - offset.x() + d->vx * followT + d->ax * followT2 - eW/2, + d->y - offset.y() + d->vy * followT + d->ay * followT2 - eH/2, + eW, eH); + + QQuickParticleExtruder* effectiveEmissionExtruder = m_emissionExtruder ? m_emissionExtruder : m_defaultEmissionExtruder; + const QPointF &newPos = effectiveEmissionExtruder->extrude(boundsRect); + datum->x = newPos.x(); + datum->y = newPos.y(); + + // Particle speed + const QPointF &speed = m_speed->sample(newPos); + datum->vx = speed.x() + + m_speed_from_movement * d->vx; + datum->vy = speed.y() + + m_speed_from_movement * d->vy; + + // Particle acceleration + const QPointF &accel = m_acceleration->sample(newPos); + datum->ax = accel.x(); + datum->ay = accel.y(); + + // Particle size + float sizeVariation = -m_particleSizeVariation + + rand() / float(RAND_MAX) * m_particleSizeVariation * 2; + + float size = qMax((qreal)0.0, m_particleSize + sizeVariation); + float endSize = qMax((qreal)0.0, sizeAtEnd + sizeVariation); + + datum->size = size * float(m_enabled); + datum->endSize = endSize * float(m_enabled); + + toEmit << datum; + + m_system->emitParticle(datum); + } + if (!m_burstQueue.isEmpty()){ + m_burstQueue.first().first--; + if (m_burstQueue.first().first <= 0) + m_burstQueue.pop_front(); + }else{ + pt += particleRatio; + } + } + + if (isEmitConnected() || isEmitFollowConnected()) { + v8::HandleScope handle_scope; + v8::Context::Scope scope(QQmlEnginePrivate::getV8Engine(qmlEngine(this))->context()); + v8::Handle array = v8::Array::New(toEmit.size()); + for (int i=0; iSet(i, toEmit[i]->v8Value().toHandle()); + + if (isEmitFollowConnected()) + emitFollowParticles(QQmlV8Handle::fromHandle(array), d->v8Value());//A chance for many arbitrary JS changes + else if (isEmitConnected()) + emitParticles(QQmlV8Handle::fromHandle(array));//A chance for arbitrary JS changes + } + foreach (QQuickParticleData* d, toEmit) + m_system->emitParticle(d); + m_lastEmission[d->index] = pt; + } + + m_lastTimeStamp = time; +} +QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquicktrailemitter_p.h qt5-declarative-0.1~git20120423/src/particles/qquicktrailemitter_p.h --- qt5-declarative-0.1~git20120402/src/particles/qquicktrailemitter_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquicktrailemitter_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,168 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef FOLLOWEMITTER_H +#define FOLLOWEMITTER_H +#include "qquickparticleemitter_p.h" +#include "qquickparticleaffector_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QQuickTrailEmitter : public QQuickParticleEmitter +{ + Q_OBJECT + Q_PROPERTY(QString follow READ follow WRITE setFollow NOTIFY followChanged) + Q_PROPERTY(int emitRatePerParticle READ particlesPerParticlePerSecond WRITE setParticlesPerParticlePerSecond NOTIFY particlesPerParticlePerSecondChanged) + + Q_PROPERTY(QQuickParticleExtruder* emitShape READ emissonShape WRITE setEmissionShape NOTIFY emissionShapeChanged) + Q_PROPERTY(qreal emitHeight READ emitterYVariation WRITE setEmitterYVariation NOTIFY emitterYVariationChanged) + Q_PROPERTY(qreal emitWidth READ emitterXVariation WRITE setEmitterXVariation NOTIFY emitterXVariationChanged) + + Q_ENUMS(EmitSize) +public: + enum EmitSize { + ParticleSize = -2//Anything less than 0 will do + }; + explicit QQuickTrailEmitter(QQuickItem *parent = 0); + virtual void emitWindow(int timeStamp); + virtual void reset(); + + int particlesPerParticlePerSecond() const + { + return m_particlesPerParticlePerSecond; + } + + qreal emitterXVariation() const + { + return m_emitterXVariation; + } + + qreal emitterYVariation() const + { + return m_emitterYVariation; + } + + QString follow() const + { + return m_follow; + } + + QQuickParticleExtruder* emissonShape() const + { + return m_emissionExtruder; + } + +signals: + void emitFollowParticles(QQmlV8Handle particles, QQmlV8Handle followed); + + void particlesPerParticlePerSecondChanged(int arg); + + void emitterXVariationChanged(qreal arg); + + void emitterYVariationChanged(qreal arg); + + void followChanged(QString arg); + + void emissionShapeChanged(QQuickParticleExtruder* arg); + +public slots: + + void setParticlesPerParticlePerSecond(int arg) + { + if (m_particlesPerParticlePerSecond != arg) { + m_particlesPerParticlePerSecond = arg; + emit particlesPerParticlePerSecondChanged(arg); + } + } + void setEmitterXVariation(qreal arg) + { + if (m_emitterXVariation != arg) { + m_emitterXVariation = arg; + emit emitterXVariationChanged(arg); + } + } + + void setEmitterYVariation(qreal arg) + { + if (m_emitterYVariation != arg) { + m_emitterYVariation = arg; + emit emitterYVariationChanged(arg); + } + } + + void setFollow(QString arg) + { + if (m_follow != arg) { + m_follow = arg; + emit followChanged(arg); + } + } + + void setEmissionShape(QQuickParticleExtruder* arg) + { + if (m_emissionExtruder != arg) { + m_emissionExtruder = arg; + emit emissionShapeChanged(arg); + } + } + +private slots: + void recalcParticlesPerSecond(); + +private: + QSet m_pending; + QVector m_lastEmission; + int m_particlesPerParticlePerSecond; + qreal m_lastTimeStamp; + qreal m_emitterXVariation; + qreal m_emitterYVariation; + QString m_follow; + int m_followCount; + QQuickParticleExtruder* m_emissionExtruder; + QQuickParticleExtruder* m_defaultEmissionExtruder; + bool isEmitFollowConnected(); +}; + +QT_END_NAMESPACE +QT_END_HEADER +#endif // FOLLOWEMITTER_H diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquickturbulence.cpp qt5-declarative-0.1~git20120423/src/particles/qquickturbulence.cpp --- qt5-declarative-0.1~git20120402/src/particles/qquickturbulence.cpp 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquickturbulence.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,205 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickturbulence_p.h" +#include "qquickparticlepainter_p.h"//TODO: Why was this needed again? +#include +#include +#include +QT_BEGIN_NAMESPACE + +/*! + \qmlclass Turbulence QQuickTurbulenceAffector + \inqmlmodule QtQuick.Particles 2 + \inherits Affector + \brief Turbulence provides fluid like forces based on a noise image. + + The Turbulence Element scales the noise source over the area it affects, + and uses the curl of that source to generate force vectors. + + Turbulence requires a fixed size. Unlike other affectors, a 0x0 Turbulence element + will affect no particles. + + The source should be relatively smooth black and white noise, such as perlin noise. +*/ +/*! + \qmlproperty real QtQuick.Particles2::Turbulence::strength + + The magnitude of the velocity vector at any point varies between zero and + the square root of two. It will then be multiplied by strength to get the + velocity per second for the particles affected by the turbulence. +*/ +/*! + \qmlproperty url QtQuick.Particles2::Turbulence::noiseSource + + The source image to generate the turbulence from. It will be scaled to the size of the element, + so equal or larger sizes will give better results. Tweaking this image is the only way to tweak + behavior such as where vortices are or how many exist. + + The source should be a relatively smooth black and white noise image, such as perlin noise. + A default image will be used if none is provided. +*/ + +QQuickTurbulenceAffector::QQuickTurbulenceAffector(QQuickItem *parent) : + QQuickParticleAffector(parent), + m_strength(10), m_lastT(0), m_gridSize(0), m_field(0), m_vectorField(0), m_inited(false) +{ +} + +void QQuickTurbulenceAffector::geometryChanged(const QRectF &, const QRectF &) +{ + initializeGrid(); +} + +QQuickTurbulenceAffector::~QQuickTurbulenceAffector() +{ + if (m_field) { + for (int i=0; i= m_gridSize) + x = m_gridSize - 1; + if (y < 0) + y = 0; + if (y >= m_gridSize) + y = m_gridSize - 1; + return m_field[x][y]; +} + +void QQuickTurbulenceAffector::ensureInit() +{ + if (m_inited) + return; + m_inited = true; + initializeGrid(); +} + +void QQuickTurbulenceAffector::affectSystem(qreal dt) +{ + if (!m_system || !m_enabled) + return; + ensureInit(); + if (!m_gridSize) + return; + + updateOffsets();//### Needed if an ancestor is transformed. + + QRect boundsRect(0,0,m_gridSize,m_gridSize); + foreach (QQuickParticleGroupData *gd, m_system->groupData){ + if (!activeGroup(m_system->groupData.key(gd))) + continue; + foreach (QQuickParticleData *d, gd->data){ + if (!shouldAffect(d)) + continue; + QPoint pos = (QPointF(d->curX(), d->curY()) - m_offset).toPoint(); + if (!boundsRect.contains(pos,true))//Need to redo bounds checking due to quantization. + continue; + qreal fx = 0.0; + qreal fy = 0.0; + fx += m_vectorField[pos.x()][pos.y()].x() * m_strength; + fy += m_vectorField[pos.x()][pos.y()].y() * m_strength; + if (fx || fy){ + d->setInstantaneousVX(d->curVX()+ fx * dt); + d->setInstantaneousVY(d->curVY()+ fy * dt); + postAffect(d); + } + } + } +} + +QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquickturbulence_p.h qt5-declarative-0.1~git20120423/src/particles/qquickturbulence_p.h --- qt5-declarative-0.1~git20120402/src/particles/qquickturbulence_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquickturbulence_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,116 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef TURBULENCEAFFECTOR_H +#define TURBULENCEAFFECTOR_H +#include "qquickparticleaffector_p.h" +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QQuickParticlePainter; + +class QQuickTurbulenceAffector : public QQuickParticleAffector +{ + Q_OBJECT + Q_PROPERTY(qreal strength READ strength WRITE setStrength NOTIFY strengthChanged) + Q_PROPERTY(QUrl noiseSource READ noiseSource WRITE setNoiseSource NOTIFY noiseSourceChanged) + public: + explicit QQuickTurbulenceAffector(QQuickItem *parent = 0); + ~QQuickTurbulenceAffector(); + virtual void affectSystem(qreal dt); + + qreal strength() const + { + return m_strength; + } + + QUrl noiseSource() const + { + return m_noiseSource; + } +signals: + + void strengthChanged(qreal arg); + + void noiseSourceChanged(QUrl arg); + +public slots: + + void setStrength(qreal arg) + { + if (m_strength != arg) { + m_strength = arg; + emit strengthChanged(arg); + } + } + + void setNoiseSource(QUrl arg) + { + if (m_noiseSource != arg) { + m_noiseSource = arg; + emit noiseSourceChanged(arg); + initializeGrid(); + } + } + +protected: + virtual void geometryChanged(const QRectF &newGeometry, + const QRectF &oldGeometry); +private: + void ensureInit(); + void mapUpdate(); + void initializeGrid(); + qreal boundsRespectingField(int x, int y); + qreal m_strength; + qreal m_lastT; + int m_gridSize; + qreal** m_field; + QPointF** m_vectorField; + bool m_inited; + QUrl m_noiseSource; +}; + +QT_END_NAMESPACE +QT_END_HEADER +#endif // TURBULENCEAFFECTOR_H diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquickv8particledata.cpp qt5-declarative-0.1~git20120423/src/particles/qquickv8particledata.cpp --- qt5-declarative-0.1~git20120402/src/particles/qquickv8particledata.cpp 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquickv8particledata.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,505 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickv8particledata_p.h" +#include "qquickparticlesystem_p.h"//for QQuickParticleData +#include + +QT_BEGIN_NAMESPACE + +/*! + \qmlclass Particle + \inqmlmodule QtQuick.Particles 2 + \brief Particle elements can be manipulated in custom emitters and affectors. + + Particle elements are always managed internally by the ParticleSystem and cannot be created in QML. + However, sometimes they are exposed via signals so as to allow arbitrary changes to the particle state +*/ + +/*! + \qmlproperty real QtQuick.Particles2::Particle::initialX + The x coordinate of the particle at the beginning of its lifetime. + + The method of simulation prefers to have the initial values changed, rather + than determining and changing the value at a given time. Change initial + values in CustomEmitters instead of the current values. +*/ + +/*! + \qmlproperty real QtQuick.Particles2::Particle::initialVX + The x velocity of the particle at the beginning of its lifetime. + + The method of simulation prefers to have the initial values changed, rather + than determining and changing the value at a given time. Change initial + values in CustomEmitters instead of the current values. +*/ + +/*! + \qmlproperty real QtQuick.Particles2::Particle::initialAX + The x acceleration of the particle at the beginning of its lifetime. + + The method of simulation prefers to have the initial values changed, rather + than determining and changing the value at a given time. Change initial + values in CustomEmitters instead of the current values. +*/ + +/*! + \qmlproperty real QtQuick.Particles2::Particle::initialY + The y coordinate of the particle at the beginning of its lifetime. + + The method of simulation prefers to have the initial values changed, rather + than determining and changing the value at a given time. Change initial + values in CustomEmitters instead of the current values. +*/ + +/*! + \qmlproperty real QtQuick.Particles2::Particle::initialVY + The y velocity of the particle at the beginning of its lifetime. + + The method of simulation prefers to have the initial values changed, rather + than determining and changing the value at a given time. Change initial + values in CustomEmitters instead of the current values. +*/ + +/*! + \qmlproperty real QtQuick.Particles2::Particle::initialAY + The y acceleration of the particle at the beginning of its lifetime. + + The method of simulation prefers to have the initial values changed, rather + than determining and changing the value at a given time. Change initial + values in CustomEmitters instead of the current values. +*/ + +/*! + \qmlproperty real QtQuick.Particles2::Particle::x + The current x coordinate of the particle. +*/ + +/*! + \qmlproperty real QtQuick.Particles2::Particle::vx + The current x velocity of the particle. +*/ + +/*! + \qmlproperty real QtQuick.Particles2::Particle::ax + The current x acceleration of the particle. +*/ + +/*! + \qmlproperty real QtQuick.Particles2::Particle::y + The current y coordinate of the particle. +*/ + +/*! + \qmlproperty real QtQuick.Particles2::Particle::vy + The current y velocity of the particle. +*/ + +/*! + \qmlproperty real QtQuick.Particles2::Particle::ay + The current y acceleration of the particle. +*/ + +/*! + \qmlproperty real QtQuick.Particles2::Particle::t + The time, in seconds since the beginning of the simulation, that the particle was born. +*/ + + +/*! + \qmlproperty real QtQuick.Particles2::Particle::startSize + The size in pixels that the particle image is at the start + of its life. +*/ + + +/*! + \qmlproperty real QtQuick.Particles2::Particle::endSize + The size in pixels that the particle image is at the end + of its life. If this value is less than 0, then it is + disregarded and the particle will have its startSize for the + entire lifetime. +*/ + +/*! + \qmlproperty real QtQuick.Particles2::Particle::lifeSpan + The time in seconds that the particle will live for. +*/ + +/*! + \qmlproperty real QtQuick.Particles2::Particle::rotation + Degrees clockwise that the particle image is rotated at + the beginning of its life. +*/ + +/*! + \qmlproperty real QtQuick.Particles2::Particle::rotationSpeed + Degrees clockwise per second that the particle image is rotated at while alive. +*/ +/*! + \qmlproperty bool QtQuick.Particles2::Particle::autoRotate + If autoRotate is true, then the particle's rotation will be + set so that it faces the direction of travel, plus any + rotation from the rotation or rotationSpeed properties. +*/ + +/*! + \qmlproperty bool QtQuick.Particles2::Particle::update + + Inside an Affector, the changes made to the particle will only be + applied if update is set to true. +*/ +/*! + \qmlproperty real QtQuick.Particles2::Particle::xDeformationVectorX + + The x component of the deformation vector along the X axis. ImageParticle + can draw particles across non-square shapes. It will draw the texture rectangle + across the parallelogram drawn with the x and y deformation vectors. +*/ + +/*! + \qmlproperty real QtQuick.Particles2::Particle::yDeformationVectorX + + The y component of the deformation vector along the X axis. ImageParticle + can draw particles across non-square shapes. It will draw the texture rectangle + across the parallelogram drawn with the x and y deformation vectors. +*/ + +/*! + \qmlproperty real QtQuick.Particles2::Particle::xDeformationVectorY + + The x component of the deformation vector along the X axis. ImageParticle + can draw particles across non-square shapes. It will draw the texture rectangle + across the parallelogram drawn with the x and y deformation vectors. +*/ + +/*! + \qmlproperty real QtQuick.Particles2::Particle::yDeformationVectorY + + The y component of the deformation vector along the Y axis. ImageParticle + can draw particles across non-square shapes. It will draw the texture rectangle + across the parallelogram drawn with the x and y deformation vectors. +*/ + +/*! + \qmlproperty real QtQuick.Particles2::Particle::red + + ImageParticle can draw colorized particles. When it does so, red is used + as the red channel of the color applied to the source image. + + Values are from 0.0 to 1.0. +*/ + +/*! + \qmlproperty real QtQuick.Particles2::Particle::green + + ImageParticle can draw colorized particles. When it does so, green is used + as the green channel of the color applied to the source image. + + Values are from 0.0 to 1.0. +*/ + +/*! + \qmlproperty real QtQuick.Particles2::Particle::blue + + ImageParticle can draw colorized particles. When it does so, blue is used + as the blue channel of the color applied to the source image. + + Values are from 0.0 to 1.0. +*/ + +/*! + \qmlproperty real QtQuick.Particles2::Particle::alpha + + ImageParticle can draw colorized particles. When it does so, alpha is used + as the alpha channel of the color applied to the source image. + + Values are from 0.0 to 1.0. +*/ +/*! + \qmlmethod real QtQuick.Particles2::Particle::lifeLeft + The time in seconds that the particle has left to live at + the current point in time. +*/ +/*! + \qmlmethod real QtQuick.Particles2::Particle::currentSize + The currentSize of the particle, interpolating between startSize and endSize based on the currentTime. +*/ + + + +//### Particle data handles are not locked to within certain scopes like QQuickContext2D, but there's no way to reload either... +class QV8ParticleDataResource : public QV8ObjectResource +{ + V8_RESOURCE_TYPE(ParticleDataType) +public: + QV8ParticleDataResource(QV8Engine *e) : QV8ObjectResource(e) {} + QQuickParticleData* datum;//TODO: Guard needed? +}; + +class QV8ParticleDataDeletable : public QV8Engine::Deletable +{ +public: + QV8ParticleDataDeletable(QV8Engine *engine); + ~QV8ParticleDataDeletable(); + + v8::Persistent constructor; +}; + +static v8::Handle particleData_discard(const v8::Arguments &args) +{ + QV8ParticleDataResource *r = v8_resource_cast(args.This()); + + if (!r || !r->datum) + V8THROW_ERROR("Not a valid ParticleData object"); + + r->datum->lifeSpan = 0; //Don't kill(), because it could still be in the middle of being created + return v8::Undefined(); +} + +static v8::Handle particleData_lifeLeft(const v8::Arguments &args) +{ + QV8ParticleDataResource *r = v8_resource_cast(args.This()); + if (!r || !r->datum) + V8THROW_ERROR("Not a valid ParticleData object"); + + return v8::Number::New(r->datum->lifeLeft()); +} + +static v8::Handle particleData_curSize(const v8::Arguments &args) +{ + QV8ParticleDataResource *r = v8_resource_cast(args.This()); + if (!r || !r->datum) + V8THROW_ERROR("Not a valid ParticleData object"); + + return v8::Number::New(r->datum->curSize()); +} +#define COLOR_GETTER_AND_SETTER(VAR, NAME) static v8::Handle particleData_get_ ## NAME (v8::Local, const v8::AccessorInfo &info) \ +{ \ + QV8ParticleDataResource *r = v8_resource_cast(info.This()); \ + if (!r || !r->datum) \ + V8THROW_ERROR("Not a valid ParticleData object"); \ +\ + return v8::Number::New((r->datum->color. VAR )/255.0);\ +}\ +\ +static void particleData_set_ ## NAME (v8::Local, v8::Local value, const v8::AccessorInfo &info)\ +{\ + QV8ParticleDataResource *r = v8_resource_cast(info.This());\ + if (!r || !r->datum)\ + V8THROW_ERROR_SETTER("Not a valid ParticleData object");\ +\ + r->datum->color. VAR = qMin(255, qMax(0, (int)floor(value->NumberValue() * 255.0)));\ +} + + +#define SEMIBOOL_GETTER_AND_SETTER(VARIABLE) static v8::Handle particleData_get_ ## VARIABLE (v8::Local, const v8::AccessorInfo &info) \ +{ \ + QV8ParticleDataResource *r = v8_resource_cast(info.This()); \ + if (!r || !r->datum) \ + V8THROW_ERROR("Not a valid ParticleData object"); \ +\ + return v8::Boolean::New(r->datum-> VARIABLE);\ +}\ +\ +static void particleData_set_ ## VARIABLE (v8::Local, v8::Local value, const v8::AccessorInfo &info)\ +{\ + QV8ParticleDataResource *r = v8_resource_cast(info.This());\ + if (!r || !r->datum)\ + V8THROW_ERROR_SETTER("Not a valid ParticleData object");\ +\ + r->datum-> VARIABLE = value->BooleanValue() ? 1.0 : 0.0;\ +} + +#define FLOAT_GETTER_AND_SETTER(VARIABLE) static v8::Handle particleData_get_ ## VARIABLE (v8::Local, const v8::AccessorInfo &info) \ +{ \ + QV8ParticleDataResource *r = v8_resource_cast(info.This()); \ + if (!r || !r->datum) \ + V8THROW_ERROR("Not a valid ParticleData object"); \ +\ + return v8::Number::New(r->datum-> VARIABLE);\ +}\ +\ +static void particleData_set_ ## VARIABLE (v8::Local, v8::Local value, const v8::AccessorInfo &info)\ +{\ + QV8ParticleDataResource *r = v8_resource_cast(info.This());\ + if (!r || !r->datum)\ + V8THROW_ERROR_SETTER("Not a valid ParticleData object");\ +\ + r->datum-> VARIABLE = value->NumberValue();\ +} + +#define FAKE_FLOAT_GETTER_AND_SETTER(VARIABLE, GETTER, SETTER) static v8::Handle particleData_get_ ## VARIABLE (v8::Local, const v8::AccessorInfo &info) \ +{ \ + QV8ParticleDataResource *r = v8_resource_cast(info.This()); \ + if (!r || !r->datum) \ + V8THROW_ERROR("Not a valid ParticleData object"); \ +\ + return v8::Number::New(r->datum-> GETTER ());\ +}\ +\ +static void particleData_set_ ## VARIABLE (v8::Local, v8::Local value, const v8::AccessorInfo &info)\ +{\ + QV8ParticleDataResource *r = v8_resource_cast(info.This());\ + if (!r || !r->datum)\ + V8THROW_ERROR_SETTER("Not a valid ParticleData object");\ +\ + r->datum-> SETTER ( value->NumberValue() );\ +} + +#define REGISTER_ACCESSOR(FT, ENGINE, VARIABLE, NAME) FT ->PrototypeTemplate()->SetAccessor( v8::String::New( #NAME ), particleData_get_ ## VARIABLE , particleData_set_ ## VARIABLE , v8::External::Wrap(ENGINE)) + +COLOR_GETTER_AND_SETTER(r, red) +COLOR_GETTER_AND_SETTER(g, green) +COLOR_GETTER_AND_SETTER(b, blue) +COLOR_GETTER_AND_SETTER(a, alpha) +SEMIBOOL_GETTER_AND_SETTER(autoRotate) +SEMIBOOL_GETTER_AND_SETTER(update) +FLOAT_GETTER_AND_SETTER(x) +FLOAT_GETTER_AND_SETTER(y) +FLOAT_GETTER_AND_SETTER(t) +FLOAT_GETTER_AND_SETTER(lifeSpan) +FLOAT_GETTER_AND_SETTER(size) +FLOAT_GETTER_AND_SETTER(endSize) +FLOAT_GETTER_AND_SETTER(vx) +FLOAT_GETTER_AND_SETTER(vy) +FLOAT_GETTER_AND_SETTER(ax) +FLOAT_GETTER_AND_SETTER(ay) +FLOAT_GETTER_AND_SETTER(xx) +FLOAT_GETTER_AND_SETTER(xy) +FLOAT_GETTER_AND_SETTER(yx) +FLOAT_GETTER_AND_SETTER(yy) +FLOAT_GETTER_AND_SETTER(rotation) +FLOAT_GETTER_AND_SETTER(rotationSpeed) +FLOAT_GETTER_AND_SETTER(animIdx) +FLOAT_GETTER_AND_SETTER(frameDuration) +FLOAT_GETTER_AND_SETTER(frameAt) +FLOAT_GETTER_AND_SETTER(frameCount) +FLOAT_GETTER_AND_SETTER(animT) +FLOAT_GETTER_AND_SETTER(r) +FAKE_FLOAT_GETTER_AND_SETTER(curX, curX, setInstantaneousX) +FAKE_FLOAT_GETTER_AND_SETTER(curVX, curVX, setInstantaneousVX) +FAKE_FLOAT_GETTER_AND_SETTER(curAX, curAX, setInstantaneousAX) +FAKE_FLOAT_GETTER_AND_SETTER(curY, curY, setInstantaneousY) +FAKE_FLOAT_GETTER_AND_SETTER(curVY, curVY, setInstantaneousVY) +FAKE_FLOAT_GETTER_AND_SETTER(curAY, curAY, setInstantaneousAY) + +QV8ParticleDataDeletable::QV8ParticleDataDeletable(QV8Engine *engine) +{ + v8::HandleScope handle_scope; + v8::Context::Scope scope(engine->context()); + + v8::Local ft = v8::FunctionTemplate::New(); + ft->InstanceTemplate()->SetHasExternalResource(true); + ft->PrototypeTemplate()->Set(v8::String::New("discard"), V8FUNCTION(particleData_discard, engine)); + ft->PrototypeTemplate()->Set(v8::String::New("lifeLeft"), V8FUNCTION(particleData_lifeLeft, engine)); + ft->PrototypeTemplate()->Set(v8::String::New("currentSize"), V8FUNCTION(particleData_curSize, engine)); + REGISTER_ACCESSOR(ft, engine, x, initialX); + REGISTER_ACCESSOR(ft, engine, y, initialY); + REGISTER_ACCESSOR(ft, engine, t, t); + REGISTER_ACCESSOR(ft, engine, lifeSpan, lifeSpan); + REGISTER_ACCESSOR(ft, engine, size, startSize); + REGISTER_ACCESSOR(ft, engine, endSize, endSize); + REGISTER_ACCESSOR(ft, engine, vx, initialVX); + REGISTER_ACCESSOR(ft, engine, vy, initialVY); + REGISTER_ACCESSOR(ft, engine, ax, initialAX); + REGISTER_ACCESSOR(ft, engine, ay, initialAY); + REGISTER_ACCESSOR(ft, engine, xx, xDeformationVectorX); + REGISTER_ACCESSOR(ft, engine, xy, xDeformationVectorY); + REGISTER_ACCESSOR(ft, engine, yx, yDeformationVectorX); + REGISTER_ACCESSOR(ft, engine, yy, yDeformationVectorY); + REGISTER_ACCESSOR(ft, engine, rotation, rotation); + REGISTER_ACCESSOR(ft, engine, rotationSpeed, rotationSpeed); + REGISTER_ACCESSOR(ft, engine, autoRotate, autoRotate); + REGISTER_ACCESSOR(ft, engine, animIdx, animationIndex); + REGISTER_ACCESSOR(ft, engine, frameDuration, frameDuration); + REGISTER_ACCESSOR(ft, engine, frameAt, frameAt); + REGISTER_ACCESSOR(ft, engine, frameCount, frameCount); + REGISTER_ACCESSOR(ft, engine, animT, animationT); + REGISTER_ACCESSOR(ft, engine, r, r); + REGISTER_ACCESSOR(ft, engine, update, update); + REGISTER_ACCESSOR(ft, engine, curX, x); + REGISTER_ACCESSOR(ft, engine, curVX, vx); + REGISTER_ACCESSOR(ft, engine, curAX, ax); + REGISTER_ACCESSOR(ft, engine, curY, y); + REGISTER_ACCESSOR(ft, engine, curVY, vy); + REGISTER_ACCESSOR(ft, engine, curAY, ay); + REGISTER_ACCESSOR(ft, engine, red, red); + REGISTER_ACCESSOR(ft, engine, green, green); + REGISTER_ACCESSOR(ft, engine, blue, blue); + REGISTER_ACCESSOR(ft, engine, alpha, alpha); + + constructor = qPersistentNew(ft->GetFunction()); +} + +QV8ParticleDataDeletable::~QV8ParticleDataDeletable() +{ + qPersistentDispose(constructor); +} + +V8_DEFINE_EXTENSION(QV8ParticleDataDeletable, particleV8Data); + + +QQuickV8ParticleData::QQuickV8ParticleData(QV8Engine* engine, QQuickParticleData* datum) +{ + if (!engine || !datum) + return; + v8::HandleScope handle_scope; + v8::Context::Scope scope(engine->context()); + + QV8ParticleDataDeletable *d = particleV8Data(engine); + m_v8Value = qPersistentNew(d->constructor->NewInstance()); + QV8ParticleDataResource *r = new QV8ParticleDataResource(engine); + r->datum = datum; + m_v8Value->SetExternalResource(r); +} + +QQuickV8ParticleData::~QQuickV8ParticleData() +{ + qPersistentDispose(m_v8Value); +} + +QQmlV8Handle QQuickV8ParticleData::v8Value() +{ + return QQmlV8Handle::fromHandle(m_v8Value); +} + +QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquickv8particledata_p.h qt5-declarative-0.1~git20120423/src/particles/qquickv8particledata_p.h --- qt5-declarative-0.1~git20120402/src/particles/qquickv8particledata_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquickv8particledata_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQuickV8PARTICLEDATA_H +#define QQuickV8PARTICLEDATA_H + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QQuickParticleData; +class QQuickV8ParticleData { +public: + QQuickV8ParticleData(QV8Engine*,QQuickParticleData*); + ~QQuickV8ParticleData(); + QQmlV8Handle v8Value(); +private: + v8::Persistent m_v8Value; +}; + + +QT_END_NAMESPACE + +QT_END_HEADER + + +#endif diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquickwander.cpp qt5-declarative-0.1~git20120423/src/particles/qquickwander.cpp --- qt5-declarative-0.1~git20120402/src/particles/qquickwander.cpp 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquickwander.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,181 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickwander_p.h" +#include "qquickparticlesystem_p.h"//for ParticlesVertices +QT_BEGIN_NAMESPACE +/*! + \qmlclass Wander QQuickWanderAffector + \inqmlmodule QtQuick.Particles 2 + \inherits Affector + \brief The Wander affector allows particles to randomly vary their trajectory. + +*/ +/*! + \qmlproperty real QtQuick.Particles2::Wander::pace + + Maximum attribute change per second. +*/ +/*! + \qmlproperty real QtQuick.Particles2::Wander::xVariance + + Maximum attribute x value (as a result of Wander). + + If unset, Wander will not affect x values. +*/ +/*! + \qmlproperty real QtQuick.Particles2::Wander::yVariance + + Maximum attribute y value (as a result of Wander). + + If unset, Wander will not affect y values. +*/ +/*! + \qmlproperty AffectableParameter QtQuick.Particles2::Wander::affectedParameter + + What attribute of particles is directly affected. + \list + \li PointAttractor.Position + \li PointAttractor.Velocity + \li PointAttractor.Acceleration + \endlist +*/ + +QQuickWanderAffector::QQuickWanderAffector(QQuickItem *parent) : + QQuickParticleAffector(parent), m_xVariance(0), m_yVariance(0), m_pace(0) + , m_affectedParameter(Velocity) +{ + m_needsReset = true; +} + +QQuickWanderAffector::~QQuickWanderAffector() +{ + for (QHash::const_iterator iter=m_wanderData.constBegin(); + iter != m_wanderData.constEnd(); iter++) + delete (*iter); +} + +WanderData* QQuickWanderAffector::getData(int idx) +{ + if (m_wanderData.contains(idx)) + return m_wanderData[idx]; + WanderData* d = new WanderData; + d->x_vel = 0; + d->y_vel = 0; + d->x_peak = m_xVariance; + d->y_peak = m_yVariance; + d->x_var = m_pace * qreal(qrand()) / RAND_MAX; + d->y_var = m_pace * qreal(qrand()) / RAND_MAX; + + m_wanderData.insert(idx, d); + return d; +} + +// TODO: see below +//void QQuickWanderAffector::reset(int systemIdx) +//{ +// if (m_wanderData.contains(systemIdx)) +// delete m_wanderData[systemIdx]; +// m_wanderData.remove(systemIdx); +//} + +bool QQuickWanderAffector::affectParticle(QQuickParticleData* data, qreal dt) +{ + /*TODO: Add a mode which does basically this - picking a direction, going in it (random speed) and then going back + WanderData* d = getData(data->systemIndex); + if (m_xVariance != 0.) { + if ((d->x_vel > d->x_peak && d->x_var > 0.0) || (d->x_vel < -d->x_peak && d->x_var < 0.0)) { + d->x_var = -d->x_var; + d->x_peak = m_xVariance + m_xVariance * qreal(qrand()) / RAND_MAX; + } + d->x_vel += d->x_var * dt; + } + qreal dx = dt * d->x_vel; + + if (m_yVariance != 0.) { + if ((d->y_vel > d->y_peak && d->y_var > 0.0) || (d->y_vel < -d->y_peak && d->y_var < 0.0)) { + d->y_var = -d->y_var; + d->y_peak = m_yVariance + m_yVariance * qreal(qrand()) / RAND_MAX; + } + d->y_vel += d->y_var * dt; + } + qreal dy = dt * d->x_vel; + + //### Should we be amending vel instead? + ParticleVertex* p = &(data->pv); + p->x += dx; + + p->y += dy; + return true; + */ + qreal dx = dt * m_pace * (2 * qreal(qrand())/RAND_MAX - 1); + qreal dy = dt * m_pace * (2 * qreal(qrand())/RAND_MAX - 1); + qreal newX, newY; + switch (m_affectedParameter){ + case Position: + newX = data->curX() + dx; + if (m_xVariance > qAbs(newX) ) + data->x += dx; + newY = data->curY() + dy; + if (m_yVariance > qAbs(newY) ) + data->y += dy; + break; + default: + case Velocity: + newX = data->curVX() + dx; + if (m_xVariance > qAbs(newX) ) + data->setInstantaneousVX(newX); + newY = data->curVY() + dy; + if (m_yVariance > qAbs(newY) ) + data->setInstantaneousVY(newY); + break; + case Acceleration: + newX = data->ax + dx; + if (m_xVariance > qAbs(newX) ) + data->setInstantaneousAX(newX); + newY = data->ay + dy; + if (m_yVariance > qAbs(newY) ) + data->setInstantaneousAY(newY); + break; + } + return true; +} +QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/particles/qquickwander_p.h qt5-declarative-0.1~git20120423/src/particles/qquickwander_p.h --- qt5-declarative-0.1~git20120402/src/particles/qquickwander_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qquickwander_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,158 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef WANDERAFFECTOR_H +#define WANDERAFFECTOR_H +#include +#include "qquickparticleaffector_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +struct WanderData{ + qreal x_vel; + qreal y_vel; + qreal x_peak; + qreal x_var; + qreal y_peak; + qreal y_var; +}; + +class QQuickWanderAffector : public QQuickParticleAffector +{ + Q_OBJECT + Q_PROPERTY(qreal pace READ pace WRITE setPace NOTIFY paceChanged) + Q_PROPERTY(qreal xVariance READ xVariance WRITE setXVariance NOTIFY xVarianceChanged) + Q_PROPERTY(qreal yVariance READ yVariance WRITE setYVariance NOTIFY yVarianceChanged) + Q_PROPERTY(AffectableParameters affectedParameter READ affectedParameter WRITE setAffectedParameter NOTIFY affectedParameterChanged) + Q_ENUMS(AffectableParameters) + +public: + enum AffectableParameters { + Position, + Velocity, + Acceleration + }; + + explicit QQuickWanderAffector(QQuickItem *parent = 0); + ~QQuickWanderAffector(); +// virtual void reset(int systemIdx); + + qreal xVariance() const + { + return m_xVariance; + } + + qreal yVariance() const + { + return m_yVariance; + } + + qreal pace() const + { + return m_pace; + } + + AffectableParameters affectedParameter() const + { + return m_affectedParameter; + } + +protected: + virtual bool affectParticle(QQuickParticleData *d, qreal dt); +signals: + + void xVarianceChanged(qreal arg); + + void yVarianceChanged(qreal arg); + + void paceChanged(qreal arg); + + + void affectedParameterChanged(AffectableParameters arg); + +public slots: +void setXVariance(qreal arg) +{ + if (m_xVariance != arg) { + m_xVariance = arg; + emit xVarianceChanged(arg); + } +} + +void setYVariance(qreal arg) +{ + if (m_yVariance != arg) { + m_yVariance = arg; + emit yVarianceChanged(arg); + } +} + +void setPace(qreal arg) +{ + if (m_pace != arg) { + m_pace = arg; + emit paceChanged(arg); + } +} + + +void setAffectedParameter(AffectableParameters arg) +{ + if (m_affectedParameter != arg) { + m_affectedParameter = arg; + emit affectedParameterChanged(arg); + } +} + +private: + WanderData* getData(int idx); + QHash m_wanderData; + qreal m_xVariance; + qreal m_yVariance; + qreal m_pace; + AffectableParameters m_affectedParameter; +}; + +QT_END_NAMESPACE +QT_END_HEADER +#endif // WANDERAFFECTOR_H diff -Nru qt5-declarative-0.1~git20120402/src/particles/qtquickparticlesglobal_p.h qt5-declarative-0.1~git20120423/src/particles/qtquickparticlesglobal_p.h --- qt5-declarative-0.1~git20120402/src/particles/qtquickparticlesglobal_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qtquickparticlesglobal_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQuickParticles module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTQUICKPARTICLESGLOBAL_P_H +#define QTQUICKPARTICLESGLOBAL_P_H + +#include + +// We only have private exports from this library + +#if defined(Q_OS_WIN) +# if defined(QT_MAKEDLL) /* create a Qt DLL library */ +# if defined(QT_BUILD_QUICKPARTICLES_LIB) +# define Q_QUICKPARTICLES_PRIVATE_EXPORT Q_DECL_EXPORT +# else +# define Q_QUICKPARTICLES_PRIVATE_EXPORT Q_DECL_IMPORT +# endif +# elif defined(QT_DLL) /* use a Qt DLL library */ +# define Q_QUICKPARTICLES_PRIVATE_EXPORT Q_DECL_IMPORT +# endif +#endif + +#if !defined(Q_QUICKPARTICLES_PRIVATE_EXPORT) +# if defined(QT_SHARED) +# define Q_QUICKPARTICLES_PRIVATE_EXPORT Q_DECL_EXPORT +# else +# define Q_QUICKPARTICLES_PRIVATE_EXPORT +# endif +#endif + +#endif // QTQUICKPARTICLESGLOBAL_P_H diff -Nru qt5-declarative-0.1~git20120402/src/particles/qtquickparticlesversion.h qt5-declarative-0.1~git20120423/src/particles/qtquickparticlesversion.h --- qt5-declarative-0.1~git20120402/src/particles/qtquickparticlesversion.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/particles/qtquickparticlesversion.h 2012-04-23 14:20:07.000000000 +0000 @@ -0,0 +1,9 @@ +/* This file was generated by syncqt with the info from sync.profile. */ +#ifndef QT_QTQUICKPARTICLES_VERSION_H +#define QT_QTQUICKPARTICLES_VERSION_H + +#define QTQUICKPARTICLES_VERSION_STR "5.0.0" + +#define QTQUICKPARTICLES_VERSION 0x050000 + +#endif // QT_QTQUICKPARTICLES_VERSION_H diff -Nru qt5-declarative-0.1~git20120402/src/plugins/accessible/quick/main.cpp qt5-declarative-0.1~git20120423/src/plugins/accessible/quick/main.cpp --- qt5-declarative-0.1~git20120402/src/plugins/accessible/quick/main.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/plugins/accessible/quick/main.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -46,6 +46,7 @@ #include #include +#include #include #include @@ -86,8 +87,11 @@ if (classname == QLatin1String("QQuickView")) { return new QAccessibleQuickView(qobject_cast(object)); // FIXME } else if (classname == QLatin1String("QQuickItem")) { - QQuickItem * item = qobject_cast(object); + QQuickItem *item = qobject_cast(object); Q_ASSERT(item); + QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item); + if (!itemPrivate->isAccessible) + return 0; QVariant v = QQuickAccessibleAttached::property(item, "role"); bool ok; diff -Nru qt5-declarative-0.1~git20120402/src/plugins/accessible/quick/main.moc qt5-declarative-0.1~git20120423/src/plugins/accessible/quick/main.moc --- qt5-declarative-0.1~git20120402/src/plugins/accessible/quick/main.moc 2012-04-02 12:46:24.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/plugins/accessible/quick/main.moc 2012-04-23 14:18:30.000000000 +0000 @@ -1,7 +1,7 @@ /**************************************************************************** ** Meta object code from reading C++ file 'main.cpp' ** -** Created: Mon Apr 2 15:46:24 2012 +** Created: Mon Apr 23 17:18:30 2012 ** by: The Qt Meta Object Compiler version 64 (Qt 5.0.0) ** ** WARNING! All changes made in this file will be lost! Binary files /tmp/39TcBOrOwX/qt5-declarative-0.1~git20120402/src/plugins/accessible/quick/main.o and /tmp/4OL5ZoauBZ/qt5-declarative-0.1~git20120423/src/plugins/accessible/quick/main.o differ Binary files /tmp/39TcBOrOwX/qt5-declarative-0.1~git20120402/src/plugins/accessible/quick/qaccessiblequickitem.o and /tmp/4OL5ZoauBZ/qt5-declarative-0.1~git20120423/src/plugins/accessible/quick/qaccessiblequickitem.o differ diff -Nru qt5-declarative-0.1~git20120402/src/plugins/accessible/quick/qaccessiblequickview.cpp qt5-declarative-0.1~git20120423/src/plugins/accessible/quick/qaccessiblequickview.cpp --- qt5-declarative-0.1~git20120402/src/plugins/accessible/quick/qaccessiblequickview.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/plugins/accessible/quick/qaccessiblequickview.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -127,7 +127,11 @@ } QScopedPointer accessibleInterface(QAccessible::queryAccessibleInterface(item)); - if (accessibleInterface && accessibleInterface->childCount() == 0) { + // this item has no Accessible attached property + if (!accessibleInterface) + return 0; + + if (accessibleInterface->childCount() == 0) { return (itemScreenRect(item).contains(x, y)) ? item : 0; } @@ -155,6 +159,7 @@ if (root) { if (QQuickItem *item = childAt_helper(root, x, y)) return QAccessible::queryAccessibleInterface(item); + return QAccessible::queryAccessibleInterface(root); } return 0; } Binary files /tmp/39TcBOrOwX/qt5-declarative-0.1~git20120402/src/plugins/accessible/quick/qaccessiblequickview.o and /tmp/4OL5ZoauBZ/qt5-declarative-0.1~git20120423/src/plugins/accessible/quick/qaccessiblequickview.o differ Binary files /tmp/39TcBOrOwX/qt5-declarative-0.1~git20120402/src/plugins/accessible/quick/qqmlaccessible.o and /tmp/4OL5ZoauBZ/qt5-declarative-0.1~git20120423/src/plugins/accessible/quick/qqmlaccessible.o differ diff -Nru qt5-declarative-0.1~git20120402/src/plugins/qmltooling/qmldbg_qtquick2/highlight.cpp qt5-declarative-0.1~git20120423/src/plugins/qmltooling/qmldbg_qtquick2/highlight.cpp --- qt5-declarative-0.1~git20120402/src/plugins/qmltooling/qmldbg_qtquick2/highlight.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/plugins/qmltooling/qmldbg_qtquick2/highlight.cpp 2012-04-23 11:44:59.000000000 +0000 @@ -42,6 +42,7 @@ #include "highlight.h" #include +#include namespace QmlJSDebugger { namespace QtQuick2 { @@ -55,7 +56,7 @@ void Highlight::setItem(QQuickItem *item) { if (m_item) - m_item.data()->disconnect(this); + m_item->disconnect(this); if (item) { connect(item, SIGNAL(xChanged()), SLOT(adjust())); @@ -66,34 +67,81 @@ connect(item, SIGNAL(transformOriginChanged(TransformOrigin)), SLOT(adjust())); } - + QQuickCanvas *view = item->canvas(); + QQuickItem * rootItem = view->rootItem(); + if (rootItem) { + connect(rootItem, SIGNAL(xChanged()), SLOT(adjust())); + connect(rootItem, SIGNAL(yChanged()), SLOT(adjust())); + connect(rootItem, SIGNAL(widthChanged()), SLOT(adjust())); + connect(rootItem, SIGNAL(heightChanged()), SLOT(adjust())); + connect(rootItem, SIGNAL(rotationChanged()), SLOT(adjust())); + connect(rootItem, SIGNAL(transformOriginChanged(TransformOrigin)), + SLOT(adjust())); + } m_item = item; adjust(); } void Highlight::adjust() { - const QQuickItem *item = m_item.data(); - setSize(QSizeF(item->width(), item->height())); - setPos(parentItem()->mapFromItem(item->parentItem(), item->pos())); - setRotation(item->rotation()); - setTransformOrigin(item->transformOrigin()); + if (!m_item) + return; + + bool success = false; + m_transform = m_item->itemTransform(0, &success); + if (!success) + m_transform = QTransform(); + + setSize(QSizeF(m_item->width(), m_item->height())); + qreal scaleFactor = 1; + QPointF originOffset = QPointF(0,0); + QQuickCanvas *view = m_item->canvas(); + if (view->rootItem()) { + scaleFactor = view->rootItem()->scale(); + originOffset -= view->rootItem()->pos(); + } + // The scale transform for the overlay needs to be cancelled + // as the Item's transform which will be applied to the painter + // takes care of it. + parentItem()->setScale(1/scaleFactor); + setPos(originOffset); + setContentsSize(view->size()); + update(); } -void SelectionHighlight::paint(QPainter *painter) +void HoverHighlight::paint(QPainter *painter) { + if (!item()) + return; + + painter->save(); + painter->setTransform(transform()); painter->setPen(QColor(108, 141, 221)); - painter->drawRect(QRect(0, 0, width() - 1, height() - 1)); + painter->drawRect(QRect(0, 0, item()->width() - 1, item()->height() - 1)); + painter->restore(); } -void HoverHighlight::paint(QPainter *painter) +void SelectionHighlight::paint(QPainter *painter) { + if (!item()) + return; + + painter->save(); + painter->setTransform(transform()); + if (item()->height() >= 10 && item()->width() >= 10) { + QColor colorHighlight = Qt::green; + painter->fillRect(QRectF(0, 0, item()->width(), 5), colorHighlight); + painter->fillRect(QRectF(0, item()->height()-5, item()->width(), 5), colorHighlight); + painter->fillRect(QRectF(0, 5, 5, item()->height() - 10), colorHighlight); + painter->fillRect(QRectF(item()->width()-5, 5, 5, item()->height() - 10), colorHighlight); + } painter->setPen(QPen(QColor(0, 22, 159))); - painter->drawRect(QRect(1, 1, width() - 3, height() - 3)); + painter->drawRect(QRect(1, 1, item()->width() - 3, item()->height() - 3)); painter->setPen(QColor(158, 199, 255)); - painter->drawRect(QRect(0, 0, width() - 1, height() - 1)); + painter->drawRect(QRect(0, 0, item()->width() - 1, item()->height() - 1)); + painter->restore(); } } // namespace QtQuick2 diff -Nru qt5-declarative-0.1~git20120402/src/plugins/qmltooling/qmldbg_qtquick2/highlight.h qt5-declarative-0.1~git20120423/src/plugins/qmltooling/qmldbg_qtquick2/highlight.h --- qt5-declarative-0.1~git20120402/src/plugins/qmltooling/qmldbg_qtquick2/highlight.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/plugins/qmltooling/qmldbg_qtquick2/highlight.h 2012-04-23 11:44:59.000000000 +0000 @@ -42,9 +42,11 @@ #ifndef HIGHLIGHT_H #define HIGHLIGHT_H -#include +#include +#include #include + namespace QmlJSDebugger { namespace QtQuick2 { @@ -57,12 +59,17 @@ Highlight(QQuickItem *item, QQuickItem *parent); void setItem(QQuickItem *item); + QQuickItem *item() {return m_item;} + +protected: + QTransform transform() {return m_transform;} private slots: void adjust(); private: - QWeakPointer m_item; + QPointer m_item; + QTransform m_transform; }; /** diff -Nru qt5-declarative-0.1~git20120402/src/plugins/qmltooling/qmldbg_qtquick2/inspecttool.cpp qt5-declarative-0.1~git20120423/src/plugins/qmltooling/qmldbg_qtquick2/inspecttool.cpp --- qt5-declarative-0.1~git20120402/src/plugins/qmltooling/qmldbg_qtquick2/inspecttool.cpp 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/plugins/qmltooling/qmldbg_qtquick2/inspecttool.cpp 2012-04-23 11:44:59.000000000 +0000 @@ -0,0 +1,412 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "inspecttool.h" + +#include "highlight.h" +#include "qquickviewinspector.h" + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace QmlJSDebugger { +namespace QtQuick2 { + +InspectTool::InspectTool(QQuickViewInspector *inspector, QQuickView *view) : + AbstractTool(inspector), + m_originalSmooth(view->rootItem()->smooth()), + m_dragStarted(false), + m_pinchStarted(false), + m_didPressAndHold(false), + m_tapEvent(false), + m_rootItem(view->rootItem()), + m_originalPosition(view->rootItem()->pos()), + m_smoothScaleFactor(Constants::ZoomSnapDelta), + m_minScale(0.125f), + m_maxScale(48.0f), + m_originalScale(view->rootItem()->scale()), + m_touchTimestamp(0), + m_hoverHighlight(new HoverHighlight(inspector->overlay())), + m_lastItem(0), + m_lastClickedItem(0) +{ + //Press and Hold Timer + m_pressAndHoldTimer.setSingleShot(true); + m_pressAndHoldTimer.setInterval(Constants::PressAndHoldTimeout); + connect(&m_pressAndHoldTimer, SIGNAL(timeout()), SLOT(zoomTo100())); + enable(true); +} + +InspectTool::~InspectTool() +{ + enable(false); +} + +void InspectTool::enable(bool enable) +{ + if (!enable) { + inspector()->setSelectedItems(QList()); + // restoring the original states. + if (m_rootItem) { + m_rootItem->setScale(m_originalScale); + m_rootItem->setPos(m_originalPosition); + m_rootItem->setSmooth(m_originalSmooth); + } + } else { + if (m_rootItem) { + m_originalSmooth = m_rootItem->smooth(); + m_originalScale = m_rootItem->scale(); + m_originalPosition = m_rootItem->pos(); + m_rootItem->setSmooth(true); + } + } +} + +void InspectTool::leaveEvent(QEvent *) +{ + m_hoverHighlight->setVisible(false); +} + +void InspectTool::mousePressEvent(QMouseEvent *event) +{ + m_mousePosition = event->posF(); + if (event->button() == Qt::LeftButton) { + m_pressAndHoldTimer.start(); + initializeDrag(event->posF()); + } +} + +void InspectTool::mouseReleaseEvent(QMouseEvent *event) +{ + m_mousePosition = event->posF(); + m_pressAndHoldTimer.stop(); + if (event->button() == Qt::LeftButton && !m_dragStarted) { + selectItem(); + m_hoverHighlight->setVisible(false); + } +} + +void InspectTool::mouseDoubleClickEvent(QMouseEvent *event) +{ + m_mousePosition = event->posF(); + m_pressAndHoldTimer.stop(); + if (event->button() == Qt::LeftButton) { + selectNextItem(); + m_hoverHighlight->setVisible(false); + } +} + +void InspectTool::mouseMoveEvent(QMouseEvent *event) +{ + m_mousePosition = event->posF(); + moveItem(event->buttons() & Qt::LeftButton); +} + +void InspectTool::hoverMoveEvent(QMouseEvent *event) +{ + m_mousePosition = event->posF(); + m_pressAndHoldTimer.stop(); + QQuickItem *item = inspector()->topVisibleItemAt(event->pos()); + if (!item || item == m_lastClickedItem) { + m_hoverHighlight->setVisible(false); + } else { + m_hoverHighlight->setItem(item); + m_hoverHighlight->setVisible(true); + } +} + +void InspectTool::wheelEvent(QWheelEvent *event) +{ + if (event->orientation() != Qt::Vertical) + return; + + Qt::KeyboardModifier smoothZoomModifier = Qt::ControlModifier; + if (event->modifiers() & smoothZoomModifier) { + int numDegrees = event->delta() / 8; + qreal newScale = m_rootItem->scale() + m_smoothScaleFactor * (numDegrees / 15.0f); + scaleView(newScale / m_rootItem->scale(), m_mousePosition, m_mousePosition); + } else if (!event->modifiers()) { + if (event->delta() > 0) { + zoomIn(); + } else if (event->delta() < 0) { + zoomOut(); + } + } +} + +void InspectTool::keyReleaseEvent(QKeyEvent *event) +{ + switch (event->key()) { + case Qt::Key_Plus: + zoomIn(); + break; + case Qt::Key_Minus: + zoomOut(); + break; + case Qt::Key_1: + case Qt::Key_2: + case Qt::Key_3: + case Qt::Key_4: + case Qt::Key_5: + case Qt::Key_6: + case Qt::Key_7: + case Qt::Key_8: + case Qt::Key_9: { + qreal newScale = ((event->key() - Qt::Key_0) * 1.0f); + scaleView(newScale / m_rootItem->scale(), m_mousePosition, m_mousePosition); + break; + } + default: + break; + } +} + +void InspectTool::touchEvent(QTouchEvent *event) +{ + QList touchPoints = event->touchPoints(); + + switch (event->type()) { + case QEvent::TouchBegin: + if (touchPoints.count() == 1 && (event->touchPointStates() & Qt::TouchPointPressed)) { + if (!m_pressAndHoldTimer.isActive()) + m_pressAndHoldTimer.start(); + m_mousePosition = touchPoints.first().pos(); + initializeDrag(touchPoints.first().pos()); + m_tapEvent = true; + } else { + m_tapEvent = false; + } + break; + case QEvent::TouchUpdate: { + if (touchPoints.count() > 1) + m_tapEvent = false; + if ((touchPoints.count() == 1) + && (event->touchPointStates() & Qt::TouchPointMoved)) { + m_mousePosition = touchPoints.first().pos(); + moveItem(true); + } else if ((touchPoints.count() == 2) + && (!(event->touchPointStates() & Qt::TouchPointReleased))) { + // determine scale factor + const QTouchEvent::TouchPoint &touchPoint0 = touchPoints.first(); + const QTouchEvent::TouchPoint &touchPoint1 = touchPoints.last(); + + qreal touchScaleFactor = + QLineF(touchPoint0.pos(), touchPoint1.pos()).length() + / QLineF(touchPoint0.lastPos(), touchPoint1.lastPos()).length(); + + QPointF oldcenter = (touchPoint0.lastPos() + touchPoint1.lastPos()) / 2; + QPointF newcenter = (touchPoint0.pos() + touchPoint1.pos()) / 2; + + m_pinchStarted = true; + scaleView(touchScaleFactor, newcenter, oldcenter); + } + break; + } + case QEvent::TouchEnd: { + m_pressAndHoldTimer.stop(); + if (m_pinchStarted) { + m_pinchStarted = false; + } + if (touchPoints.count() == 1 && !m_dragStarted && + !m_didPressAndHold && m_tapEvent) { + m_tapEvent = false; + bool doubleTap = event->timestamp() - m_touchTimestamp + < static_cast(qApp->styleHints()->mouseDoubleClickInterval()); + if (doubleTap) + selectNextItem(); + else + selectItem(); + m_touchTimestamp = event->timestamp(); + } + m_didPressAndHold = false; + break; + } + default: + break; + } +} + +void InspectTool::scaleView(const qreal &factor, const QPointF &newcenter, const QPointF &oldcenter) +{ + m_pressAndHoldTimer.stop(); + if (((m_rootItem->scale() * factor) > m_maxScale) + || ((m_rootItem->scale() * factor) < m_minScale)) { + return; + } + //New position = new center + scalefactor * (oldposition - oldcenter) + QPointF newPosition = newcenter + (factor * (m_rootItem->pos() - oldcenter)); + m_rootItem->setScale(m_rootItem->scale() * factor); + m_rootItem->setPos(newPosition); +} + +void InspectTool::zoomIn() +{ + qreal newScale = nextZoomScale(ZoomIn); + scaleView(newScale / m_rootItem->scale(), m_mousePosition, m_mousePosition); +} + +void InspectTool::zoomOut() +{ + qreal newScale = nextZoomScale(ZoomOut); + scaleView(newScale / m_rootItem->scale(), m_mousePosition, m_mousePosition); +} + +void InspectTool::zoomTo100() +{ + m_didPressAndHold = true; + + m_rootItem->setPos(QPointF(0, 0)); + m_rootItem->setScale(1.0); +} + +qreal InspectTool::nextZoomScale(ZoomDirection direction) +{ + static QList zoomScales = + QList() + << 0.125f + << 1.0f / 6.0f + << 0.25f + << 1.0f / 3.0f + << 0.5f + << 2.0f / 3.0f + << 1.0f + << 2.0f + << 3.0f + << 4.0f + << 5.0f + << 6.0f + << 7.0f + << 8.0f + << 12.0f + << 16.0f + << 32.0f + << 48.0f; + + if (direction == ZoomIn) { + for (int i = 0; i < zoomScales.length(); ++i) { + if (zoomScales[i] > m_rootItem->scale()) + return zoomScales[i]; + } + return zoomScales.last(); + } else { + for (int i = zoomScales.length() - 1; i >= 0; --i) { + if (zoomScales[i] < m_rootItem->scale()) + return zoomScales[i]; + } + return zoomScales.first(); + } + + return 1.0f; +} + +void InspectTool::initializeDrag(const QPointF &pos) +{ + m_dragStartPosition = pos; + m_dragStarted = false; +} + +void InspectTool::dragItemToPosition() +{ + QPointF newPosition = m_rootItem->pos() + m_mousePosition - m_dragStartPosition; + m_dragStartPosition = m_mousePosition; + m_rootItem->setPos(newPosition); +} + +void InspectTool::moveItem(bool valid) +{ + if (m_pinchStarted) + return; + + if (!m_dragStarted + && valid + && ((m_dragStartPosition - m_mousePosition).manhattanLength() + > qApp->styleHints()->startDragDistance())) { + m_pressAndHoldTimer.stop(); + m_dragStarted = true; + } + if (m_dragStarted) + dragItemToPosition(); +} + +void InspectTool::selectNextItem() +{ + if (m_lastClickedItem != inspector()->topVisibleItemAt(m_mousePosition)) + return; + QList items = inspector()->itemsAt(m_mousePosition); + for (int i = 0; i < items.count(); i++) { + if (m_lastItem == items[i]) { + if (i + 1 < items.count()) + m_lastItem = items[i+1]; + else + m_lastItem = items[0]; + inspector()->setSelectedItems(QList() << m_lastItem); + break; + } + } +} + +void InspectTool::selectItem() +{ + if (!inspector()->topVisibleItemAt(m_mousePosition)) + return; + if (m_lastClickedItem == inspector()->topVisibleItemAt(m_mousePosition)) + return; + m_lastClickedItem = inspector()->topVisibleItemAt(m_mousePosition); + m_lastItem = m_lastClickedItem; + inspector()->setSelectedItems(QList() << m_lastClickedItem); +} + +QQuickViewInspector *InspectTool::inspector() const +{ + return static_cast(AbstractTool::inspector()); +} + +} // namespace QtQuick2 +} // namespace QmlJSDebugger diff -Nru qt5-declarative-0.1~git20120402/src/plugins/qmltooling/qmldbg_qtquick2/inspecttool.h qt5-declarative-0.1~git20120423/src/plugins/qmltooling/qmldbg_qtquick2/inspecttool.h --- qt5-declarative-0.1~git20120402/src/plugins/qmltooling/qmldbg_qtquick2/inspecttool.h 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/plugins/qmltooling/qmldbg_qtquick2/inspecttool.h 2012-04-23 11:44:59.000000000 +0000 @@ -0,0 +1,129 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef INSPECTTOOL_H +#define INSPECTTOOL_H + +#include "abstracttool.h" + +#include +#include +#include + +QT_FORWARD_DECLARE_CLASS(QQuickView) +QT_FORWARD_DECLARE_CLASS(QQuickItem) + +namespace QmlJSDebugger { +namespace QtQuick2 { + +class QQuickViewInspector; +class HoverHighlight; + +class InspectTool : public AbstractTool +{ + Q_OBJECT +public: + enum ZoomDirection { + ZoomIn, + ZoomOut + }; + + InspectTool(QQuickViewInspector *inspector, QQuickView *view); + ~InspectTool(); + + void enable(bool enable); + + void leaveEvent(QEvent *); + + void mousePressEvent(QMouseEvent *); + void mouseMoveEvent(QMouseEvent *); + void mouseReleaseEvent(QMouseEvent *); + void mouseDoubleClickEvent(QMouseEvent *); + + void hoverMoveEvent(QMouseEvent *); + void wheelEvent(QWheelEvent *); + + void keyPressEvent(QKeyEvent *) {} + void keyReleaseEvent(QKeyEvent *); + + void touchEvent(QTouchEvent *event); + +private: + QQuickViewInspector *inspector() const; + qreal nextZoomScale(ZoomDirection direction); + void scaleView(const qreal &factor, const QPointF &newcenter, const QPointF &oldcenter); + void zoomIn(); + void zoomOut(); + void initializeDrag(const QPointF &pos); + void dragItemToPosition(); + void moveItem(bool valid); + void selectNextItem(); + void selectItem(); + +private slots: + void zoomTo100(); + +private: + bool m_originalSmooth; + bool m_dragStarted; + bool m_pinchStarted; + bool m_didPressAndHold; + bool m_tapEvent; + QPointer m_rootItem; + QPointF m_dragStartPosition; + QPointF m_mousePosition; + QPointF m_originalPosition; + qreal m_smoothScaleFactor; + qreal m_minScale; + qreal m_maxScale; + qreal m_originalScale; + ulong m_touchTimestamp; + QTimer m_pressAndHoldTimer; + + HoverHighlight *m_hoverHighlight; + QQuickItem *m_lastItem; + QQuickItem *m_lastClickedItem; +}; + +} // namespace QtQuick2 +} // namespace QmlJSDebugger + +#endif // INSPECTTOOL_H diff -Nru qt5-declarative-0.1~git20120402/src/plugins/qmltooling/qmldbg_qtquick2/qmldbg_qtquick2.pro qt5-declarative-0.1~git20120423/src/plugins/qmltooling/qmldbg_qtquick2/qmldbg_qtquick2.pro --- qt5-declarative-0.1~git20120402/src/plugins/qmltooling/qmldbg_qtquick2/qmldbg_qtquick2.pro 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/plugins/qmltooling/qmldbg_qtquick2/qmldbg_qtquick2.pro 2012-04-23 11:32:40.000000000 +0000 @@ -12,22 +12,20 @@ SOURCES += \ qtquick2plugin.cpp \ highlight.cpp \ - selectiontool.cpp \ qquickviewinspector.cpp \ ../shared/abstracttool.cpp \ ../shared/abstractviewinspector.cpp \ - zoomtool.cpp + inspecttool.cpp HEADERS += \ qtquick2plugin.h \ highlight.h \ - selectiontool.h \ qquickviewinspector.h \ ../shared/abstracttool.h \ ../shared/abstractviewinspector.h \ ../shared/qqmlinspectorprotocol.h \ ../shared/qmlinspectorconstants.h \ - zoomtool.h + inspecttool.h OTHER_FILES += qtquick2plugin.json diff -Nru qt5-declarative-0.1~git20120402/src/plugins/qmltooling/qmldbg_qtquick2/qquickviewinspector.cpp qt5-declarative-0.1~git20120423/src/plugins/qmltooling/qmldbg_qtquick2/qquickviewinspector.cpp --- qt5-declarative-0.1~git20120402/src/plugins/qmltooling/qmldbg_qtquick2/qquickviewinspector.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/plugins/qmltooling/qmldbg_qtquick2/qquickviewinspector.cpp 2012-04-23 11:44:59.000000000 +0000 @@ -43,8 +43,7 @@ #include "qqmlinspectorprotocol.h" #include "highlight.h" -#include "selectiontool.h" -#include "zoomtool.h" +#include "inspecttool.h" #include @@ -59,8 +58,8 @@ /* * Collects all the items at the given position, from top to bottom. */ -static void collectItemsAt(QQuickItem *item, const QPointF &pos, QQuickItem *overlay, - QList &resultList) +static void collectItemsAt(QQuickItem *item, const QPointF &pos, + QQuickItem *overlay, QList &resultList) { if (item == overlay) return; @@ -86,7 +85,8 @@ * Returns the first visible item at the given position, or 0 when no such * child exists. */ -static QQuickItem *itemAt(QQuickItem *item, const QPointF &pos, QQuickItem *overlay) +static QQuickItem *itemAt(QQuickItem *item, const QPointF &pos, + QQuickItem *overlay) { if (item == overlay) return 0; @@ -102,7 +102,8 @@ QList children = QQuickItemPrivate::get(item)->paintOrderChildItems(); for (int i = children.count() - 1; i >= 0; --i) { QQuickItem *child = children.at(i); - if (QQuickItem *betterCandidate = itemAt(child, item->mapToItem(child, pos), overlay)) + if (QQuickItem *betterCandidate = itemAt(child, item->mapToItem(child, pos), + overlay)) return betterCandidate; } @@ -120,8 +121,7 @@ AbstractViewInspector(parent), m_view(view), m_overlay(new QQuickItem), - m_selectionTool(new SelectionTool(this)), - m_zoomTool(0), + m_inspectTool(new InspectTool(this, view)), m_designMode(true) { // Try to make sure the overlay is always on top @@ -131,7 +131,7 @@ m_overlay->setParentItem(root); view->installEventFilter(this); - setCurrentTool(m_selectionTool); + setCurrentTool(m_inspectTool); } void QQuickViewInspector::changeCurrentObjects(const QList &objects) @@ -165,23 +165,15 @@ void QQuickViewInspector::changeTool(InspectorProtocol::Tool tool) { switch (tool) { - case InspectorProtocol::ColorPickerTool: - // TODO - emit colorPickerActivated(); - break; case InspectorProtocol::SelectMarqueeTool: // TODO emit marqueeSelectToolActivated(); break; - case InspectorProtocol::SelectTool: - setCurrentTool(m_selectionTool); - emit selectToolActivated(); + case InspectorProtocol::InspectTool: + setCurrentTool(m_inspectTool); + emit inspectToolActivated(); break; - case InspectorProtocol::ZoomTool: - if (!m_zoomTool) - m_zoomTool = new ZoomTool(this, m_view); - setCurrentTool(m_zoomTool); - emit zoomToolActivated(); + default: break; } } @@ -225,16 +217,17 @@ { QQuickItem *root = m_view->rootItem(); QList resultList; - collectItemsAt(root, root->mapFromScene(pos), m_overlay, resultList); + collectItemsAt(root, root->mapFromScene(pos), m_overlay, + resultList); return resultList; } QList QQuickViewInspector::selectedItems() const { QList selection; - foreach (const QWeakPointer &selectedItem, m_selectedItems) { + foreach (const QPointer &selectedItem, m_selectedItems) { if (selectedItem) - selection << selectedItem.data(); + selection << selectedItem; } return selection; } @@ -256,16 +249,16 @@ bool selectionChanged = false; // Disconnect and remove items that are no longer selected - foreach (const QWeakPointer &item, m_selectedItems) { + foreach (const QPointer &item, m_selectedItems) { if (!item) // Don't see how this can happen due to handling of destroyed() continue; - if (items.contains(item.data())) + if (items.contains(item)) continue; selectionChanged = true; - item.data()->disconnect(this); + item->disconnect(this); m_selectedItems.removeOne(item); - delete m_highlightItems.take(item.data()); + delete m_highlightItems.take(item); } // Connect and add newly selected items @@ -276,7 +269,9 @@ selectionChanged = true; connect(item, SIGNAL(destroyed(QObject*)), this, SLOT(removeFromSelectedItems(QObject*))); m_selectedItems.append(item); - m_highlightItems.insert(item, new SelectionHighlight(item, m_overlay)); + SelectionHighlight *selectionHighlightItem; + selectionHighlightItem = new SelectionHighlight(item, m_overlay); + m_highlightItems.insert(item, selectionHighlightItem); } return selectionChanged; diff -Nru qt5-declarative-0.1~git20120402/src/plugins/qmltooling/qmldbg_qtquick2/qquickviewinspector.h qt5-declarative-0.1~git20120423/src/plugins/qmltooling/qmldbg_qtquick2/qquickviewinspector.h --- qt5-declarative-0.1~git20120402/src/plugins/qmltooling/qmldbg_qtquick2/qquickviewinspector.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/plugins/qmltooling/qmldbg_qtquick2/qquickviewinspector.h 2012-04-23 11:44:59.000000000 +0000 @@ -44,7 +44,7 @@ #include "abstractviewinspector.h" -#include +#include #include QT_BEGIN_NAMESPACE @@ -55,9 +55,8 @@ namespace QmlJSDebugger { namespace QtQuick2 { -class SelectionTool; +class InspectTool; class SelectionHighlight; -class ZoomTool; class QQuickViewInspector : public AbstractViewInspector { @@ -99,10 +98,9 @@ QQuickView *m_view; QQuickItem *m_overlay; - SelectionTool *m_selectionTool; - ZoomTool *m_zoomTool; + InspectTool *m_inspectTool; - QList > m_selectedItems; + QList > m_selectedItems; QHash m_highlightItems; bool m_designMode; diff -Nru qt5-declarative-0.1~git20120402/src/plugins/qmltooling/qmldbg_qtquick2/selectiontool.cpp qt5-declarative-0.1~git20120423/src/plugins/qmltooling/qmldbg_qtquick2/selectiontool.cpp --- qt5-declarative-0.1~git20120402/src/plugins/qmltooling/qmldbg_qtquick2/selectiontool.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/plugins/qmltooling/qmldbg_qtquick2/selectiontool.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,92 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "selectiontool.h" - -#include "highlight.h" -#include "qquickviewinspector.h" - -#include -#include -#include - -namespace QmlJSDebugger { -namespace QtQuick2 { - -SelectionTool::SelectionTool(QQuickViewInspector *inspector) : - AbstractTool(inspector), - m_hoverHighlight(new HoverHighlight(inspector->overlay())) -{ -} - -void SelectionTool::leaveEvent(QEvent *) -{ - m_hoverHighlight->setVisible(false); -} - -void SelectionTool::mousePressEvent(QMouseEvent *event) -{ - if (event->button() == Qt::LeftButton) { - if (QQuickItem *item = inspector()->topVisibleItemAt(event->pos())) - inspector()->setSelectedItems(QList() << item); - } else if (event->button() == Qt::RightButton) { - // todo: Show context menu - } -} - -void SelectionTool::hoverMoveEvent(QMouseEvent *event) -{ - QQuickItem *item = inspector()->topVisibleItemAt(event->pos()); - if (!item) { - m_hoverHighlight->setVisible(false); - } else { - m_hoverHighlight->setItem(item); - m_hoverHighlight->setVisible(true); - } -} - -QQuickViewInspector *SelectionTool::inspector() const -{ - return static_cast(AbstractTool::inspector()); -} - -} // namespace QtQuick2 -} // namespace QmlJSDebugger diff -Nru qt5-declarative-0.1~git20120402/src/plugins/qmltooling/qmldbg_qtquick2/selectiontool.h qt5-declarative-0.1~git20120423/src/plugins/qmltooling/qmldbg_qtquick2/selectiontool.h --- qt5-declarative-0.1~git20120402/src/plugins/qmltooling/qmldbg_qtquick2/selectiontool.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/plugins/qmltooling/qmldbg_qtquick2/selectiontool.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,86 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef SELECTIONTOOL_H -#define SELECTIONTOOL_H - -#include "abstracttool.h" - -#include -#include - -QT_FORWARD_DECLARE_CLASS(QQuickItem) - -namespace QmlJSDebugger { -namespace QtQuick2 { - -class QQuickViewInspector; -class HoverHighlight; - -class SelectionTool : public AbstractTool -{ - Q_OBJECT -public: - explicit SelectionTool(QQuickViewInspector *inspector); - - void leaveEvent(QEvent *); - - void mousePressEvent(QMouseEvent *); - void mouseMoveEvent(QMouseEvent *) {} - void mouseReleaseEvent(QMouseEvent *) {} - void mouseDoubleClickEvent(QMouseEvent *) {} - - void hoverMoveEvent(QMouseEvent *); - void wheelEvent(QWheelEvent *) {} - - void keyPressEvent(QKeyEvent *) {} - void keyReleaseEvent(QKeyEvent *) {} - -private: - QQuickViewInspector *inspector() const; - - HoverHighlight *m_hoverHighlight; -}; - -} // namespace QtQuick2 -} // namespace QmlJSDebugger - -#endif // SELECTIONTOOL_H diff -Nru qt5-declarative-0.1~git20120402/src/plugins/qmltooling/qmldbg_qtquick2/zoomtool.cpp qt5-declarative-0.1~git20120423/src/plugins/qmltooling/qmldbg_qtquick2/zoomtool.cpp --- qt5-declarative-0.1~git20120402/src/plugins/qmltooling/qmldbg_qtquick2/zoomtool.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/plugins/qmltooling/qmldbg_qtquick2/zoomtool.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,292 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "zoomtool.h" -#include "qquickviewinspector.h" - -#include -#include -#include -#include -#include - -#include -#include - -namespace QmlJSDebugger { -namespace QtQuick2 { - -ZoomTool::ZoomTool(QQuickViewInspector *inspector, QQuickView *view) : - AbstractTool(inspector), - m_dragStarted(false), - m_pinchStarted(false), - m_currentScale(1.0f), - m_smoothScaleFactor(0.05f), - m_minScale(0.125f), - m_maxScale(48.0f), - m_tapScaleCounter(0) -{ - m_rootItem = view->rootItem(); - m_originalSmooth = m_rootItem->smooth(); - if (!m_originalSmooth) - m_rootItem->setSmooth(true); - m_originalPosition = m_rootItem->pos(); - m_originalScale = m_rootItem->scale(); -} - -ZoomTool::~ZoomTool() -{ - // restoring the original states. - if (m_rootItem) { - m_rootItem->setScale(m_originalScale); - m_rootItem->setPos(m_originalPosition); - if (!m_originalSmooth) - m_rootItem->setSmooth(m_originalSmooth); - } -} - -void ZoomTool::mousePressEvent(QMouseEvent *event) -{ - m_mousePosition = event->posF(); - if (event->buttons() & Qt::LeftButton) { - m_dragStartPosition = event->posF(); - m_dragStarted = false; - } -} - -void ZoomTool::mouseMoveEvent(QMouseEvent *event) -{ - if (m_pinchStarted) - return; - - m_mousePosition = event->posF(); - if (!m_dragStarted - && event->buttons() & Qt::LeftButton - && ((m_dragStartPosition - event->posF()).manhattanLength() - > Constants::DragStartDistance)) { - m_dragStarted = true; - } - if (m_dragStarted) { - m_adjustedOrigin += event->posF() - m_dragStartPosition; - m_dragStartPosition = event->posF(); - m_rootItem->setPos(m_adjustedOrigin); - } -} - -void ZoomTool::hoverMoveEvent(QMouseEvent *event) -{ - m_mousePosition = event->posF(); -} - -void ZoomTool::wheelEvent(QWheelEvent *event) -{ - if (event->orientation() != Qt::Vertical) - return; - - Qt::KeyboardModifier smoothZoomModifier = Qt::ControlModifier; - if (event->modifiers() & smoothZoomModifier) { - int numDegrees = event->delta() / 8; - qreal newScale = m_currentScale + m_smoothScaleFactor * (numDegrees / 15.0f); - scaleView(newScale / m_currentScale, m_mousePosition, m_mousePosition); - } else if (!event->modifiers()) { - if (event->delta() > 0) { - zoomIn(); - } else if (event->delta() < 0) { - zoomOut(); - } - } -} - -void ZoomTool::mouseDoubleClickEvent(QMouseEvent *event) -{ - m_mousePosition = event->posF(); - zoomTo100(); -} - -void ZoomTool::keyReleaseEvent(QKeyEvent *event) -{ - switch (event->key()) { - case Qt::Key_Plus: - zoomIn(); - break; - case Qt::Key_Minus: - zoomOut(); - break; - case Qt::Key_1: - case Qt::Key_2: - case Qt::Key_3: - case Qt::Key_4: - case Qt::Key_5: - case Qt::Key_6: - case Qt::Key_7: - case Qt::Key_8: - case Qt::Key_9: { - qreal newScale = ((event->key() - Qt::Key_0) * 1.0f); - scaleView(newScale / m_currentScale, m_mousePosition, m_mousePosition); - break; - } - default: - break; - } -} - -void ZoomTool::touchEvent(QTouchEvent *event) -{ - QList touchPoints = event->touchPoints(); - - switch (event->type()) { - case QEvent::TouchBegin: - // fall through.. - case QEvent::TouchUpdate: { - if ((touchPoints.count() == 2) - && (!(event->touchPointStates() & Qt::TouchPointReleased))) { - // determine scale factor - const QTouchEvent::TouchPoint &touchPoint0 = touchPoints.first(); - const QTouchEvent::TouchPoint &touchPoint1 = touchPoints.last(); - - qreal touchScaleFactor = - QLineF(touchPoint0.pos(), touchPoint1.pos()).length() - / QLineF(touchPoint0.lastPos(), touchPoint1.lastPos()).length(); - - QPointF oldcenter = (touchPoint0.lastPos() + touchPoint1.lastPos()) / 2; - QPointF newcenter = (touchPoint0.pos() + touchPoint1.pos()) / 2; - - m_pinchStarted = true; - m_tapScaleCounter = 0; - scaleView(touchScaleFactor, newcenter, oldcenter); - } - break; - } - case QEvent::TouchEnd: { - if (m_pinchStarted) { - m_pinchStarted = false; - } else if ((touchPoints.count() == 1) - &&(!m_dragStarted)) { - ++m_tapScaleCounter; - qreal factor = 1.0f + (1.0f / (m_tapScaleCounter + 1)); - scaleView(factor, touchPoints.first().pos(), - touchPoints.first().pos()); - } - break; - } - default: - break; - } -} - -void ZoomTool::scaleView(const qreal &factor, const QPointF &newcenter, const QPointF &oldcenter) -{ - if (((m_currentScale * factor) > m_maxScale) - || ((m_currentScale * factor) < m_minScale)) { - return; - } - //New position = new center + scalefactor * (oldposition - oldcenter) - m_adjustedOrigin = newcenter + (factor * (m_adjustedOrigin - oldcenter)); - m_currentScale *= factor; - - m_rootItem->setScale(m_currentScale); - m_rootItem->setPos(m_adjustedOrigin); -} - -void ZoomTool::zoomIn() -{ - qreal newScale = nextZoomScale(ZoomIn); - scaleView(newScale / m_currentScale, m_mousePosition, m_mousePosition); -} - -void ZoomTool::zoomOut() -{ - qreal newScale = nextZoomScale(ZoomOut); - scaleView(newScale / m_currentScale, m_mousePosition, m_mousePosition); -} - -void ZoomTool::zoomTo100() -{ - m_currentScale = 1.0; - m_adjustedOrigin = QPointF(0, 0); - m_tapScaleCounter = 0; - - m_rootItem->setPos(m_adjustedOrigin); - m_rootItem->setScale(m_currentScale); -} - -qreal ZoomTool::nextZoomScale(ZoomDirection direction) -{ - static QList zoomScales = - QList() - << 0.125f - << 1.0f / 6.0f - << 0.25f - << 1.0f / 3.0f - << 0.5f - << 2.0f / 3.0f - << 1.0f - << 2.0f - << 3.0f - << 4.0f - << 5.0f - << 6.0f - << 7.0f - << 8.0f - << 12.0f - << 16.0f - << 32.0f - << 48.0f; - - if (direction == ZoomIn) { - for (int i = 0; i < zoomScales.length(); ++i) { - if (zoomScales[i] > m_currentScale) - return zoomScales[i]; - } - return zoomScales.last(); - } else { - for (int i = zoomScales.length() - 1; i >= 0; --i) { - if (zoomScales[i] < m_currentScale) - return zoomScales[i]; - } - return zoomScales.first(); - } - - return 1.0f; -} - -} // namespace QtQuick2 -} // namespace QmlJSDebugger diff -Nru qt5-declarative-0.1~git20120402/src/plugins/qmltooling/qmldbg_qtquick2/zoomtool.h qt5-declarative-0.1~git20120423/src/plugins/qmltooling/qmldbg_qtquick2/zoomtool.h --- qt5-declarative-0.1~git20120402/src/plugins/qmltooling/qmldbg_qtquick2/zoomtool.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/plugins/qmltooling/qmldbg_qtquick2/zoomtool.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,112 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef ZOOMTOOL_H -#define ZOOMTOOL_H - -#include "abstracttool.h" - -#include -#include - -QT_FORWARD_DECLARE_CLASS(QQuickView) -QT_FORWARD_DECLARE_CLASS(QQuickItem) - -namespace QmlJSDebugger { -namespace QtQuick2 { - -class QQuickViewInspector; - -class ZoomTool : public AbstractTool -{ - Q_OBJECT - -public: - enum ZoomDirection { - ZoomIn, - ZoomOut - }; - - explicit ZoomTool(QQuickViewInspector *inspector, QQuickView *view); - virtual ~ZoomTool(); - void leaveEvent(QEvent *) {} - - void mousePressEvent(QMouseEvent *event); - void mouseMoveEvent(QMouseEvent *event); - void mouseReleaseEvent(QMouseEvent *) {} - void mouseDoubleClickEvent(QMouseEvent *event); - - void hoverMoveEvent(QMouseEvent *event); - void wheelEvent(QWheelEvent *event); - - void keyPressEvent(QKeyEvent *) {} - void keyReleaseEvent(QKeyEvent *event); - - void touchEvent(QTouchEvent *event); - -private: - qreal nextZoomScale(ZoomDirection direction); - void scaleView(const qreal &factor, const QPointF &newcenter, const QPointF &oldcenter); - void zoomTo100(); - void zoomIn(); - void zoomOut(); - -private: - bool m_originalSmooth; - bool m_dragStarted; - bool m_pinchStarted; - QPointer m_rootItem; - QPointF m_adjustedOrigin; - QPointF m_dragStartPosition; - QPointF m_mousePosition; - QPointF m_originalPosition; - qreal m_currentScale; - qreal m_smoothScaleFactor; - qreal m_minScale; - qreal m_maxScale; - qreal m_tapScaleCounter; - qreal m_originalScale; -}; - -} // namespace QtQuick2 -} // namespace QmlJSDebugger - -#endif // ZOOMTOOL_H diff -Nru qt5-declarative-0.1~git20120402/src/plugins/qmltooling/shared/abstracttool.h qt5-declarative-0.1~git20120423/src/plugins/qmltooling/shared/abstracttool.h --- qt5-declarative-0.1~git20120402/src/plugins/qmltooling/shared/abstracttool.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/plugins/qmltooling/shared/abstracttool.h 2012-04-23 11:32:40.000000000 +0000 @@ -64,6 +64,8 @@ AbstractViewInspector *inspector() const { return m_inspector; } + virtual void enable(bool enable) = 0; + virtual void leaveEvent(QEvent *event) = 0; virtual void mousePressEvent(QMouseEvent *event) = 0; diff -Nru qt5-declarative-0.1~git20120402/src/plugins/qmltooling/shared/abstractviewinspector.cpp qt5-declarative-0.1~git20120423/src/plugins/qmltooling/shared/abstractviewinspector.cpp --- qt5-declarative-0.1~git20120402/src/plugins/qmltooling/shared/abstractviewinspector.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/plugins/qmltooling/shared/abstractviewinspector.cpp 2012-04-23 11:44:59.000000000 +0000 @@ -100,6 +100,7 @@ return; m_designModeBehavior = value; + m_currentTool->enable(m_designModeBehavior); emit designModeBehaviorChanged(value); sendDesignModeBehavior(value); } @@ -163,19 +164,9 @@ emit showAppOnTopChanged(appOnTop); } -void AbstractViewInspector::changeToColorPickerTool() +void AbstractViewInspector::changeToInspectTool() { - changeTool(InspectorProtocol::ColorPickerTool); -} - -void AbstractViewInspector::changeToZoomTool() -{ - changeTool(InspectorProtocol::ZoomTool); -} - -void AbstractViewInspector::changeToSingleSelectTool() -{ - changeTool(InspectorProtocol::SelectTool); + changeTool(InspectorProtocol::InspectTool); } void AbstractViewInspector::changeToMarqueeSelectTool() @@ -272,18 +263,12 @@ { switch (event->key()) { case Qt::Key_V: - changeTool(InspectorProtocol::SelectTool); + changeTool(InspectorProtocol::InspectTool); break; // disabled because multiselection does not do anything useful without design mode // case Qt::Key_M: // changeTool(InspectorProtocol::SelectMarqueeTool); // break; - case Qt::Key_I: - changeTool(InspectorProtocol::ColorPickerTool); - break; - case Qt::Key_Z: - changeTool(InspectorProtocol::ZoomTool); - break; case Qt::Key_Space: setAnimationPaused(!animationPaused()); break; @@ -332,8 +317,8 @@ if (QObject *obj = QQmlDebugService::objectForId(debugId)) selectedObjects << obj; } - - changeCurrentObjects(selectedObjects); + if (m_designModeBehavior) + changeCurrentObjects(selectedObjects); break; } case InspectorProtocol::Reload: { @@ -497,17 +482,6 @@ m_debugService->sendMessage(message); } -void AbstractViewInspector::sendColorChanged(const QColor &color) -{ - QByteArray message; - QDataStream ds(&message, QIODevice::WriteOnly); - - ds << InspectorProtocol::ColorChanged - << color; - - m_debugService->sendMessage(message); -} - QString AbstractViewInspector::idStringForObject(QObject *obj) const { const int id = QQmlDebugService::idForObject(obj); diff -Nru qt5-declarative-0.1~git20120402/src/plugins/qmltooling/shared/abstractviewinspector.h qt5-declarative-0.1~git20120423/src/plugins/qmltooling/shared/abstractviewinspector.h --- qt5-declarative-0.1~git20120402/src/plugins/qmltooling/shared/abstractviewinspector.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/plugins/qmltooling/shared/abstractviewinspector.h 2012-04-23 11:32:40.000000000 +0000 @@ -45,7 +45,6 @@ #include #include #include -#include #include "qqmlinspectorprotocol.h" #include "qmlinspectorconstants.h" @@ -109,10 +108,7 @@ void showAppOnTopChanged(bool showAppOnTop); void reloadRequested(); void marqueeSelectToolActivated(); - void selectToolActivated(); - void zoomToolActivated(); - void colorPickerActivated(); - void selectedColorChanged(const QColor &color); + void inspectToolActivated(); void animationSpeedChanged(qreal factor); void animationPausedChanged(bool paused); @@ -132,15 +128,11 @@ virtual bool wheelEvent(QWheelEvent *event); virtual bool touchEvent(QTouchEvent *event); -private slots: - void sendColorChanged(const QColor &color); - private: void sendDesignModeBehavior(bool inDesignMode); - void changeToColorPickerTool(); void changeToZoomTool(); - void changeToSingleSelectTool(); + void changeToInspectTool(); void changeToMarqueeSelectTool(); virtual void setDesignModeBehavior(bool value); diff -Nru qt5-declarative-0.1~git20120402/src/plugins/qmltooling/shared/qmlinspectorconstants.h qt5-declarative-0.1~git20120423/src/plugins/qmltooling/shared/qmlinspectorconstants.h --- qt5-declarative-0.1~git20120402/src/plugins/qmltooling/shared/qmlinspectorconstants.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/plugins/qmltooling/shared/qmlinspectorconstants.h 2012-04-23 11:32:40.000000000 +0000 @@ -53,13 +53,10 @@ MarqueeSelectionToolMode = 2, MoveToolMode = 3, ResizeToolMode = 4, - ColorPickerMode = 5, ZoomMode = 6 }; -static const int DragStartTime = 50; - -static const int DragStartDistance = 20; +static const int PressAndHoldTimeout = 800; static const double ZoomSnapDelta = 0.04; diff -Nru qt5-declarative-0.1~git20120402/src/plugins/qmltooling/shared/qqmlinspectorprotocol.h qt5-declarative-0.1~git20120423/src/plugins/qmltooling/shared/qqmlinspectorprotocol.h --- qt5-declarative-0.1~git20120402/src/plugins/qmltooling/shared/qqmlinspectorprotocol.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/plugins/qmltooling/shared/qqmlinspectorprotocol.h 2012-04-23 11:32:40.000000000 +0000 @@ -60,7 +60,6 @@ AnimationPausedChanged = 19, // highest value ChangeTool = 1, ClearComponentCache = 2, - ColorChanged = 3, CreateObject = 5, CurrentObjectsChanged = 6, DestroyObject = 7, @@ -77,10 +76,8 @@ }; enum Tool { - ColorPickerTool, - SelectMarqueeTool, - SelectTool, - ZoomTool + SelectMarqueeTool = 1, + InspectTool }; static inline QString toString(Message message) diff -Nru qt5-declarative-0.1~git20120402/src/qml/animations/qabstractanimationjob.cpp qt5-declarative-0.1~git20120423/src/qml/animations/qabstractanimationjob.cpp --- qt5-declarative-0.1~git20120402/src/qml/animations/qabstractanimationjob.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/qml/animations/qabstractanimationjob.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -567,7 +567,6 @@ changeListeners.removeOne(ChangeListener(listener, changes)); } - QT_END_NAMESPACE //#include "moc_qabstractanimation2_p.cpp" diff -Nru qt5-declarative-0.1~git20120402/src/qml/animations/qabstractanimationjob_p.h qt5-declarative-0.1~git20120423/src/qml/animations/qabstractanimationjob_p.h --- qt5-declarative-0.1~git20120402/src/qml/animations/qabstractanimationjob_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/qml/animations/qabstractanimationjob_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -113,7 +113,6 @@ void addAnimationChangeListener(QAnimationJobChangeListener *listener, QAbstractAnimationJob::ChangeTypes); void removeAnimationChangeListener(QAnimationJobChangeListener *listener, QAbstractAnimationJob::ChangeTypes); - QAbstractAnimationJob *nextSibling() const { return m_nextSibling; } QAbstractAnimationJob *previousSibling() const { return m_previousSibling; } diff -Nru qt5-declarative-0.1~git20120402/src/qml/animations/qanimationgroupjob.cpp qt5-declarative-0.1~git20120423/src/qml/animations/qanimationgroupjob.cpp --- qt5-declarative-0.1~git20120402/src/qml/animations/qanimationgroupjob.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/qml/animations/qanimationgroupjob.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -51,8 +51,7 @@ QAnimationGroupJob::~QAnimationGroupJob() { - while (firstChild() != 0) - delete firstChild(); + clear(); } void QAnimationGroupJob::topLevelAnimationLoopChanged() @@ -123,9 +122,16 @@ void QAnimationGroupJob::clear() { - //### should this remove and delete, or just remove? - while (firstChild() != 0) - delete firstChild(); //removeAnimation(firstChild()); + QAbstractAnimationJob *child = firstChild(); + QAbstractAnimationJob *nextSibling = 0; + while (child != 0) { + child->m_group = 0; + nextSibling = child->nextSibling(); + delete child; + child = nextSibling; + } + m_firstChild = 0; + m_lastChild = 0; } void QAnimationGroupJob::resetUncontrolledAnimationsFinishTime() diff -Nru qt5-declarative-0.1~git20120402/src/qml/debugger/qqmldebugserver.cpp qt5-declarative-0.1~git20120423/src/qml/debugger/qqmldebugserver.cpp --- qt5-declarative-0.1~git20120402/src/qml/debugger/qqmldebugserver.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/qml/debugger/qqmldebugserver.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -457,14 +457,14 @@ QList QQmlDebugServer::services() const { - const Q_D(QQmlDebugServer); + Q_D(const QQmlDebugServer); QReadLocker(&d->pluginsLock); return d->plugins.values(); } QStringList QQmlDebugServer::serviceNames() const { - const Q_D(QQmlDebugServer); + Q_D(const QQmlDebugServer); QReadLocker(&d->pluginsLock); return d->plugins.keys(); } diff -Nru qt5-declarative-0.1~git20120402/src/qml/debugger/qqmlprofilerservice_p.h qt5-declarative-0.1~git20120423/src/qml/debugger/qqmlprofilerservice_p.h --- qt5-declarative-0.1~git20120402/src/qml/debugger/qqmlprofilerservice_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/qml/debugger/qqmlprofilerservice_p.h 2012-04-23 11:44:59.000000000 +0000 @@ -205,16 +205,16 @@ { enabled = QQmlProfilerService::instance ? QQmlProfilerService::instance->profilingEnabled() : false; - if (enabled) - init(signal, expression); - } - - QQmlHandlingSignalProfiler(QObject *object, int index, QQmlBoundSignalExpression *expression) - { - enabled = QQmlProfilerService::instance - ? QQmlProfilerService::instance->profilingEnabled() : false; - if (enabled) - init(object->metaObject()->method(index), expression); + if (enabled) { + QQmlProfilerService *service = QQmlProfilerService::instance; + service->startRange(QQmlProfilerService::HandlingSignal); + service->rangeData(QQmlProfilerService::HandlingSignal, + QLatin1String(signal.signature()) + QLatin1String(": ") + + expression->expression()); + service->rangeLocation(QQmlProfilerService::HandlingSignal, + expression->sourceFile(), expression->lineNumber(), + expression->columnNumber()); + } } ~QQmlHandlingSignalProfiler() @@ -224,19 +224,6 @@ } bool enabled; - -private: - void init(const QMetaMethod &signal, QQmlBoundSignalExpression *expression) - { - QQmlProfilerService *service = QQmlProfilerService::instance; - service->startRange(QQmlProfilerService::HandlingSignal); - service->rangeData(QQmlProfilerService::HandlingSignal, - QLatin1String(signal.signature()) + QLatin1String(": ") - + expression->expression()); - service->rangeLocation(QQmlProfilerService::HandlingSignal, - expression->sourceFile(), expression->lineNumber(), - expression->columnNumber()); - } }; struct QQmlObjectCreatingProfiler { diff -Nru qt5-declarative-0.1~git20120402/src/qml/qml/ftw/qqmlpool.cpp qt5-declarative-0.1~git20120423/src/qml/qml/ftw/qqmlpool.cpp --- qt5-declarative-0.1~git20120402/src/qml/qml/ftw/qqmlpool.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/qml/qml/ftw/qqmlpool.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -40,6 +40,7 @@ ****************************************************************************/ #include "qqmlpool_p.h" +#include #ifdef Q_OS_QNX #include diff -Nru qt5-declarative-0.1~git20120402/src/qml/qml/qqmlaccessors_p.h qt5-declarative-0.1~git20120423/src/qml/qml/qqmlaccessors_p.h --- qt5-declarative-0.1~git20120402/src/qml/qml/qqmlaccessors_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/qml/qml/qqmlaccessors_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -47,7 +47,7 @@ #include #include -#ifdef Q_OS_QNX +#if defined(Q_OS_QNX) || defined(Q_OS_LINUX) #include #endif diff -Nru qt5-declarative-0.1~git20120402/src/qml/qml/qqmlboundsignal.cpp qt5-declarative-0.1~git20120423/src/qml/qml/qqmlboundsignal.cpp --- qt5-declarative-0.1~git20120402/src/qml/qml/qqmlboundsignal.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/qml/qml/qqmlboundsignal.cpp 2012-04-23 11:44:59.000000000 +0000 @@ -204,10 +204,9 @@ } } -void QQmlAbstractBoundSignal::addToObject() +void QQmlAbstractBoundSignal::addToObject(QObject *obj) { Q_ASSERT(!m_prevSignal); - QObject *obj = object(); Q_ASSERT(obj); QQmlData *data = QQmlData::get(obj, true); @@ -220,13 +219,15 @@ QQmlBoundSignal::QQmlBoundSignal(QObject *scope, const QMetaMethod &signal, QObject *owner) -: m_expression(0), m_signal(signal), m_paramsValid(false), m_isEvaluating(false), m_params(0), m_owner(owner) +: m_expression(0), m_params(0), m_scope(scope), m_signal(signal), m_paramsValid(false), m_isEvaluating(false) { // This is thread safe. Although it may be updated by two threads, they // will both set it to the same value - so the worst thing that can happen // is that they both do the work to figure it out. Boo hoo. if (evaluateIdx == -1) evaluateIdx = metaObject()->methodCount(); + addToObject(owner); + QQmlPropertyPrivate::connect(scope, m_signal.methodIndex(), this, evaluateIdx); } @@ -347,7 +348,7 @@ if (scope == "Qt") meta = &QObject::staticQtMetaObject; else - meta = static_cast(parent)->object()->metaObject(); + meta = static_cast(parent)->scope()->metaObject(); for (int i = meta->enumeratorCount() - 1; i >= 0; --i) { QMetaEnum m = meta->enumerator(i); if ((m.name() == name) && (scope.isEmpty() || (m.scope() == scope))) { @@ -400,70 +401,6 @@ } } -//////////////////////////////////////////////////////////////////////// - -QQmlBoundSignalNoParams::QQmlBoundSignalNoParams(QObject *scope, const QMetaMethod &signal, - QObject *owner) -: m_expression(0), m_owner(owner), m_index(signal.methodIndex()), m_isEvaluating(false) -{ - callback = &subscriptionCallback; - QQmlNotifierEndpoint::connect(scope, m_index); -} - -QQmlBoundSignalNoParams::~QQmlBoundSignalNoParams() -{ - delete m_expression; - m_expression = 0; -} - -int QQmlBoundSignalNoParams::index() const -{ - return m_index; -} - -/*! - Returns the signal expression. -*/ -QQmlBoundSignalExpression *QQmlBoundSignalNoParams::expression() const -{ - return m_expression; -} - -/*! - Sets the signal expression to \a e. Returns the current signal expression, - or null if there is no signal expression. - - The QQmlBoundSignalNoParams instance takes ownership of \a e. The caller is - assumes ownership of the returned QQmlExpression. -*/ -QQmlBoundSignalExpression *QQmlBoundSignalNoParams::setExpression(QQmlBoundSignalExpression *e) -{ - QQmlBoundSignalExpression *rv = m_expression; - m_expression = e; - if (m_expression) m_expression->setNotifyOnValueChanged(false); - return rv; -} - -void QQmlBoundSignalNoParams::subscriptionCallback(QQmlNotifierEndpoint *e) -{ - QQmlBoundSignalNoParams *s = static_cast(e); - if (!s->m_expression) - return; - - if (QQmlDebugService::isDebuggingEnabled()) - QV8DebugService::instance()->signalEmitted(QString::fromAscii(s->m_owner->metaObject()->method(s->m_index).signature())); - - QQmlHandlingSignalProfiler prof(s->m_owner, s->m_index, s->m_expression); - - s->m_isEvaluating = true; - if (s->m_expression && s->m_expression->engine()) { - s->m_expression->evaluate(); // evaluate signal expression. - if (s->m_expression && s->m_expression->hasError()) - QQmlEnginePrivate::warning(s->m_expression->engine(), s->m_expression->error()); - } - s->m_isEvaluating = false; -} - QT_END_NAMESPACE #include diff -Nru qt5-declarative-0.1~git20120402/src/qml/qml/qqmlboundsignal_p.h qt5-declarative-0.1~git20120423/src/qml/qml/qqmlboundsignal_p.h --- qt5-declarative-0.1~git20120402/src/qml/qml/qqmlboundsignal_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/qml/qml/qqmlboundsignal_p.h 2012-04-23 11:44:59.000000000 +0000 @@ -57,7 +57,6 @@ #include #include -#include #include QT_BEGIN_NAMESPACE @@ -108,9 +107,10 @@ virtual int index() const = 0; virtual QQmlBoundSignalExpression *expression() const = 0; virtual QQmlBoundSignalExpression *setExpression(QQmlBoundSignalExpression *) = 0; - virtual QObject *object() = 0; + virtual QObject *scope() = 0; - void addToObject(); +protected: + void addToObject(QObject *owner); private: friend class QQmlData; @@ -132,7 +132,7 @@ QQmlBoundSignalExpression *expression() const; QQmlBoundSignalExpression *setExpression(QQmlBoundSignalExpression *); - QObject *object() { return m_owner; } + QObject *scope() { return m_scope; } bool isEvaluating() const { return m_isEvaluating; } @@ -141,38 +141,13 @@ private: QQmlBoundSignalExpression *m_expression; + QQmlBoundSignalParameters *m_params; + QObject *m_scope; QMetaMethod m_signal; bool m_paramsValid : 1; bool m_isEvaluating : 1; - QQmlBoundSignalParameters *m_params; - QObject *m_owner; }; -class Q_QML_EXPORT QQmlBoundSignalNoParams : public QQmlAbstractBoundSignal, - public QQmlNotifierEndpoint -{ -public: - QQmlBoundSignalNoParams(QObject *scope, const QMetaMethod &signal, QObject *owner); - virtual ~QQmlBoundSignalNoParams(); - - int index() const; - - QQmlBoundSignalExpression *expression() const; - QQmlBoundSignalExpression *setExpression(QQmlBoundSignalExpression *); - QObject *object() { return m_owner; } - - static void subscriptionCallback(QQmlNotifierEndpoint *e); - - bool isEvaluating() const { return m_isEvaluating; } - -private: - QQmlBoundSignalExpression *m_expression; - QObject *m_owner; - int m_index; - bool m_isEvaluating; -}; - - QT_END_NAMESPACE #endif // QQMLBOUNDSIGNAL_P_H diff -Nru qt5-declarative-0.1~git20120402/src/qml/qml/qqmlcomponent.cpp qt5-declarative-0.1~git20120423/src/qml/qml/qqmlcomponent.cpp --- qt5-declarative-0.1~git20120402/src/qml/qml/qqmlcomponent.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/qml/qml/qqmlcomponent.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -1396,7 +1396,8 @@ { if (s == Ready) { Q_ASSERT(QQmlData::get(object())); - QQmlData::get(object())->setImplicitDestructible(); + QQmlData::get(object())->explicitIndestructibleSet = false; + QQmlData::get(object())->indestructible = false; } if (!me.IsEmpty()) { // Will be false in synchronous mode diff -Nru qt5-declarative-0.1~git20120402/src/qml/qml/qqmldata_p.h qt5-declarative-0.1~git20120423/src/qml/qml/qqmldata_p.h --- qt5-declarative-0.1~git20120402/src/qml/qml/qqmldata_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/qml/qml/qqmldata_p.h 2012-04-23 11:44:59.000000000 +0000 @@ -181,11 +181,25 @@ QQmlNotifier *objectNameNotifier() const; QHash *attachedProperties() const; + static inline bool wasDeleted(QObject *); private: // For objectNameNotifier and attachedProperties mutable QQmlDataExtended *extendedData; }; +bool QQmlData::wasDeleted(QObject *object) +{ + if (!object) + return true; + + QObjectPrivate *priv = QObjectPrivate::get(const_cast(object)); + if (priv->wasDeleted) + return true; + + return priv->declarativeData && + static_cast(priv->declarativeData)->isQueuedForDeletion; +} + QQmlNotifierEndpoint *QQmlData::notify(int index) { Q_ASSERT(index <= 0xFFFF); diff -Nru qt5-declarative-0.1~git20120402/src/qml/qml/qqmllist.cpp qt5-declarative-0.1~git20120423/src/qml/qml/qqmllist.cpp --- qt5-declarative-0.1~git20120402/src/qml/qml/qqmllist.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/qml/qml/qqmllist.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -88,7 +88,7 @@ /*! \class QQmlListReference \since 5.0 -\module QtQml +\inmodule QtQml \brief The QQmlListReference class allows the manipulation of QQmlListProperty properties. QQmlListReference allows C++ programs to read from, and assign values to a QML list property in a diff -Nru qt5-declarative-0.1~git20120402/src/qml/qml/qqmllocale.cpp qt5-declarative-0.1~git20120423/src/qml/qml/qqmllocale.cpp --- qt5-declarative-0.1~git20120402/src/qml/qml/qqmllocale.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/qml/qml/qqmllocale.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -750,8 +750,8 @@ \inqmlmodule QtQuick 2 \brief The Locale object provides locale specific properties and formatted data. - The Locale object is created via the \l{QML:Qt::locale()}{Qt.locale()} function. It cannot be created - directly. + The Locale object may only be created via the \l{QML:Qt::locale()}{Qt.locale()} function. + It cannot be created directly. The \l{QML:Qt::locale()}{Qt.locale()} function returns a JS Locale object representing the locale with the specified name, which has the format diff -Nru qt5-declarative-0.1~git20120402/src/qml/qml/qqmlproperty.cpp qt5-declarative-0.1~git20120423/src/qml/qml/qqmlproperty.cpp --- qt5-declarative-0.1~git20120402/src/qml/qml/qqmlproperty.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/qml/qml/qqmlproperty.cpp 2012-04-23 11:44:59.000000000 +0000 @@ -970,13 +970,8 @@ return signalHandler->setExpression(expr); if (expr) { - QQmlAbstractBoundSignal *signal = 0; - if (that.method().parameterTypes().count()) - signal = new QQmlBoundSignal(that.d->object, that.method(), that.d->object); - else - signal = new QQmlBoundSignalNoParams(that.d->object, that.method(), that.d->object); + QQmlBoundSignal *signal = new QQmlBoundSignal(that.d->object, that.method(), that.d->object); QQmlBoundSignalExpression *oldExpr = signal->setExpression(expr); - signal->addToObject(); return oldExpr; } else { return 0; @@ -1527,8 +1522,9 @@ if (QObject *o = *(QObject **)value.constData()) { valueType = o->metaObject()->className(); - const QMetaObject *propertyMetaObject = rawMetaObjectForType(QQmlEnginePrivate::get(engine), type); - propertyType = propertyMetaObject->className(); + if (const QMetaObject *propertyMetaObject = rawMetaObjectForType(QQmlEnginePrivate::get(engine), type)) { + propertyType = propertyMetaObject->className(); + } } } else if (value.userType() != QVariant::Invalid) { valueType = QMetaType::typeName(value.userType()); diff -Nru qt5-declarative-0.1~git20120402/src/qml/qml/qqmlscript.cpp qt5-declarative-0.1~git20120423/src/qml/qml/qqmlscript.cpp --- qt5-declarative-0.1~git20120402/src/qml/qml/qqmlscript.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/qml/qml/qqmlscript.cpp 2012-04-23 11:44:59.000000000 +0000 @@ -66,6 +66,11 @@ : type(-1), idIndex(-1), metatype(0), synthCache(0), defaultProperty(0), parserStatusCast(-1), componentCompileState(0), nextAliasingObject(0), nextIdObject(0) { + // initialize the members in the meta object + extObject.d.superdata = 0; + extObject.d.stringdata = 0; + extObject.d.data = 0; + extObject.d.extradata = 0; } QQmlScript::Object::~Object() @@ -1340,11 +1345,6 @@ _errors[ii].setUrl(url); } - if (_errors.isEmpty()) { - // Sort the imports into desired order - qStableSort(_imports.begin(), _imports.end()); - } - return _errors.isEmpty(); } diff -Nru qt5-declarative-0.1~git20120402/src/qml/qml/qqmlscript_p.h qt5-declarative-0.1~git20120423/src/qml/qml/qqmlscript_p.h --- qt5-declarative-0.1~git20120402/src/qml/qml/qqmlscript_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/qml/qml/qqmlscript_p.h 2012-04-23 11:44:59.000000000 +0000 @@ -121,11 +121,6 @@ void extractVersion(int *maj, int *min) const; QQmlScript::LocationSpan location; - - bool operator<(const Import& other) const { - // Shorter URIs first, so 'import X' is before 'import X.Y' - return (uri.length() < other.uri.length()); - } }; class Object; diff -Nru qt5-declarative-0.1~git20120402/src/qml/qml/qqmlvme.cpp qt5-declarative-0.1~git20120423/src/qml/qml/qqmlvme.cpp --- qt5-declarative-0.1~git20120402/src/qml/qml/qqmlvme.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/qml/qml/qqmlvme.cpp 2012-04-23 11:44:59.000000000 +0000 @@ -205,13 +205,19 @@ { QQmlData *ddata = static_cast(QObjectPrivate::get(o)->declarativeData); + index &= 0xFFFFFF; // To handle value types + return ddata && (ddata->bindingBitsSize > index) && (ddata->bindingBits[index / 32] & (1 << (index % 32))); } static void removeBindingOnProperty(QObject *o, int index) { - QQmlAbstractBinding *binding = QQmlPropertyPrivate::setBinding(o, index, -1, 0); + int coreIndex = index & 0xFFFFFF; + int valueTypeIndex = index & 0xFF000000; + if (!valueTypeIndex) valueTypeIndex = -1; + + QQmlAbstractBinding *binding = QQmlPropertyPrivate::setBinding(o, coreIndex, valueTypeIndex, 0); if (binding) binding->destroy(); } @@ -711,15 +717,10 @@ QMetaMethod signal = target->metaObject()->method(instr.signalIndex); - QQmlAbstractBoundSignal *bs = 0; - if (signal.parameterTypes().count()) - bs = new QQmlBoundSignal(target, signal, target); - else - bs = new QQmlBoundSignalNoParams(target, signal, target); + QQmlBoundSignal *bs = new QQmlBoundSignal(target, signal, target); QQmlBoundSignalExpression *expr = new QQmlBoundSignalExpression(CTXT, context, DATAS.at(instr.value), true, COMP->name, instr.line, instr.column); bs->setExpression(expr); - bs->addToObject(); QML_END_INSTR(StoreSignal) QML_BEGIN_INSTR(StoreImportedScript) @@ -787,6 +788,8 @@ Q_ASSERT(bind->propertyIndex() == QDPP::bindingIndex(instr.property)); Q_ASSERT(bind->object() == target); + CLEAN_PROPERTY(target, QDPP::bindingIndex(instr.property)); + bind->addToObject(); } QML_END_INSTR(StoreBinding) @@ -810,6 +813,8 @@ Q_ASSERT(binding->propertyIndex() == (property & 0xFF00FFFF)); Q_ASSERT(binding->object() == target); + CLEAN_PROPERTY(target, property & 0xFF00FFFF); + binding->addToObject(); QML_END_INSTR(StoreV4Binding) @@ -840,6 +845,8 @@ Q_ASSERT(binding->propertyIndex() == QDPP::bindingIndex(instr.property)); Q_ASSERT(binding->object() == target); + CLEAN_PROPERTY(target, QDPP::bindingIndex(instr.property)); + binding->addToObject(); } } @@ -1224,9 +1231,9 @@ while (!bindValues.isEmpty()) { QQmlAbstractBinding *b = bindValues.pop(); - if(b) { + if (b) { b->m_mePtr = 0; - b->setEnabled(true, QQmlPropertyPrivate::BypassInterceptor | + b->setEnabled(true, QQmlPropertyPrivate::BypassInterceptor | QQmlPropertyPrivate::DontRemoveBinding); } diff -Nru qt5-declarative-0.1~git20120402/src/qml/qml/v4/qv4bindings.cpp qt5-declarative-0.1~git20120423/src/qml/qml/v4/qv4bindings.cpp --- qt5-declarative-0.1~git20120402/src/qml/qml/v4/qv4bindings.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/qml/qml/v4/qv4bindings.cpp 2012-04-23 11:44:59.000000000 +0000 @@ -66,47 +66,52 @@ struct Register { typedef QQmlRegisterType Type; - void setUndefined() { dataType = UndefinedType; } - void setNull() { dataType = NullType; } - void setNaN() { setqreal(qSNaN()); } - bool isUndefined() const { return dataType == UndefinedType; } - - void setQObject(QObject *o) { qobjectValue = o; dataType = QObjectStarType; } - QObject *getQObject() const { return qobjectValue; } - - void setqreal(qreal v) { qrealValue = v; dataType = QRealType; } - qreal getqreal() const { return qrealValue; } - qreal &getqrealref() { return qrealValue; } - - void setint(int v) { intValue = v; dataType = IntType; } - int getint() const { return intValue; } - int &getintref() { return intValue; } - - void setbool(bool v) { boolValue = v; dataType = BoolType; } - bool getbool() const { return boolValue; } - bool &getboolref() { return boolValue; } - - QVariant *getvariantptr() { return (QVariant *)typeDataPtr(); } - QString *getstringptr() { return (QString *)typeDataPtr(); } - QUrl *geturlptr() { return (QUrl *)typeDataPtr(); } - QColor *getcolorptr() { return (QColor *)typeDataPtr(); } - const QVariant *getvariantptr() const { return (QVariant *)typeDataPtr(); } - const QString *getstringptr() const { return (QString *)typeDataPtr(); } - const QUrl *geturlptr() const { return (QUrl *)typeDataPtr(); } - const QColor *getcolorptr() const { return (QColor *)typeDataPtr(); } - - void *typeDataPtr() { return (void *)&data; } - void *typeMemory() { return (void *)data; } - const void *typeDataPtr() const { return (void *)&data; } - const void *typeMemory() const { return (void *)data; } + inline void setUndefined() { dataType = UndefinedType; } + inline void setNull() { dataType = NullType; } + inline void setNaN() { setnumber(qSNaN()); } + inline bool isUndefined() const { return dataType == UndefinedType; } + + inline void setQObject(QObject *o) { qobjectValue = o; dataType = QObjectStarType; } + inline QObject *getQObject() const { return qobjectValue; } + + inline void setnumber(double v) { numberValue = v; dataType = NumberType; } + inline double getnumber() const { return numberValue; } + inline double &getnumberref() { return numberValue; } + + inline void setfloat(float v) { floatValue = v; dataType = FloatType; } + inline float getfloat() const { return floatValue; } + inline float &getfloatref() { return floatValue; } + + inline void setint(int v) { intValue = v; dataType = IntType; } + inline int getint() const { return intValue; } + inline int &getintref() { return intValue; } + + inline void setbool(bool v) { boolValue = v; dataType = BoolType; } + inline bool getbool() const { return boolValue; } + inline bool &getboolref() { return boolValue; } + + inline QVariant *getvariantptr() { return (QVariant *)typeDataPtr(); } + inline QString *getstringptr() { return (QString *)typeDataPtr(); } + inline QUrl *geturlptr() { return (QUrl *)typeDataPtr(); } + inline QColor *getcolorptr() { return (QColor *)typeDataPtr(); } + inline const QVariant *getvariantptr() const { return (QVariant *)typeDataPtr(); } + inline const QString *getstringptr() const { return (QString *)typeDataPtr(); } + inline const QUrl *geturlptr() const { return (QUrl *)typeDataPtr(); } + inline const QColor *getcolorptr() const { return (QColor *)typeDataPtr(); } + + inline void *typeDataPtr() { return (void *)&data; } + inline void *typeMemory() { return (void *)data; } + inline const void *typeDataPtr() const { return (void *)&data; } + inline const void *typeMemory() const { return (void *)data; } - Type gettype() const { return dataType; } - void settype(Type t) { dataType = t; } + inline Type gettype() const { return dataType; } + inline void settype(Type t) { dataType = t; } Type dataType; // Type of data union { QObject *qobjectValue; - qreal qrealValue; + double numberValue; + float floatValue; int intValue; bool boolValue; void *data[sizeof(QVariant)]; @@ -388,85 +393,6 @@ sub->disconnect(); } -// Conversion functions - these MUST match the QtScript expression path -inline static qreal toReal(Register *reg, int type, bool *ok = 0) -{ - if (ok) *ok = true; - - if (type == QMetaType::QReal) { - return reg->getqreal(); - } else if (type == qMetaTypeId()) { - return reg->getvariantptr()->toReal(); - } else { - if (ok) *ok = false; - return 0; - } -} - -inline static QString toString(Register *reg, int type, bool *ok = 0) -{ - if (ok) *ok = true; - - if (type == QMetaType::QReal) { - return QString::number(reg->getqreal()); - } else if (type == QMetaType::Int) { - return QString::number(reg->getint()); - } else if (type == qMetaTypeId()) { - return reg->getvariantptr()->toString(); - } else if (type == QMetaType::QString) { - return *reg->getstringptr(); - } else { - if (ok) *ok = false; - return QString(); - } -} - -inline static bool toBool(Register *reg, int type, bool *ok = 0) -{ - if (ok) *ok = true; - - if (type == QMetaType::Bool) { - return reg->getbool(); - } else if (type == qMetaTypeId()) { - return reg->getvariantptr()->toBool(); - } else { - if (ok) *ok = false; - return false; - } -} - -inline static QUrl toUrl(Register *reg, int type, QQmlContextData *context, bool *ok = 0) -{ - if (ok) *ok = true; - - QUrl base; - if (type == qMetaTypeId()) { - QVariant *var = reg->getvariantptr(); - int vt = var->type(); - if (vt == QVariant::Url) { - base = var->toUrl(); - } else if (vt == QVariant::ByteArray) { - // Preserve any valid percent-encoded octets supplied by the source - base.setEncodedUrl(var->toByteArray(), QUrl::TolerantMode); - } else if (vt == QVariant::String) { - base.setEncodedUrl(var->toString().toUtf8(), QUrl::TolerantMode); - } else { - if (ok) *ok = false; - return QUrl(); - } - } else if (type == QMetaType::QString) { - base.setEncodedUrl(reg->getstringptr()->toUtf8(), QUrl::TolerantMode); - } else { - if (ok) *ok = false; - return QUrl(); - } - - if (!base.isEmpty() && base.isRelative()) - return context->url.resolved(base); - else - return base; -} - static bool testCompareVariants(const QVariant &qtscriptRaw, const QVariant &v4) { QVariant qtscript = qtscriptRaw; @@ -530,10 +456,29 @@ if (expression.hasError()) { iserror = true; qtscriptResult = "exception"; - } else { - qtscriptResult = testResultToString(value, isUndefined); + } else if ((value.userType() != resultType) && (resultType != QMetaType::QVariant)) { + // Override the QMetaType conversions to make them more JS friendly. + if (value.userType() == QMetaType::Double && (resultType == QMetaType::QString || + resultType == QMetaType::QUrl)) { + // number to string-like conversion. + value = QVariant::fromValue(QString::number(value.toDouble(), 'g', 16)); + } else if (value.userType() == QMetaType::QUrl && resultType == QMetaType::Bool) { + // url to bool conversion + value = QVariant::fromValue(!value.toUrl().isEmpty()); + } + + if (!value.isNull() && !value.convert(resultType)) { + iserror = true; + qtscriptResult = "exception"; + } else if (resultType == QMetaType::QUrl) { + // a V8 value was converted to QUrl. + value = QVariant::fromValue(context->resolvedUrl(value.toUrl())); + } } + if (! iserror) + qtscriptResult = testResultToString(value, isUndefined); + if (isUndefined && result.isUndefined()) { return; } else if(isUndefined != result.isUndefined()) { @@ -558,8 +503,14 @@ case QMetaType::Int: v4value = result.getint(); break; - case QMetaType::QReal: - v4value = result.getqreal(); + case QMetaType::Double: + v4value = result.getnumber(); + break; + case QMetaType::QColor: + v4value = *result.getcolorptr(); + break; + case QMetaType::QVariant: + v4value = *result.getvariantptr(); break; default: if (resultType == QQmlMetaType::QQuickAnchorLineMetaTypeId()) { @@ -622,15 +573,15 @@ QQmlEnginePrivate::warning(context->engine, error->error); } -const qreal QV4Bindings::D32 = 4294967296.0; +const double QV4Bindings::D32 = 4294967296.0; -qint32 QV4Bindings::toInt32(qreal n) +qint32 QV4Bindings::toInt32(double n) { if (qIsNaN(n) || qIsInf(n) || (n == 0)) return 0; double sign = (n < 0) ? -1.0 : 1.0; - qreal abs_n = fabs(n); + double abs_n = fabs(n); n = ::fmod(sign * ::floor(abs_n), D32); const double D31 = D32 / 2.0; @@ -644,13 +595,13 @@ return qint32 (n); } -inline quint32 QV4Bindings::toUint32(qreal n) +inline quint32 QV4Bindings::toUint32(double n) { if (qIsNaN(n) || qIsInf(n) || (n == 0)) return 0; double sign = (n < 0) ? -1.0 : 1.0; - qreal abs_n = fabs(n); + double abs_n = fabs(n); n = ::fmod(sign * ::floor(abs_n), D32); @@ -666,6 +617,11 @@ goto exceptionExit; \ } +#define THROW_VALUE_EXCEPTION_STR(id, str) { \ + throwException((id), error, program, context, (str)); \ + goto exceptionExit; \ +} + #define THROW_EXCEPTION(id) THROW_EXCEPTION_STR(id, QString()) #define MARK_REGISTER(reg) cleanupRegisterMask |= (1 << (reg)) @@ -792,13 +748,21 @@ sub->bindings = this; sub->method = subIdx; } - reg.init((Register::Type)instr->fetchAndSubscribe.valueType); + + const Register::Type valueType = (Register::Type)instr->fetchAndSubscribe.valueType; + reg.init(valueType); if (instr->fetchAndSubscribe.valueType >= FirstCleanupType) MARK_REGISTER(instr->fetchAndSubscribe.reg); QQmlAccessors *accessors = instr->fetchAndSubscribe.property.accessors; accessors->read(object, instr->fetchAndSubscribe.property.accessorData, reg.typeDataPtr()); + if (valueType == FloatType) { + // promote floats + const double v = reg.getfloat(); + reg.setnumber(v); + } + if (accessors->notifier) { QQmlNotifier *notifier = 0; accessors->notifier(object, instr->fetchAndSubscribe.property.accessorData, ¬ifier); @@ -869,11 +833,11 @@ } QML_V4_END_INSTR(UnaryNot, unaryop) - QML_V4_BEGIN_INSTR(UnaryMinusReal, unaryop) + QML_V4_BEGIN_INSTR(UnaryMinusNumber, unaryop) { - registers[instr->unaryop.output].setqreal(-registers[instr->unaryop.src].getqreal()); + registers[instr->unaryop.output].setnumber(-registers[instr->unaryop.src].getnumber()); } - QML_V4_END_INSTR(UnaryMinusReal, unaryop) + QML_V4_END_INSTR(UnaryMinusNumber, unaryop) QML_V4_BEGIN_INSTR(UnaryMinusInt, unaryop) { @@ -881,11 +845,11 @@ } QML_V4_END_INSTR(UnaryMinusInt, unaryop) - QML_V4_BEGIN_INSTR(UnaryPlusReal, unaryop) + QML_V4_BEGIN_INSTR(UnaryPlusNumber, unaryop) { - registers[instr->unaryop.output].setqreal(+registers[instr->unaryop.src].getqreal()); + registers[instr->unaryop.output].setnumber(+registers[instr->unaryop.src].getnumber()); } - QML_V4_END_INSTR(UnaryPlusReal, unaryop) + QML_V4_END_INSTR(UnaryPlusNumber, unaryop) QML_V4_BEGIN_INSTR(UnaryPlusInt, unaryop) { @@ -902,14 +866,14 @@ } QML_V4_END_INSTR(ConvertBoolToInt, unaryop) - QML_V4_BEGIN_INSTR(ConvertBoolToReal, unaryop) + QML_V4_BEGIN_INSTR(ConvertBoolToNumber, unaryop) { const Register &src = registers[instr->unaryop.src]; Register &output = registers[instr->unaryop.output]; if (src.isUndefined()) output.setUndefined(); - else output.setqreal(src.getbool()); + else output.setnumber(src.getbool()); } - QML_V4_END_INSTR(ConvertBoolToReal, unaryop) + QML_V4_END_INSTR(ConvertBoolToNumber, unaryop) QML_V4_BEGIN_INSTR(ConvertBoolToString, unaryop) { @@ -924,6 +888,19 @@ } QML_V4_END_INSTR(ConvertBoolToString, unaryop) + QML_V4_BEGIN_INSTR(ConvertBoolToVariant, unaryop) + { + const Register &src = registers[instr->unaryop.src]; + Register &output = registers[instr->unaryop.output]; + if (src.isUndefined()) { + output.setUndefined(); + } else { + new (output.getvariantptr()) QVariant(src.getbool()); + VARIANT_REGISTER(instr->unaryop.output); + } + } + QML_V4_END_INSTR(ConvertBoolToVariant, unaryop) + QML_V4_BEGIN_INSTR(ConvertIntToBool, unaryop) { const Register &src = registers[instr->unaryop.src]; @@ -933,14 +910,14 @@ } QML_V4_END_INSTR(ConvertIntToBool, unaryop) - QML_V4_BEGIN_INSTR(ConvertIntToReal, unaryop) + QML_V4_BEGIN_INSTR(ConvertIntToNumber, unaryop) { const Register &src = registers[instr->unaryop.src]; Register &output = registers[instr->unaryop.output]; if (src.isUndefined()) output.setUndefined(); - else output.setqreal(qreal(src.getint())); + else output.setnumber(double(src.getint())); } - QML_V4_END_INSTR(ConvertIntToReal, unaryop) + QML_V4_END_INSTR(ConvertIntToNumber, unaryop) QML_V4_BEGIN_INSTR(ConvertIntToString, unaryop) { @@ -948,32 +925,45 @@ Register &output = registers[instr->unaryop.output]; if (src.isUndefined()) { output.setUndefined(); - } else { + } else { new (output.getstringptr()) QString(QString::number(src.getint())); STRING_REGISTER(instr->unaryop.output); } } QML_V4_END_INSTR(ConvertIntToString, unaryop) - QML_V4_BEGIN_INSTR(ConvertRealToBool, unaryop) + QML_V4_BEGIN_INSTR(ConvertIntToVariant, unaryop) + { + const Register &src = registers[instr->unaryop.src]; + Register &output = registers[instr->unaryop.output]; + if (src.isUndefined()) { + output.setUndefined(); + } else { + new (output.getvariantptr()) QVariant(src.getint()); + VARIANT_REGISTER(instr->unaryop.output); + } + } + QML_V4_END_INSTR(ConvertIntToVariant, unaryop) + + QML_V4_BEGIN_INSTR(ConvertNumberToBool, unaryop) { const Register &src = registers[instr->unaryop.src]; Register &output = registers[instr->unaryop.output]; if (src.isUndefined()) output.setUndefined(); - else output.setbool(src.getqreal() != 0); + else output.setbool(src.getnumber() != 0); } - QML_V4_END_INSTR(ConvertRealToBool, unaryop) + QML_V4_END_INSTR(ConvertNumberToBool, unaryop) - QML_V4_BEGIN_INSTR(ConvertRealToInt, unaryop) + QML_V4_BEGIN_INSTR(ConvertNumberToInt, unaryop) { const Register &src = registers[instr->unaryop.src]; Register &output = registers[instr->unaryop.output]; if (src.isUndefined()) output.setUndefined(); - else output.setint(toInt32(src.getqreal())); + else output.setint(toInt32(src.getnumber())); } - QML_V4_END_INSTR(ConvertRealToInt, unaryop) + QML_V4_END_INSTR(ConvertNumberToInt, unaryop) - QML_V4_BEGIN_INSTR(ConvertRealToString, unaryop) + QML_V4_BEGIN_INSTR(ConvertNumberToString, unaryop) { const Register &src = registers[instr->unaryop.src]; Register &output = registers[instr->unaryop.output]; @@ -981,11 +971,24 @@ if (src.isUndefined()) { output.setUndefined(); } else { - new (output.getstringptr()) QString(QString::number(src.getqreal())); + new (output.getstringptr()) QString(QString::number(src.getnumber(), 'g', 16)); STRING_REGISTER(instr->unaryop.output); } } - QML_V4_END_INSTR(ConvertRealToString, unaryop) + QML_V4_END_INSTR(ConvertNumberToString, unaryop) + + QML_V4_BEGIN_INSTR(ConvertNumberToVariant, unaryop) + { + const Register &src = registers[instr->unaryop.src]; + Register &output = registers[instr->unaryop.output]; + if (src.isUndefined()) { + output.setUndefined(); + } else { + new (output.getvariantptr()) QVariant(src.getnumber()); + VARIANT_REGISTER(instr->unaryop.output); + } + } + QML_V4_END_INSTR(ConvertNumberToVariant, unaryop) QML_V4_BEGIN_INSTR(ConvertStringToBool, unaryop) { @@ -1027,7 +1030,7 @@ } QML_V4_END_INSTR(ConvertStringToInt, unaryop) - QML_V4_BEGIN_INSTR(ConvertStringToReal, unaryop) + QML_V4_BEGIN_INSTR(ConvertStringToNumber, unaryop) { const Register &src = registers[instr->unaryop.src]; Register &output = registers[instr->unaryop.output]; @@ -1042,10 +1045,10 @@ output.cleanupString(); MARK_CLEAN_REGISTER(instr->unaryop.output); } - output.setqreal(tmp.toNumber()); + output.setnumber(tmp.toNumber()); } } - QML_V4_END_INSTR(ConvertStringToReal, unaryop) + QML_V4_END_INSTR(ConvertStringToNumber, unaryop) QML_V4_BEGIN_INSTR(ConvertStringToUrl, unaryop) { @@ -1090,6 +1093,25 @@ } QML_V4_END_INSTR(ConvertStringToUrl, unaryop) + QML_V4_BEGIN_INSTR(ConvertStringToVariant, unaryop) + { + const Register &src = registers[instr->unaryop.src]; + Register &output = registers[instr->unaryop.output]; + if (src.isUndefined()) { + output.setUndefined(); + } else { + const QString tmp(*src.getstringptr()); + if (instr->unaryop.src == instr->unaryop.output) { + output.cleanupString(); + MARK_CLEAN_REGISTER(instr->unaryop.output); + } + new (output.getvariantptr()) QVariant(tmp); + + VARIANT_REGISTER(instr->unaryop.output); + } + } + QML_V4_END_INSTR(ConvertStringToVariant, unaryop) + QML_V4_BEGIN_INSTR(ConvertUrlToBool, unaryop) { const Register &src = registers[instr->unaryop.src]; @@ -1127,6 +1149,25 @@ } QML_V4_END_INSTR(ConvertUrlToString, unaryop) + QML_V4_BEGIN_INSTR(ConvertUrlToVariant, unaryop) + { + const Register &src = registers[instr->unaryop.src]; + Register &output = registers[instr->unaryop.output]; + // ### NaN + if (src.isUndefined()) { + output.setUndefined(); + } else { + const QUrl tmp(*src.geturlptr()); + if (instr->unaryop.src == instr->unaryop.output) { + output.cleanupUrl(); + MARK_CLEAN_REGISTER(instr->unaryop.output); + } + new (output.getvariantptr()) QVariant(tmp); + VARIANT_REGISTER(instr->unaryop.output); + } + } + QML_V4_END_INSTR(ConvertUrlToVariant, unaryop) + QML_V4_BEGIN_INSTR(ConvertColorToBool, unaryop) { const Register &src = registers[instr->unaryop.src]; @@ -1161,6 +1202,25 @@ } QML_V4_END_INSTR(ConvertColorToString, unaryop) + QML_V4_BEGIN_INSTR(ConvertColorToVariant, unaryop) + { + const Register &src = registers[instr->unaryop.src]; + Register &output = registers[instr->unaryop.output]; + // ### NaN + if (src.isUndefined()) { + output.setUndefined(); + } else { + const QColor tmp(*src.getcolorptr()); + if (instr->unaryop.src == instr->unaryop.output) { + output.cleanupColor(); + MARK_CLEAN_REGISTER(instr->unaryop.output); + } + new (output.getvariantptr()) QVariant(tmp); + VARIANT_REGISTER(instr->unaryop.output); + } + } + QML_V4_END_INSTR(ConvertColorToVariant, unaryop) + QML_V4_BEGIN_INSTR(ConvertObjectToBool, unaryop) { const Register &src = registers[instr->unaryop.src]; @@ -1173,6 +1233,20 @@ } QML_V4_END_INSTR(ConvertObjectToBool, unaryop) + QML_V4_BEGIN_INSTR(ConvertObjectToVariant, unaryop) + { + const Register &src = registers[instr->unaryop.src]; + Register &output = registers[instr->unaryop.output]; + // ### NaN + if (src.isUndefined()) + output.setUndefined(); + else { + new (output.getvariantptr()) QVariant(qVariantFromValue(src.getQObject())); + VARIANT_REGISTER(instr->unaryop.output); + } + } + QML_V4_END_INSTR(ConvertObjectToVariant, unaryop) + QML_V4_BEGIN_INSTR(ConvertNullToObject, unaryop) { Register &output = registers[instr->unaryop.output]; @@ -1180,6 +1254,14 @@ } QML_V4_END_INSTR(ConvertNullToObject, unaryop) + QML_V4_BEGIN_INSTR(ConvertNullToVariant, unaryop) + { + Register &output = registers[instr->unaryop.output]; + new (output.getvariantptr()) QVariant(); + VARIANT_REGISTER(instr->unaryop.output); + } + QML_V4_END_INSTR(ConvertNullToVariant, unaryop) + QML_V4_BEGIN_INSTR(ResolveUrl, unaryop) { const Register &src = registers[instr->unaryop.src]; @@ -1198,75 +1280,75 @@ } QML_V4_END_INSTR(ResolveUrl, unaryop) - QML_V4_BEGIN_INSTR(MathSinReal, unaryop) + QML_V4_BEGIN_INSTR(MathSinNumber, unaryop) { const Register &src = registers[instr->unaryop.src]; Register &output = registers[instr->unaryop.output]; if (src.isUndefined()) output.setUndefined(); - else output.setqreal(qSin(src.getqreal())); + else output.setnumber(qSin(src.getnumber())); } - QML_V4_END_INSTR(MathSinReal, unaryop) + QML_V4_END_INSTR(MathSinNumber, unaryop) - QML_V4_BEGIN_INSTR(MathCosReal, unaryop) + QML_V4_BEGIN_INSTR(MathCosNumber, unaryop) { const Register &src = registers[instr->unaryop.src]; Register &output = registers[instr->unaryop.output]; if (src.isUndefined()) output.setUndefined(); - else output.setqreal(qCos(src.getqreal())); + else output.setnumber(qCos(src.getnumber())); } - QML_V4_END_INSTR(MathCosReal, unaryop) + QML_V4_END_INSTR(MathCosNumber, unaryop) - QML_V4_BEGIN_INSTR(MathAbsReal, unaryop) + QML_V4_BEGIN_INSTR(MathAbsNumber, unaryop) { const Register &src = registers[instr->unaryop.src]; Register &output = registers[instr->unaryop.output]; if (src.isUndefined()) output.setUndefined(); - else output.setqreal(qAbs(src.getqreal())); + else output.setnumber(qAbs(src.getnumber())); } - QML_V4_END_INSTR(MathAbsReal, unaryop) + QML_V4_END_INSTR(MathAbsNumber, unaryop) - QML_V4_BEGIN_INSTR(MathRoundReal, unaryop) + QML_V4_BEGIN_INSTR(MathRoundNumber, unaryop) { const Register &src = registers[instr->unaryop.src]; Register &output = registers[instr->unaryop.output]; if (src.isUndefined()) output.setUndefined(); - else output.setint(qRound(src.getqreal())); + else output.setint(qRound(src.getnumber())); } - QML_V4_END_INSTR(MathRoundReal, unaryop) + QML_V4_END_INSTR(MathRoundNumber, unaryop) - QML_V4_BEGIN_INSTR(MathFloorReal, unaryop) + QML_V4_BEGIN_INSTR(MathFloorNumber, unaryop) { const Register &src = registers[instr->unaryop.src]; Register &output = registers[instr->unaryop.output]; if (src.isUndefined()) output.setUndefined(); - else output.setint(qFloor(src.getqreal())); + else output.setint(qFloor(src.getnumber())); } - QML_V4_END_INSTR(MathFloorReal, unaryop) + QML_V4_END_INSTR(MathFloorNumber, unaryop) - QML_V4_BEGIN_INSTR(MathCeilReal, unaryop) + QML_V4_BEGIN_INSTR(MathCeilNumber, unaryop) { const Register &src = registers[instr->unaryop.src]; Register &output = registers[instr->unaryop.output]; if (src.isUndefined()) output.setUndefined(); - else output.setint(qCeil(src.getqreal())); + else output.setint(qCeil(src.getnumber())); } - QML_V4_END_INSTR(MathCeilReal, unaryop) + QML_V4_END_INSTR(MathCeilNumber, unaryop) - QML_V4_BEGIN_INSTR(MathPIReal, unaryop) + QML_V4_BEGIN_INSTR(MathPINumber, unaryop) { - static const qreal qmlPI = 2.0 * qAsin(1.0); + static const double qmlPI = 2.0 * qAsin(1.0); Register &output = registers[instr->unaryop.output]; - output.setqreal(qmlPI); + output.setnumber(qmlPI); } - QML_V4_END_INSTR(MathPIReal, unaryop) + QML_V4_END_INSTR(MathPINumber, unaryop) QML_V4_BEGIN_INSTR(LoadNull, null_value) registers[instr->null_value.reg].setNull(); QML_V4_END_INSTR(LoadNull, null_value) - QML_V4_BEGIN_INSTR(LoadReal, real_value) - registers[instr->real_value.reg].setqreal(instr->real_value.value); - QML_V4_END_INSTR(LoadReal, real_value) + QML_V4_BEGIN_INSTR(LoadNumber, number_value) + registers[instr->number_value.reg].setnumber(instr->number_value.value); + QML_V4_END_INSTR(LoadNumber, number_value) QML_V4_BEGIN_INSTR(LoadInt, int_value) registers[instr->int_value.reg].setint(instr->int_value.value); @@ -1313,12 +1395,12 @@ } QML_V4_END_INSTR(BitXorInt, binaryop) - QML_V4_BEGIN_INSTR(AddReal, binaryop) + QML_V4_BEGIN_INSTR(AddNumber, binaryop) { - registers[instr->binaryop.output].setqreal(registers[instr->binaryop.left].getqreal() + - registers[instr->binaryop.right].getqreal()); + registers[instr->binaryop.output].setnumber(registers[instr->binaryop.left].getnumber() + + registers[instr->binaryop.right].getnumber()); } - QML_V4_END_INSTR(AddReal, binaryop) + QML_V4_END_INSTR(AddNumber, binaryop) QML_V4_BEGIN_INSTR(AddString, binaryop) { @@ -1332,36 +1414,33 @@ } QML_V4_END_INSTR(AddString, binaryop) - QML_V4_BEGIN_INSTR(SubReal, binaryop) + QML_V4_BEGIN_INSTR(SubNumber, binaryop) { - registers[instr->binaryop.output].setqreal(registers[instr->binaryop.left].getqreal() - - registers[instr->binaryop.right].getqreal()); + registers[instr->binaryop.output].setnumber(registers[instr->binaryop.left].getnumber() - + registers[instr->binaryop.right].getnumber()); } - QML_V4_END_INSTR(SubReal, binaryop) + QML_V4_END_INSTR(SubNumber, binaryop) - QML_V4_BEGIN_INSTR(MulReal, binaryop) + QML_V4_BEGIN_INSTR(MulNumber, binaryop) { - registers[instr->binaryop.output].setqreal(registers[instr->binaryop.left].getqreal() * - registers[instr->binaryop.right].getqreal()); + registers[instr->binaryop.output].setnumber(registers[instr->binaryop.left].getnumber() * + registers[instr->binaryop.right].getnumber()); } - QML_V4_END_INSTR(MulReal, binaryop) + QML_V4_END_INSTR(MulNumber, binaryop) - QML_V4_BEGIN_INSTR(DivReal, binaryop) + QML_V4_BEGIN_INSTR(DivNumber, binaryop) { - registers[instr->binaryop.output].setqreal(registers[instr->binaryop.left].getqreal() / - registers[instr->binaryop.right].getqreal()); + registers[instr->binaryop.output].setnumber(registers[instr->binaryop.left].getnumber() / + registers[instr->binaryop.right].getnumber()); } - QML_V4_END_INSTR(DivReal, binaryop) + QML_V4_END_INSTR(DivNumber, binaryop) - QML_V4_BEGIN_INSTR(ModReal, binaryop) + QML_V4_BEGIN_INSTR(ModNumber, binaryop) { Register &target = registers[instr->binaryop.output]; const Register &left = registers[instr->binaryop.left]; const Register &right = registers[instr->binaryop.right]; - if (QMetaType::QReal == QMetaType::Float) - target.setqreal(::fmodf(left.getqreal(), right.getqreal())); - else - target.setqreal(::fmod(left.getqreal(), right.getqreal())); + target.setnumber(::fmod(left.getnumber(), right.getnumber())); } QML_V4_END_INSTR(ModInt, binaryop) @@ -1386,61 +1465,61 @@ } QML_V4_END_INSTR(URShiftInt, binaryop) - QML_V4_BEGIN_INSTR(GtReal, binaryop) + QML_V4_BEGIN_INSTR(GtNumber, binaryop) { - registers[instr->binaryop.output].setbool(registers[instr->binaryop.left].getqreal() > - registers[instr->binaryop.right].getqreal()); + registers[instr->binaryop.output].setbool(registers[instr->binaryop.left].getnumber() > + registers[instr->binaryop.right].getnumber()); } - QML_V4_END_INSTR(GtReal, binaryop) + QML_V4_END_INSTR(GtNumber, binaryop) - QML_V4_BEGIN_INSTR(LtReal, binaryop) + QML_V4_BEGIN_INSTR(LtNumber, binaryop) { - registers[instr->binaryop.output].setbool(registers[instr->binaryop.left].getqreal() < - registers[instr->binaryop.right].getqreal()); + registers[instr->binaryop.output].setbool(registers[instr->binaryop.left].getnumber() < + registers[instr->binaryop.right].getnumber()); } - QML_V4_END_INSTR(LtReal, binaryop) + QML_V4_END_INSTR(LtNumber, binaryop) - QML_V4_BEGIN_INSTR(GeReal, binaryop) + QML_V4_BEGIN_INSTR(GeNumber, binaryop) { - registers[instr->binaryop.output].setbool(registers[instr->binaryop.left].getqreal() >= - registers[instr->binaryop.right].getqreal()); + registers[instr->binaryop.output].setbool(registers[instr->binaryop.left].getnumber() >= + registers[instr->binaryop.right].getnumber()); } - QML_V4_END_INSTR(GeReal, binaryop) + QML_V4_END_INSTR(GeNumber, binaryop) - QML_V4_BEGIN_INSTR(LeReal, binaryop) + QML_V4_BEGIN_INSTR(LeNumber, binaryop) { - registers[instr->binaryop.output].setbool(registers[instr->binaryop.left].getqreal() <= - registers[instr->binaryop.right].getqreal()); + registers[instr->binaryop.output].setbool(registers[instr->binaryop.left].getnumber() <= + registers[instr->binaryop.right].getnumber()); } - QML_V4_END_INSTR(LeReal, binaryop) + QML_V4_END_INSTR(LeNumber, binaryop) - QML_V4_BEGIN_INSTR(EqualReal, binaryop) + QML_V4_BEGIN_INSTR(EqualNumber, binaryop) { - registers[instr->binaryop.output].setbool(registers[instr->binaryop.left].getqreal() == - registers[instr->binaryop.right].getqreal()); + registers[instr->binaryop.output].setbool(registers[instr->binaryop.left].getnumber() == + registers[instr->binaryop.right].getnumber()); } - QML_V4_END_INSTR(EqualReal, binaryop) + QML_V4_END_INSTR(EqualNumber, binaryop) - QML_V4_BEGIN_INSTR(NotEqualReal, binaryop) + QML_V4_BEGIN_INSTR(NotEqualNumber, binaryop) { - registers[instr->binaryop.output].setbool(registers[instr->binaryop.left].getqreal() != - registers[instr->binaryop.right].getqreal()); + registers[instr->binaryop.output].setbool(registers[instr->binaryop.left].getnumber() != + registers[instr->binaryop.right].getnumber()); } - QML_V4_END_INSTR(NotEqualReal, binaryop) + QML_V4_END_INSTR(NotEqualNumber, binaryop) - QML_V4_BEGIN_INSTR(StrictEqualReal, binaryop) + QML_V4_BEGIN_INSTR(StrictEqualNumber, binaryop) { - registers[instr->binaryop.output].setbool(registers[instr->binaryop.left].getqreal() == - registers[instr->binaryop.right].getqreal()); + registers[instr->binaryop.output].setbool(registers[instr->binaryop.left].getnumber() == + registers[instr->binaryop.right].getnumber()); } - QML_V4_END_INSTR(StrictEqualReal, binaryop) + QML_V4_END_INSTR(StrictEqualNumber, binaryop) - QML_V4_BEGIN_INSTR(StrictNotEqualReal, binaryop) + QML_V4_BEGIN_INSTR(StrictNotEqualNumber, binaryop) { - registers[instr->binaryop.output].setbool(registers[instr->binaryop.left].getqreal() != - registers[instr->binaryop.right].getqreal()); + registers[instr->binaryop.output].setbool(registers[instr->binaryop.left].getnumber() != + registers[instr->binaryop.right].getnumber()); } - QML_V4_END_INSTR(StrictNotEqualReal, binaryop) + QML_V4_END_INSTR(StrictNotEqualNumber, binaryop) QML_V4_BEGIN_INSTR(GtString, binaryop) { @@ -1586,25 +1665,25 @@ } QML_V4_END_INSTR(StrictNotEqualObject, binaryop) - QML_V4_BEGIN_INSTR(MathMaxReal, binaryop) + QML_V4_BEGIN_INSTR(MathMaxNumber, binaryop) { const Register &left = registers[instr->binaryop.left]; const Register &right = registers[instr->binaryop.right]; Register &output = registers[instr->binaryop.output]; if (left.isUndefined() || right.isUndefined()) output.setUndefined(); - else output.setqreal(qMax(left.getqreal(), right.getqreal())); + else output.setnumber(qMax(left.getnumber(), right.getnumber())); } - QML_V4_END_INSTR(MathMaxReal, binaryop) + QML_V4_END_INSTR(MathMaxNumber, binaryop) - QML_V4_BEGIN_INSTR(MathMinReal, binaryop) + QML_V4_BEGIN_INSTR(MathMinNumber, binaryop) { const Register &left = registers[instr->binaryop.left]; const Register &right = registers[instr->binaryop.right]; Register &output = registers[instr->binaryop.output]; if (left.isUndefined() || right.isUndefined()) output.setUndefined(); - else output.setqreal(qMin(left.getqreal(), right.getqreal())); + else output.setnumber(qMin(left.getnumber(), right.getnumber())); } - QML_V4_END_INSTR(MathMinReal, binaryop) + QML_V4_END_INSTR(MathMinNumber, binaryop) QML_V4_BEGIN_INSTR(NewString, construct) { @@ -1633,11 +1712,17 @@ if (!object) { THROW_EXCEPTION(instr->fetch.exceptionId); } else { - reg.init((Register::Type)instr->fetch.valueType); + const Register::Type valueType = (Register::Type)instr->fetch.valueType; + reg.init(valueType); if (instr->fetch.valueType >= FirstCleanupType) MARK_REGISTER(instr->fetch.reg); void *argv[] = { reg.typeDataPtr(), 0 }; QMetaObject::metacall(object, QMetaObject::ReadProperty, instr->fetch.index, argv); + if (valueType == FloatType) { + // promote floats + const double v = reg.getfloat(); + reg.setnumber(v); + } } } QML_V4_END_INSTR(Fetch, fetch) @@ -1675,6 +1760,12 @@ } } + if (instr->store.valueType == FloatType) { + // cast numbers to floats + const float v = (float) data.getnumber(); + data.setfloat(v); + } + int status = -1; void *argv[] = { data.typeDataPtr(), 0, &status, &storeFlags }; QMetaObject::metacall(output, QMetaObject::WriteProperty, @@ -1713,22 +1804,14 @@ executedBlocks |= instr->blockop.block; QML_V4_END_INSTR(Block, blockop) - // XXX not applicable in v8 - QML_V4_BEGIN_INSTR(InitString, initstring) -// if (!identifiers[instr->initstring.offset].identifier) { -// quint32 len = *(quint32 *)(data + instr->initstring.dataIdx); -// QChar *strdata = (QChar *)(data + instr->initstring.dataIdx + sizeof(quint32)); - -// QString str = QString::fromRawData(strdata, len); - -// // identifiers[instr->initstring.offset] = engine->objectClass->createPersistentIdentifier(str); -// } - QML_V4_END_INSTR(InitString, initstring) - QML_V4_BEGIN_INSTR(CleanupRegister, cleanup) registers[instr->cleanup.reg].cleanup(); QML_V4_END_INSTR(CleanupRegister, cleanup) + QML_V4_BEGIN_INSTR(Throw, throwop) + THROW_VALUE_EXCEPTION_STR(instr->throwop.exceptionId, *registers[instr->throwop.message].getstringptr()); + QML_V4_END_INSTR(Throw, throwop) + #ifdef QML_THREADED_INTERPRETER // nothing to do #else diff -Nru qt5-declarative-0.1~git20120402/src/qml/qml/v4/qv4bindings_p.h qt5-declarative-0.1~git20120423/src/qml/qml/v4/qv4bindings_p.h --- qt5-declarative-0.1~git20120402/src/qml/qml/v4/qv4bindings_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/qml/qml/v4/qv4bindings_p.h 2012-04-23 11:44:59.000000000 +0000 @@ -141,9 +141,9 @@ inline void subscribeId(QQmlContextData *p, int idIndex, int subIndex); inline void subscribe(QObject *o, int notifyIndex, int subIndex); - inline static qint32 toInt32(qreal n); - static const qreal D32; - static quint32 toUint32(qreal n); + inline static qint32 toInt32(double n); + static const double D32; + static quint32 toUint32(double n); }; diff -Nru qt5-declarative-0.1~git20120402/src/qml/qml/v4/qv4compiler.cpp qt5-declarative-0.1~git20120423/src/qml/qml/v4/qv4compiler.cpp --- qt5-declarative-0.1~git20120402/src/qml/qml/v4/qv4compiler.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/qml/qml/v4/qv4compiler.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -62,7 +62,9 @@ using namespace QQmlJS; QV4CompilerPrivate::QV4CompilerPrivate() - : _function(0) , _block(0) , _discarded(false), registerCount(0) + : subscriptionOffset(0) + , _function(0) , _block(0) , _discarded(false), registerCount(0) + , bindingLine(0), bindingColumn(0) { } @@ -73,6 +75,8 @@ { bytecode.clear(); + this->bindingLine = line; + this->bindingColumn = column; this->currentReg = _function->tempCount; this->registerCount = qMax(this->registerCount, this->currentReg); @@ -226,8 +230,9 @@ gen(i); } break; - case IR::RealType: { - Instr::LoadReal i; + case IR::FloatType: + case IR::NumberType: { + Instr::LoadNumber i; i.reg = currentReg; i.value = e->value; gen(i); @@ -316,7 +321,7 @@ Instr::LoadAttached attached; attached.output = currentReg; attached.reg = currentReg; - attached.exceptionId = exceptionId(e->line, e->column); + attached.exceptionId = exceptionId(bindingLine, bindingColumn); if (e->declarativeType->attachedPropertiesId() == -1) discard(); attached.id = e->declarativeType->attachedPropertiesId(); @@ -351,8 +356,11 @@ QQmlRegisterType regType; switch (propTy) { - case QMetaType::QReal: - regType = QRealType; + case QMetaType::Float: + regType = FloatType; + break; + case QMetaType::Double: + regType = NumberType; break; case QMetaType::Bool: regType = BoolType; @@ -369,6 +377,9 @@ case QMetaType::QColor: regType = QColorType; break; + case QMetaType::QVariant: + regType = QVariantType; + break; default: if (propTy == QQmlMetaType::QQuickAnchorLineMetaTypeId()) { @@ -458,14 +469,14 @@ } break; case IR::OpUMinus: - if (e->expr->type == IR::RealType) { - Instr::UnaryMinusReal i; + if (IR::isRealType(e->expr->type)) { + Instr::UnaryMinusNumber i; i.output = currentReg; i.src = src; gen(i); } else if (e->expr->type == IR::IntType) { - convertToReal(e->expr, currentReg); - Instr::UnaryMinusReal i; + convertToNumber(e->expr, currentReg); + Instr::UnaryMinusNumber i; i.output = currentReg; i.src = src; gen(i); @@ -475,14 +486,14 @@ break; case IR::OpUPlus: - if (e->expr->type == IR::RealType) { - Instr::UnaryPlusReal i; + if (IR::isRealType(e->expr->type)) { + Instr::UnaryPlusNumber i; i.output = currentReg; i.src = src; gen(i); } else if (e->expr->type == IR::IntType) { - convertToReal(e->expr, currentReg); - Instr::UnaryPlusReal i; + convertToNumber(e->expr, currentReg); + Instr::UnaryPlusNumber i; i.output = currentReg; i.src = src; gen(i); @@ -522,25 +533,26 @@ } // switch } -void QV4CompilerPrivate::convertToReal(IR::Expr *expr, int reg) +void QV4CompilerPrivate::convertToNumber(IR::Expr *expr, int reg) { - if (expr->type == IR::RealType) + if (expr->type == IR::NumberType) return; switch (expr->type) { case IR::BoolType: { - Instr::ConvertBoolToReal i; + Instr::ConvertBoolToNumber i; i.output = i.src = reg; gen(i); } break; case IR::IntType: { - Instr::ConvertIntToReal i; + Instr::ConvertIntToNumber i; i.output = i.src = reg; gen(i); } break; - case IR::RealType: + case IR::FloatType: + case IR::NumberType: // nothing to do return; @@ -566,8 +578,9 @@ // nothing to do return; - case IR::RealType: { - Instr::ConvertRealToInt i; + case IR::FloatType: + case IR::NumberType: { + Instr::ConvertNumberToInt i; i.output = i.src = reg; gen(i); } break; @@ -594,8 +607,9 @@ gen(i); } break; - case IR::RealType: { - Instr::ConvertRealToBool i; + case IR::FloatType: + case IR::NumberType: { + Instr::ConvertNumberToBool i; i.output = i.src = reg; gen(i); } return; @@ -643,19 +657,19 @@ case IR::OpAdd: if (e->type == IR::StringType) return V4Instr::AddString; - return V4Instr::AddReal; + return V4Instr::AddNumber; case IR::OpSub: - return V4Instr::SubReal; + return V4Instr::SubNumber; case IR::OpMul: - return V4Instr::MulReal; + return V4Instr::MulNumber; case IR::OpDiv: - return V4Instr::DivReal; + return V4Instr::DivNumber; case IR::OpMod: - return V4Instr::ModReal; + return V4Instr::ModNumber; case IR::OpLShift: return V4Instr::LShiftInt; @@ -669,50 +683,50 @@ case IR::OpGt: if (e->left->type == IR::StringType) return V4Instr::GtString; - return V4Instr::GtReal; + return V4Instr::GtNumber; case IR::OpLt: if (e->left->type == IR::StringType) return V4Instr::LtString; - return V4Instr::LtReal; + return V4Instr::LtNumber; case IR::OpGe: if (e->left->type == IR::StringType) return V4Instr::GeString; - return V4Instr::GeReal; + return V4Instr::GeNumber; case IR::OpLe: if (e->left->type == IR::StringType) return V4Instr::LeString; - return V4Instr::LeReal; + return V4Instr::LeNumber; case IR::OpEqual: if (e->left->type == IR::ObjectType || e->right->type == IR::ObjectType) return V4Instr::EqualObject; if (e->left->type == IR::StringType) return V4Instr::EqualString; - return V4Instr::EqualReal; + return V4Instr::EqualNumber; case IR::OpNotEqual: if (e->left->type == IR::ObjectType || e->right->type == IR::ObjectType) return V4Instr::NotEqualObject; if (e->left->type == IR::StringType) return V4Instr::NotEqualString; - return V4Instr::NotEqualReal; + return V4Instr::NotEqualNumber; case IR::OpStrictEqual: if (e->left->type == IR::ObjectType || e->right->type == IR::ObjectType) return V4Instr::StrictEqualObject; if (e->left->type == IR::StringType) return V4Instr::StrictEqualString; - return V4Instr::StrictEqualReal; + return V4Instr::StrictEqualNumber; case IR::OpStrictNotEqual: if (e->left->type == IR::ObjectType || e->right->type == IR::ObjectType) return V4Instr::StrictNotEqualObject; if (e->left->type == IR::StringType) return V4Instr::StrictNotEqualString; - return V4Instr::StrictNotEqualReal; + return V4Instr::StrictNotEqualNumber; case IR::OpAnd: case IR::OpOr: @@ -733,12 +747,26 @@ int left = currentReg; int right = currentReg + 1; - traceExpression(e->left, left); - traceExpression(e->right, right); + if (e->left->asTemp() && e->type != IR::StringType) + left = e->left->asTemp()->index; + else + traceExpression(e->left, left); - // At this point it is possible that the type of the - // subexpressions is different. This can happen because - // we keep BINOP expressions in HIR. + if (IR::Temp *t = e->right->asTemp()) + right = t->index; + else + traceExpression(e->right, right); + + if (e->left->type != e->right->type) { + if (qmlVerboseCompiler()) + qWarning().nospace() << "invalid operands to binary operator " << IR::binaryOperator(e->op) + << "(`" << IR::binaryOperator(e->left->type) + << "' and `" + << IR::binaryOperator(e->right->type) + << "'"; + discard(); + return; + } switch (e->op) { case IR::OpInvalid: @@ -766,8 +794,8 @@ case IR::OpAdd: if (e->type != IR::StringType) { - convertToReal(e->left, left); - convertToReal(e->right, right); + convertToNumber(e->left, left); + convertToNumber(e->right, right); } break; @@ -775,8 +803,8 @@ case IR::OpMul: case IR::OpDiv: case IR::OpMod: - convertToReal(e->left, left); - convertToReal(e->right, right); + convertToNumber(e->left, left); + convertToNumber(e->right, right); break; case IR::OpGt: @@ -788,8 +816,8 @@ case IR::OpStrictEqual: case IR::OpStrictNotEqual: if (e->left->type >= IR::FirstNumberType) { - convertToReal(e->left, left); - convertToReal(e->right, right); + convertToNumber(e->left, left); + convertToNumber(e->right, right); } break; @@ -813,7 +841,7 @@ { if (IR::Name *name = call->base->asName()) { IR::Expr *arg = call->onlyArgument(); - if (arg != 0 && arg->type == IR::RealType) { + if (arg != 0 && IR::isRealType(arg->type)) { traceExpression(arg, currentReg); switch (name->builtin) { @@ -821,37 +849,37 @@ break; case IR::MathSinBultinFunction: { - Instr::MathSinReal i; + Instr::MathSinNumber i; i.output = i.src = currentReg; gen(i); } return; case IR::MathCosBultinFunction: { - Instr::MathCosReal i; + Instr::MathCosNumber i; i.output = i.src = currentReg; gen(i); } return; case IR::MathAbsBuiltinFunction: { - Instr::MathAbsReal i; + Instr::MathAbsNumber i; i.output = i.src = currentReg; gen(i); } return; case IR::MathRoundBultinFunction: { - Instr::MathRoundReal i; + Instr::MathRoundNumber i; i.output = i.src = currentReg; gen(i); } return; case IR::MathFloorBultinFunction: { - Instr::MathFloorReal i; + Instr::MathFloorNumber i; i.output = i.src = currentReg; gen(i); } return; case IR::MathCeilBuiltinFunction: { - Instr::MathCeilReal i; + Instr::MathCeilNumber i; i.output = i.src = currentReg; gen(i); } return; @@ -869,21 +897,21 @@ IR::Expr *arg1 = call->args->expr; IR::Expr *arg2 = call->args->next->expr; - if (arg1 != 0 && arg1->type == IR::RealType && - arg2 != 0 && arg2->type == IR::RealType) { + if (arg1 != 0 && IR::isRealType(arg1->type) && + arg2 != 0 && IR::isRealType(arg2->type)) { traceExpression(arg1, currentReg); traceExpression(arg2, currentReg + 1); if (name->builtin == IR::MathMaxBuiltinFunction) { - Instr::MathMaxReal i; + Instr::MathMaxNumber i; i.left = currentReg; i.right = currentReg + 1; i.output = currentReg; gen(i); return; } else if (name->builtin == IR::MathMinBuiltinFunction) { - Instr::MathMinReal i; + Instr::MathMinNumber i; i.left = currentReg; i.right = currentReg + 1; i.output = currentReg; @@ -917,7 +945,17 @@ quint8 dest = target->index; - if (target->type != s->source->type) { + IR::Type targetTy = s->target->type; + IR::Type sourceTy = s->source->type; + + // promote the floats + if (sourceTy == IR::FloatType) + sourceTy = IR::NumberType; + + if (targetTy == IR::FloatType) + targetTy = IR::NumberType; + + if (sourceTy != targetTy) { quint8 src = dest; if (IR::Temp *t = s->source->asTemp()) @@ -926,17 +964,26 @@ traceExpression(s->source, dest); V4Instr::Type opcode = V4Instr::Noop; - IR::Type targetTy = s->target->type; - IR::Type sourceTy = s->source->type; if (sourceTy == IR::UrlType) { switch (targetTy) { case IR::BoolType: case IR::StringType: + case IR::VariantType: // nothing to do. V4 will generate optimized // url-to-xxx conversions. break; default: { + if (s->isMoveForReturn) { + V4Instr instr; + instr.throwop.exceptionId = exceptionId(bindingLine, bindingColumn); + registerLiteralString(dest, _function->newString(QString::fromUtf8("Unable to assign %1 to %2") + .arg(QLatin1String(IR::typeName(sourceTy))) + .arg(QLatin1String(IR::typeName(targetTy))))); + instr.throwop.message = dest; + gen(V4Instr::Throw, instr); + return; + } // generate a UrlToString conversion and fix // the type of the source expression. V4Instr conv; @@ -952,7 +999,7 @@ if (targetTy == IR::BoolType) { switch (sourceTy) { case IR::IntType: opcode = V4Instr::ConvertIntToBool; break; - case IR::RealType: opcode = V4Instr::ConvertRealToBool; break; + case IR::NumberType: opcode = V4Instr::ConvertNumberToBool; break; case IR::StringType: opcode = V4Instr::ConvertStringToBool; break; case IR::UrlType: opcode = V4Instr::ConvertUrlToBool; break; case IR::ColorType: opcode = V4Instr::ConvertColorToBool; break; @@ -962,33 +1009,44 @@ } else if (targetTy == IR::IntType) { switch (sourceTy) { case IR::BoolType: opcode = V4Instr::ConvertBoolToInt; break; - case IR::RealType: { + case IR::NumberType: { if (s->isMoveForReturn) - opcode = V4Instr::MathRoundReal; + opcode = V4Instr::MathRoundNumber; else - opcode = V4Instr::ConvertRealToInt; + opcode = V4Instr::ConvertNumberToInt; break; } case IR::StringType: opcode = V4Instr::ConvertStringToInt; break; default: break; } // switch - } else if (targetTy == IR::RealType) { + } else if (IR::isRealType(targetTy)) { switch (sourceTy) { - case IR::BoolType: opcode = V4Instr::ConvertBoolToReal; break; - case IR::IntType: opcode = V4Instr::ConvertIntToReal; break; - case IR::StringType: opcode = V4Instr::ConvertStringToReal; break; + case IR::BoolType: opcode = V4Instr::ConvertBoolToNumber; break; + case IR::IntType: opcode = V4Instr::ConvertIntToNumber; break; + case IR::StringType: opcode = V4Instr::ConvertStringToNumber; break; default: break; } // switch } else if (targetTy == IR::StringType) { switch (sourceTy) { case IR::BoolType: opcode = V4Instr::ConvertBoolToString; break; case IR::IntType: opcode = V4Instr::ConvertIntToString; break; - case IR::RealType: opcode = V4Instr::ConvertRealToString; break; + case IR::NumberType: opcode = V4Instr::ConvertNumberToString; break; case IR::UrlType: opcode = V4Instr::ConvertUrlToString; break; case IR::ColorType: opcode = V4Instr::ConvertColorToString; break; default: break; } // switch } else if (targetTy == IR::UrlType) { + if (s->isMoveForReturn && sourceTy != IR::StringType) { + V4Instr instr; + instr.throwop.exceptionId = exceptionId(bindingLine, bindingColumn); + registerLiteralString(dest, _function->newString(QString::fromUtf8("Unable to assign %1 to %2") + .arg(QLatin1String(IR::typeName(sourceTy))) + .arg(QLatin1String(IR::typeName(targetTy))))); + instr.throwop.message = dest; + gen(V4Instr::Throw, instr); + return; + } + V4Instr convToString; convToString.unaryop.output = dest; convToString.unaryop.src = src; @@ -997,7 +1055,7 @@ switch (sourceTy) { case IR::BoolType: gen(V4Instr::ConvertBoolToString, convToString); sourceTy = IR::StringType; break; case IR::IntType: gen(V4Instr::ConvertIntToString, convToString); sourceTy = IR::StringType; break; - case IR::RealType: gen(V4Instr::ConvertRealToString, convToString); sourceTy = IR::StringType; break; + case IR::NumberType: gen(V4Instr::ConvertNumberToString, convToString); sourceTy = IR::StringType; break; case IR::ColorType: gen(V4Instr::ConvertColorToString, convToString); sourceTy = IR::StringType; break; default: break; } // switch @@ -1014,6 +1072,20 @@ case IR::NullType: opcode = V4Instr::ConvertNullToObject; break; default: break; } // switch + } else if (targetTy == IR::VariantType) { + if (s->isMoveForReturn) { + switch (sourceTy) { + case IR::BoolType: opcode = V4Instr::ConvertBoolToVariant; break; + case IR::IntType: opcode = V4Instr::ConvertIntToVariant; break; + case IR::NumberType: opcode = V4Instr::ConvertNumberToVariant; break; + case IR::UrlType: opcode = V4Instr::ConvertUrlToVariant; break; + case IR::ColorType: opcode = V4Instr::ConvertColorToVariant; break; + case IR::StringType: opcode = V4Instr::ConvertStringToVariant; break; + case IR::ObjectType: opcode = V4Instr::ConvertObjectToVariant; break; + case IR::NullType: opcode = V4Instr::ConvertNullToVariant; break; + default: break; + } // switch + } } if (opcode != V4Instr::Noop) { V4Instr conv; @@ -1087,14 +1159,18 @@ case IR::ObjectType: test.regType = QMetaType::QObjectStar; break; + case IR::VariantType: + test.regType = QMetaType::QVariant; + break; case IR::BoolType: test.regType = QMetaType::Bool; break; case IR::IntType: test.regType = QMetaType::Int; break; - case IR::RealType: - test.regType = QMetaType::QReal; + case IR::FloatType: + case IR::NumberType: + test.regType = QMetaType::Double; break; default: discard(); @@ -1107,6 +1183,7 @@ store.output = 0; store.index = expression->property->index; store.reg = storeReg; + store.valueType = s->type == IR::FloatType ? FloatType : 0; store.exceptionId = exceptionId(s->line, s->column); gen(store); } @@ -1118,7 +1195,6 @@ qWarning() << "Program.bindings:" << program->bindings; qWarning() << "Program.dataLength:" << program->dataLength; qWarning() << "Program.subscriptions:" << program->subscriptions; - qWarning() << "Program.indentifiers:" << program->identifiers; const int programSize = program->instructionCount; const char *start = program->instructions(); @@ -1136,8 +1212,8 @@ data = committed.data; exceptions = committed.exceptions; usedSubscriptionIds.clear(); - subscriptionIds = committed.subscriptionIds; - registeredStrings = committed.registeredStrings; + subscriptionIds.clear(); + subscriptionOffset = committed.subscriptionCount; bytecode.clear(); patches.clear(); pool.clear(); @@ -1158,8 +1234,9 @@ committed.bytecode.append(bytecode.constData(), bytecode.size()); committed.data = data; committed.exceptions = exceptions; - committed.subscriptionIds = subscriptionIds; - committed.registeredStrings = registeredStrings; + committed.subscriptionCount = subscriptionOffset + subscriptionIds.count(); + if (bindingsDump()) + committed.subscriptions.append(subscriptionIds); return rv; } @@ -1211,7 +1288,7 @@ qerr << endl; } - if (discarded || subscriptionIds.count() > 0xFFFF || registeredStrings.count() > 0xFFFF || registerCount > 31) + if (discarded || subscriptionIds.count() > 0xFFFF || registerCount > 31) return false; return true; @@ -1235,32 +1312,6 @@ return reg; } -// Returns an identifier offset -int QV4CompilerPrivate::registerString(const QString &string) -{ - Q_ASSERT(!string.isEmpty()); - - QPair *iter = registeredStrings.value(string); - - if (!iter) { - quint32 len = string.length(); - QByteArray lendata((const char *)&len, sizeof(quint32)); - QByteArray strdata((const char *)string.constData(), string.length() * sizeof(QChar)); - strdata.prepend(lendata); - int rv = data.count(); - data += strdata; - - iter = ®isteredStrings[string]; - *iter = qMakePair(registeredStrings.count(), rv); - } - - Instr::InitString reg; - reg.offset = iter->first; - reg.dataIdx = iter->second; - gen(reg); - return reg.offset; -} - /*! Returns true if the current expression has not already subscribed to \a sub in currentBlockMask. */ @@ -1284,7 +1335,7 @@ QString str = sub.join(QLatin1String(".")); int *iter = subscriptionIds.value(str); if (!iter) { - int count = subscriptionIds.count(); + int count = subscriptionOffset + subscriptionIds.count(); iter = &subscriptionIds[str]; *iter = count; } @@ -1383,8 +1434,8 @@ QVector header; QVector data; - for (int ii = 0; ii < committed.subscriptionIds.count(); ++ii) { - header.append(committed.subscriptionIds.count() + data.count()); + for (int ii = 0; ii < committed.subscriptionCount; ++ii) { + header.append(committed.subscriptionCount + data.count()); const QList > &bindings = table[ii]; data.append(bindings.count()); for (int jj = 0; jj < bindings.count(); ++jj) { @@ -1442,8 +1493,7 @@ data += d->buildExceptionData(); prog.dataLength = 4 * ((data.size() + 3) / 4); - prog.subscriptions = d->committed.subscriptionIds.count(); - prog.identifiers = d->committed.registeredStrings.count(); + prog.subscriptions = d->committed.subscriptionCount; prog.instructionCount = bytecode.count(); int size = sizeof(QV4Program) + bytecode.count(); size += prog.dataLength; @@ -1460,12 +1510,13 @@ if (bindingsDump()) { qWarning().nospace() << "Subscription slots:"; - for (QQmlAssociationList::ConstIterator iter = d->committed.subscriptionIds.begin(); - iter != d->committed.subscriptionIds.end(); - ++iter) { - qWarning().nospace() << " " << iter->first << "\t-> " << iter->second; + QQmlAssociationList subscriptionIds; + foreach (subscriptionIds, d->committed.subscriptions) { + for (QQmlAssociationList::ConstIterator iter = subscriptionIds.begin(); + iter != subscriptionIds.end(); ++iter) { + qWarning().nospace() << " " << iter->first << "\t-> " << iter->second; + } } - QV4Compiler::dump(programData); } diff -Nru qt5-declarative-0.1~git20120402/src/qml/qml/v4/qv4compiler_p_p.h qt5-declarative-0.1~git20120423/src/qml/qml/v4/qv4compiler_p_p.h --- qt5-declarative-0.1~git20120402/src/qml/qml/v4/qv4compiler_p_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/qml/qml/v4/qv4compiler_p_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -128,8 +128,6 @@ bool compile(QQmlJS::AST::Node *); int registerLiteralString(quint8 reg, const QStringRef &); - int registerString(const QString &); - QQmlAssociationList > registeredStrings; QByteArray data; bool blockNeedsSubscription(const QStringList &); @@ -141,7 +139,7 @@ QVector exceptions; QQmlAssociationList usedSubscriptionIds; - + int subscriptionOffset; QQmlAssociationList subscriptionIds; QQmlJS::Bytecode bytecode; @@ -156,17 +154,17 @@ QQmlPool pool; // Committed binding data - struct { + struct Committed { + Committed(): subscriptionCount(0) {} QList offsets; QList > dependencies; //QQmlJS::Bytecode bytecode; QByteArray bytecode; QByteArray data; - QQmlAssociationList subscriptionIds; QVector exceptions; - - QQmlAssociationList > registeredStrings; + int subscriptionCount; + QList > subscriptions; int count() const { return offsets.count(); } } committed; @@ -174,7 +172,7 @@ QByteArray buildSignalTable() const; QByteArray buildExceptionData() const; - void convertToReal(QQmlJS::IR::Expr *expr, int reg); + void convertToNumber(QQmlJS::IR::Expr *expr, int reg); void convertToInt(QQmlJS::IR::Expr *expr, int reg); void convertToBool(QQmlJS::IR::Expr *expr, int reg); quint8 instructionOpcode(QQmlJS::IR::Binop *e); @@ -235,6 +233,8 @@ bool usedSubscriptionIdsChanged; quint32 currentBlockMask; + int bindingLine; + int bindingColumn; }; diff -Nru qt5-declarative-0.1~git20120402/src/qml/qml/v4/qv4instruction.cpp qt5-declarative-0.1~git20120423/src/qml/qml/v4/qv4instruction.cpp --- qt5-declarative-0.1~git20120402/src/qml/qml/v4/qv4instruction.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/qml/qml/v4/qv4instruction.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -123,14 +123,14 @@ case V4Instr::UnaryNot: INSTR_DUMP << "\t" << "UnaryNot" << "\t\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; break; - case V4Instr::UnaryMinusReal: - INSTR_DUMP << "\t" << "UnaryMinusReal" << "\t\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; + case V4Instr::UnaryMinusNumber: + INSTR_DUMP << "\t" << "UnaryMinusNumber" << "\t\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; break; case V4Instr::UnaryMinusInt: INSTR_DUMP << "\t" << "UnaryMinusInt" << "\t\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; break; - case V4Instr::UnaryPlusReal: - INSTR_DUMP << "\t" << "UnaryPlusReal" << "\t\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; + case V4Instr::UnaryPlusNumber: + INSTR_DUMP << "\t" << "UnaryPlusNumber" << "\t\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; break; case V4Instr::UnaryPlusInt: INSTR_DUMP << "\t" << "UnaryPlusInt" << "\t\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; @@ -138,29 +138,38 @@ case V4Instr::ConvertBoolToInt: INSTR_DUMP << "\t" << "ConvertBoolToInt" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; break; - case V4Instr::ConvertBoolToReal: - INSTR_DUMP << "\t" << "ConvertBoolToReal" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; + case V4Instr::ConvertBoolToNumber: + INSTR_DUMP << "\t" << "ConvertBoolToNumber" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; break; case V4Instr::ConvertBoolToString: INSTR_DUMP << "\t" << "ConvertBoolToString" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; break; + case V4Instr::ConvertBoolToVariant: + INSTR_DUMP << "\t" << "ConvertBoolToVariant" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; + break; case V4Instr::ConvertIntToBool: INSTR_DUMP << "\t" << "ConvertIntToBool" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; break; - case V4Instr::ConvertIntToReal: - INSTR_DUMP << "\t" << "ConvertIntToReal" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; + case V4Instr::ConvertIntToNumber: + INSTR_DUMP << "\t" << "ConvertIntToNumber" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; break; case V4Instr::ConvertIntToString: INSTR_DUMP << "\t" << "ConvertIntToString" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; break; - case V4Instr::ConvertRealToBool: - INSTR_DUMP << "\t" << "ConvertRealToBool" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; + case V4Instr::ConvertIntToVariant: + INSTR_DUMP << "\t" << "ConvertIntToVariant" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; + break; + case V4Instr::ConvertNumberToBool: + INSTR_DUMP << "\t" << "ConvertNumberToBool" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; + break; + case V4Instr::ConvertNumberToInt: + INSTR_DUMP << "\t" << "ConvertNumberToInt" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; break; - case V4Instr::ConvertRealToInt: - INSTR_DUMP << "\t" << "ConvertRealToInt" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; + case V4Instr::ConvertNumberToString: + INSTR_DUMP << "\t" << "ConvertNumberToString" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; break; - case V4Instr::ConvertRealToString: - INSTR_DUMP << "\t" << "ConvertRealToString" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; + case V4Instr::ConvertNumberToVariant: + INSTR_DUMP << "\t" << "ConvertNumberToVariant" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; break; case V4Instr::ConvertStringToBool: INSTR_DUMP << "\t" << "ConvertStringToBool" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; @@ -168,8 +177,8 @@ case V4Instr::ConvertStringToInt: INSTR_DUMP << "\t" << "ConvertStringToInt" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; break; - case V4Instr::ConvertStringToReal: - INSTR_DUMP << "\t" << "ConvertStringToReal" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; + case V4Instr::ConvertStringToNumber: + INSTR_DUMP << "\t" << "ConvertStringToNumber" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; break; case V4Instr::ConvertStringToUrl: INSTR_DUMP << "\t" << "ConvertStringToUrl" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; @@ -177,53 +186,68 @@ case V4Instr::ConvertStringToColor: INSTR_DUMP << "\t" << "ConvertStringToColor" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; break; + case V4Instr::ConvertStringToVariant: + INSTR_DUMP << "\t" << "ConvertStringToVariant" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; + break; case V4Instr::ConvertUrlToBool: INSTR_DUMP << "\t" << "ConvertUrlToBool" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; break; case V4Instr::ConvertUrlToString: INSTR_DUMP << "\t" << "ConvertUrlToString" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; break; + case V4Instr::ConvertUrlToVariant: + INSTR_DUMP << "\t" << "ConvertUrlToVariant" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; + break; case V4Instr::ConvertColorToBool: INSTR_DUMP << "\t" << "ConvertColorToBool" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; break; case V4Instr::ConvertColorToString: INSTR_DUMP << "\t" << "ConvertColorToString" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; break; + case V4Instr::ConvertColorToVariant: + INSTR_DUMP << "\t" << "ConvertColorToVariant" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; + break; case V4Instr::ConvertObjectToBool: INSTR_DUMP << "\t" << "ConvertObjectToBool" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; break; + case V4Instr::ConvertObjectToVariant: + INSTR_DUMP << "\t" << "ConvertObjectToVariant" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; + break; case V4Instr::ConvertNullToObject: INSTR_DUMP << "\t" << "ConvertNullToObject" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; break; + case V4Instr::ConvertNullToVariant: + INSTR_DUMP << "\t" << "ConvertNullToVariant" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; + break; case V4Instr::ResolveUrl: INSTR_DUMP << "\t" << "ResolveUrl" << "\t\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; break; - case V4Instr::MathSinReal: - INSTR_DUMP << "\t" << "MathSinReal" << "\t\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; + case V4Instr::MathSinNumber: + INSTR_DUMP << "\t" << "MathSinNumber" << "\t\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; break; - case V4Instr::MathCosReal: - INSTR_DUMP << "\t" << "MathCosReal" << "\t\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; + case V4Instr::MathCosNumber: + INSTR_DUMP << "\t" << "MathCosNumber" << "\t\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; break; - case V4Instr::MathAbsReal: - INSTR_DUMP << "\t" << "MathAbsReal" << "\t\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; + case V4Instr::MathAbsNumber: + INSTR_DUMP << "\t" << "MathAbsNumber" << "\t\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; break; - case V4Instr::MathRoundReal: - INSTR_DUMP << "\t" << "MathRoundReal" << "\t\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; + case V4Instr::MathRoundNumber: + INSTR_DUMP << "\t" << "MathRoundNumber" << "\t\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; break; - case V4Instr::MathFloorReal: - INSTR_DUMP << "\t" << "MathFloorReal" << "\t\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; + case V4Instr::MathFloorNumber: + INSTR_DUMP << "\t" << "MathFloorNumber" << "\t\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; break; - case V4Instr::MathCeilReal: - INSTR_DUMP << "\t" << "MathCeilReal" << "\t\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; + case V4Instr::MathCeilNumber: + INSTR_DUMP << "\t" << "MathCeilNumber" << "\t\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; break; - case V4Instr::MathPIReal: - INSTR_DUMP << "\t" << "MathPIReal" << "\t\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; + case V4Instr::MathPINumber: + INSTR_DUMP << "\t" << "MathPINumber" << "\t\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; break; case V4Instr::LoadNull: INSTR_DUMP << "\t" << "LoadNull" << "\t\t" << "Constant(null) -> Output_Reg(" << i->null_value.reg << ")"; break; - case V4Instr::LoadReal: - INSTR_DUMP << "\t" << "LoadReal" << "\t\t" << "Constant(" << i->real_value.value << ") -> Output_Reg(" << i->real_value.reg << ")"; + case V4Instr::LoadNumber: + INSTR_DUMP << "\t" << "LoadNumber" << "\t\t" << "Constant(" << i->number_value.value << ") -> Output_Reg(" << i->number_value.reg << ")"; break; case V4Instr::LoadInt: INSTR_DUMP << "\t" << "LoadInt" << "\t\t\t" << "Constant(" << i->int_value.value << ") -> Output_Reg(" << i->int_value.reg << ")"; @@ -249,23 +273,23 @@ case V4Instr::BitXorInt: INSTR_DUMP << "\t" << "BitXorInt" << "\t\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")"; break; - case V4Instr::AddReal: - INSTR_DUMP << "\t" << "AddReal" << "\t\t\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")"; + case V4Instr::AddNumber: + INSTR_DUMP << "\t" << "AddNumber" << "\t\t\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")"; break; case V4Instr::AddString: INSTR_DUMP << "\t" << "AddString" << "\t\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")"; break; - case V4Instr::SubReal: - INSTR_DUMP << "\t" << "SubReal" << "\t\t\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")"; + case V4Instr::SubNumber: + INSTR_DUMP << "\t" << "SubNumber" << "\t\t\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")"; break; - case V4Instr::MulReal: - INSTR_DUMP << "\t" << "MulReal" << "\t\t\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")"; + case V4Instr::MulNumber: + INSTR_DUMP << "\t" << "MulNumber" << "\t\t\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")"; break; - case V4Instr::DivReal: - INSTR_DUMP << "\t" << "DivReal" << "\t\t\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")"; + case V4Instr::DivNumber: + INSTR_DUMP << "\t" << "DivNumber" << "\t\t\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")"; break; - case V4Instr::ModReal: - INSTR_DUMP << "\t" << "ModReal" << "\t\t\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")"; + case V4Instr::ModNumber: + INSTR_DUMP << "\t" << "ModNumber" << "\t\t\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")"; break; case V4Instr::LShiftInt: INSTR_DUMP << "\t" << "LShiftInt" << "\t\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")"; @@ -276,29 +300,29 @@ case V4Instr::URShiftInt: INSTR_DUMP << "\t" << "URShiftInt" << "\t\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")"; break; - case V4Instr::GtReal: - INSTR_DUMP << "\t" << "GtReal" << "\t\t\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")"; + case V4Instr::GtNumber: + INSTR_DUMP << "\t" << "GtNumber" << "\t\t\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")"; break; - case V4Instr::LtReal: - INSTR_DUMP << "\t" << "LtReal" << "\t\t\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")"; + case V4Instr::LtNumber: + INSTR_DUMP << "\t" << "LtNumber" << "\t\t\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")"; break; - case V4Instr::GeReal: - INSTR_DUMP << "\t" << "GeReal" << "\t\t\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")"; + case V4Instr::GeNumber: + INSTR_DUMP << "\t" << "GeNumber" << "\t\t\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")"; break; - case V4Instr::LeReal: - INSTR_DUMP << "\t" << "LeReal" << "\t\t\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")"; + case V4Instr::LeNumber: + INSTR_DUMP << "\t" << "LeNumber" << "\t\t\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")"; break; - case V4Instr::EqualReal: - INSTR_DUMP << "\t" << "EqualReal" << "\t\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")"; + case V4Instr::EqualNumber: + INSTR_DUMP << "\t" << "EqualNumber" << "\t\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")"; break; - case V4Instr::NotEqualReal: - INSTR_DUMP << "\t" << "NotEqualReal" << "\t\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")"; + case V4Instr::NotEqualNumber: + INSTR_DUMP << "\t" << "NotEqualNumber" << "\t\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")"; break; - case V4Instr::StrictEqualReal: - INSTR_DUMP << "\t" << "StrictEqualReal" << "\t\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")"; + case V4Instr::StrictEqualNumber: + INSTR_DUMP << "\t" << "StrictEqualNumber" << "\t\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")"; break; - case V4Instr::StrictNotEqualReal: - INSTR_DUMP << "\t" << "StrictNotEqualReal" << "\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")"; + case V4Instr::StrictNotEqualNumber: + INSTR_DUMP << "\t" << "StrictNotEqualNumber" << "\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")"; break; case V4Instr::GtString: INSTR_DUMP << "\t" << "GtString" << "\t\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")"; @@ -336,11 +360,11 @@ case V4Instr::StrictNotEqualObject: INSTR_DUMP << "\t" << "StrictNotEqualObject" << "\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")"; break; - case V4Instr::MathMaxReal: - INSTR_DUMP << "\t" << "MathMaxReal" << "\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")"; + case V4Instr::MathMaxNumber: + INSTR_DUMP << "\t" << "MathMaxNumber" << "\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")"; break; - case V4Instr::MathMinReal: - INSTR_DUMP << "\t" << "MathMinReal" << "\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")"; + case V4Instr::MathMinNumber: + INSTR_DUMP << "\t" << "MathMinNumber" << "\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")"; break; case V4Instr::NewString: INSTR_DUMP << "\t" << "NewString" << "\t\t" << "Register(" << i->construct.reg << ")"; @@ -376,12 +400,12 @@ case V4Instr::Branch: INSTR_DUMP << "\t" << "Branch" << "\t\t\t" << "Address(" << (address + size() + i->branchop.offset) << ")"; break; - case V4Instr::InitString: - INSTR_DUMP << "\t" << "InitString" << "\t\t" << "String_DataIndex(" << i->initstring.dataIdx << ") -> String_Slot(" << i->initstring.offset << ")"; - break; case V4Instr::Block: INSTR_DUMP << "\t" << "Block" << "\t\t\t" << "Mask(" << QByteArray::number(i->blockop.block, 16).constData() << ")"; break; + case V4Instr::Throw: + INSTR_DUMP << "\t" << "Throw" << "\t\t\t" << "InputReg(" << i->throwop.message << ")"; + break; default: INSTR_DUMP << "\t" << "Unknown"; break; diff -Nru qt5-declarative-0.1~git20120402/src/qml/qml/v4/qv4instruction_p.h qt5-declarative-0.1~git20120423/src/qml/qml/v4/qv4instruction_p.h --- qt5-declarative-0.1~git20120402/src/qml/qml/v4/qv4instruction_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/qml/qml/v4/qv4instruction_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -76,40 +76,48 @@ F(LoadModuleObject, load) \ F(LoadAttached, attached) \ F(UnaryNot, unaryop) \ - F(UnaryMinusReal, unaryop) \ + F(UnaryMinusNumber, unaryop) \ F(UnaryMinusInt, unaryop) \ - F(UnaryPlusReal, unaryop) \ + F(UnaryPlusNumber, unaryop) \ F(UnaryPlusInt, unaryop) \ F(ConvertBoolToInt, unaryop) \ - F(ConvertBoolToReal, unaryop) \ + F(ConvertBoolToNumber, unaryop) \ F(ConvertBoolToString, unaryop) \ + F(ConvertBoolToVariant, unaryop) \ F(ConvertIntToBool, unaryop) \ - F(ConvertIntToReal, unaryop) \ + F(ConvertIntToNumber, unaryop) \ F(ConvertIntToString, unaryop) \ - F(ConvertRealToBool, unaryop) \ - F(ConvertRealToInt, unaryop) \ - F(ConvertRealToString, unaryop) \ + F(ConvertIntToVariant, unaryop) \ + F(ConvertNumberToBool, unaryop) \ + F(ConvertNumberToInt, unaryop) \ + F(ConvertNumberToString, unaryop) \ + F(ConvertNumberToVariant, unaryop) \ F(ConvertStringToBool, unaryop) \ F(ConvertStringToInt, unaryop) \ - F(ConvertStringToReal, unaryop) \ + F(ConvertStringToNumber, unaryop) \ F(ConvertStringToUrl, unaryop) \ F(ConvertStringToColor, unaryop) \ + F(ConvertStringToVariant, unaryop) \ F(ConvertUrlToBool, unaryop) \ F(ConvertUrlToString, unaryop) \ + F(ConvertUrlToVariant, unaryop) \ F(ConvertColorToBool, unaryop) \ F(ConvertColorToString, unaryop) \ + F(ConvertColorToVariant, unaryop) \ F(ConvertObjectToBool, unaryop) \ + F(ConvertObjectToVariant, unaryop) \ F(ConvertNullToObject, unaryop) \ + F(ConvertNullToVariant, unaryop) \ F(ResolveUrl, unaryop) \ - F(MathSinReal, unaryop) \ - F(MathCosReal, unaryop) \ - F(MathAbsReal, unaryop) \ - F(MathRoundReal, unaryop) \ - F(MathFloorReal, unaryop) \ - F(MathCeilReal, unaryop) \ - F(MathPIReal, unaryop) \ + F(MathSinNumber, unaryop) \ + F(MathCosNumber, unaryop) \ + F(MathAbsNumber, unaryop) \ + F(MathRoundNumber, unaryop) \ + F(MathFloorNumber, unaryop) \ + F(MathCeilNumber, unaryop) \ + F(MathPINumber, unaryop) \ F(LoadNull, null_value) \ - F(LoadReal, real_value) \ + F(LoadNumber, number_value) \ F(LoadInt, int_value) \ F(LoadBool, bool_value) \ F(LoadString, string_value) \ @@ -118,23 +126,23 @@ F(BitAndInt, binaryop) \ F(BitOrInt, binaryop) \ F(BitXorInt, binaryop) \ - F(AddReal, binaryop) \ + F(AddNumber, binaryop) \ F(AddString, binaryop) \ - F(SubReal, binaryop) \ - F(MulReal, binaryop) \ - F(DivReal, binaryop) \ - F(ModReal, binaryop) \ + F(SubNumber, binaryop) \ + F(MulNumber, binaryop) \ + F(DivNumber, binaryop) \ + F(ModNumber, binaryop) \ F(LShiftInt, binaryop) \ F(RShiftInt, binaryop) \ F(URShiftInt, binaryop) \ - F(GtReal, binaryop) \ - F(LtReal, binaryop) \ - F(GeReal, binaryop) \ - F(LeReal, binaryop) \ - F(EqualReal, binaryop) \ - F(NotEqualReal, binaryop) \ - F(StrictEqualReal, binaryop) \ - F(StrictNotEqualReal, binaryop) \ + F(GtNumber, binaryop) \ + F(LtNumber, binaryop) \ + F(GeNumber, binaryop) \ + F(LeNumber, binaryop) \ + F(EqualNumber, binaryop) \ + F(NotEqualNumber, binaryop) \ + F(StrictEqualNumber, binaryop) \ + F(StrictNotEqualNumber, binaryop) \ F(GtString, binaryop) \ F(LtString, binaryop) \ F(GeString, binaryop) \ @@ -147,8 +155,8 @@ F(NotEqualObject, binaryop) \ F(StrictEqualObject, binaryop) \ F(StrictNotEqualObject, binaryop) \ - F(MathMaxReal, binaryop) \ - F(MathMinReal, binaryop) \ + F(MathMaxNumber, binaryop) \ + F(MathMinNumber, binaryop) \ F(NewString, construct) \ F(NewUrl, construct) \ F(CleanupRegister, cleanup) \ @@ -160,8 +168,7 @@ F(BranchFalse, branchop) \ F(Branch, branchop) \ F(Block, blockop) \ - /* Speculative property resolution */ \ - F(InitString, initstring) + F(Throw, throwop) #if defined(Q_CC_GNU) && (!defined(Q_CC_INTEL) || __INTEL_COMPILER >= 1200) # define QML_THREADED_INTERPRETER @@ -241,6 +248,7 @@ qint8 output; qint8 reg; quint8 exceptionId; + quint8 valueType; quint32 index; }; @@ -283,10 +291,10 @@ qint8 reg; }; - struct instr_real_value { + struct instr_number_value { QML_V4_INSTR_HEADER qint8 reg; - qreal value; // XXX Makes the instruction 12 bytes + double value; // XXX Makes the instruction 12 bytes }; struct instr_int_value { @@ -358,6 +366,12 @@ quint32 block; }; + struct instr_throwop { + QML_V4_INSTR_HEADER + quint8 exceptionId; + quint32 message; + }; + instr_common common; instr_id id; instr_init init; @@ -371,7 +385,7 @@ instr_copy copy; instr_construct construct; instr_null_value null_value; - instr_real_value real_value; + instr_number_value number_value; instr_int_value int_value; instr_bool_value bool_value; instr_string_value string_value; @@ -383,6 +397,7 @@ instr_initstring initstring; instr_branchop branchop; instr_blockop blockop; + instr_throwop throwop; }; template diff -Nru qt5-declarative-0.1~git20120402/src/qml/qml/v4/qv4irbuilder.cpp qt5-declarative-0.1~git20120423/src/qml/qml/v4/qv4irbuilder.cpp --- qt5-declarative-0.1~git20120402/src/qml/qml/v4/qv4irbuilder.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/qml/qml/v4/qv4irbuilder.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -61,8 +61,11 @@ case QMetaType::Int: return IR::IntType; - case QMetaType::QReal: - return IR::RealType; + case QMetaType::Float: + return IR::FloatType; + + case QMetaType::Double: + return IR::NumberType; case QMetaType::QString: return IR::StringType; @@ -113,8 +116,16 @@ //_block->MOVE(_block->TEMP(IR::InvalidType), r.code); if (r.code) { - const QMetaObject *m = 0; - const IR::Type targetType = irTypeFromVariantType(m_expression->property->type, m_engine, m); + IR::Type targetType = IR::InvalidType; + + // This is the only operation where variant is supported: + QQmlPropertyData *data = &m_expression->property->core; + if (data->propType == QMetaType::QVariant) { + targetType = (data->isVMEProperty() ? IR::VarType : IR::VariantType); + } else { + targetType = irTypeFromVariantType(data->propType, m_engine, 0); + } + if (targetType != r.type()) { IR::Expr *x = _block->TEMP(targetType); _block->MOVE(x, r, true); @@ -542,7 +553,7 @@ _expr.format = ExprResult::cx; _block->JUMP(ast->value ? _expr.iftrue : _expr.iffalse); } else { - _expr.code = _block->CONST(IR::RealType, ast->value); + _expr.code = _block->CONST(IR::NumberType, ast->value); } return false; } @@ -889,7 +900,14 @@ _expr.format = ExprResult::cx; _block->CJUMP(_block->BINOP(IR::binaryOperator(ast->op), left, right), _expr.iftrue, _expr.iffalse); } else { - _expr.code = _block->BINOP(IR::binaryOperator(ast->op), left, right); + IR::Expr *e = _block->BINOP(IR::binaryOperator(ast->op), left, right); + if (e->asConst() != 0 || e->asString() != 0) + _expr.code = e; + else { + IR::Temp *t = _block->TEMP(e->type); + _block->MOVE(t, e); + _expr.code = t; + } } } @@ -977,8 +995,8 @@ if (left.type() == IR::StringType && right.type() == IR::StringType) { binop(ast, left, right); } else if (left.isValid() && right.isValid()) { - implicitCvt(left, IR::RealType); - implicitCvt(right, IR::RealType); + implicitCvt(left, IR::NumberType); + implicitCvt(right, IR::NumberType); binop(ast, left, right); } } break; @@ -998,8 +1016,8 @@ } } else if ((left.type() == IR::StringType && right.type() >= IR::FirstNumberType) || (left.type() >= IR::FirstNumberType && right.type() == IR::StringType)) { - implicitCvt(left, IR::RealType); - implicitCvt(right, IR::RealType); + implicitCvt(left, IR::NumberType); + implicitCvt(right, IR::NumberType); binop(ast, left, right); } else if (left.isValid() && right.isValid()) { binop(ast, left, right); @@ -1086,8 +1104,8 @@ IR::Type t = maxType(left.type(), right.type()); if (t >= IR::FirstNumberType) { - implicitCvt(left, IR::RealType); - implicitCvt(right, IR::RealType); + implicitCvt(left, IR::NumberType); + implicitCvt(right, IR::NumberType); IR::Expr *code = _block->BINOP(IR::binaryOperator(ast->op), left, right); _expr.code = _block->TEMP(code->type); diff -Nru qt5-declarative-0.1~git20120402/src/qml/qml/v4/qv4irbuilder_p.h qt5-declarative-0.1~git20120423/src/qml/qml/v4/qv4irbuilder_p.h --- qt5-declarative-0.1~git20120402/src/qml/qml/v4/qv4irbuilder_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/qml/qml/v4/qv4irbuilder_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -95,8 +95,8 @@ case QQmlJS::IR::StringType: case QQmlJS::IR::BoolType: case QQmlJS::IR::IntType: - case QQmlJS::IR::RealType: - case QQmlJS::IR::RealNaNType: + case QQmlJS::IR::FloatType: + case QQmlJS::IR::NumberType: return true; default: diff -Nru qt5-declarative-0.1~git20120402/src/qml/qml/v4/qv4ir.cpp qt5-declarative-0.1~git20120423/src/qml/qml/v4/qv4ir.cpp --- qt5-declarative-0.1~git20120402/src/qml/qml/v4/qv4ir.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/qml/qml/v4/qv4ir.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -50,7 +50,7 @@ namespace QQmlJS { namespace IR { -inline const char *typeName(Type t) +const char *typeName(Type t) { switch (t) { case InvalidType: return "invalid"; @@ -58,15 +58,17 @@ case NullType: return "null"; case VoidType: return "void"; case StringType: return "string"; - case UrlType: return "url"; - case ColorType: return "color"; + case UrlType: return "QUrl"; + case ColorType: return "QColor"; case SGAnchorLineType: return "SGAnchorLine"; case AttachType: return "AttachType"; case ObjectType: return "object"; + case VariantType: return "variant"; + case VarType: return "var"; case BoolType: return "bool"; case IntType: return "int"; - case RealType: return "qreal"; - case RealNaNType: return "NaN"; + case FloatType: return "float"; + case NumberType: return "number"; default: return "invalid"; } } @@ -91,15 +93,20 @@ return IR::StringType; } else if (left == right) return left; - else if (isNumberType(left) && isNumberType(right)) - return qMax(left, right); - else if ((isNumberType(left) && isStringType(right)) || + else if (isNumberType(left) && isNumberType(right)) { + IR::Type ty = qMax(left, right); + return ty == FloatType ? NumberType : ty; // promote floats + } else if ((isNumberType(left) && isStringType(right)) || (isNumberType(right) && isStringType(left))) return IR::StringType; else return IR::InvalidType; } +bool isRealType(IR::Type type) +{ + return type == IR::NumberType || type == IR::FloatType; +} const char *opname(AluOp op) { @@ -233,7 +240,7 @@ builtin = MathMinBuiltinFunction; } else if (id->length() == 7 && *id == QLatin1String("Math.PI")) { builtin = MathPIBuiltinConstant; - this->type = RealType; + this->type = NumberType; } } @@ -267,7 +274,7 @@ case OpUMinus: case OpUPlus: case OpCompl: - return maxType(expr->type, RealType); + return maxType(expr->type, NumberType); default: break; @@ -309,13 +316,13 @@ case OpAdd: if (left->type == StringType) return StringType; - return RealType; + return NumberType; case OpSub: case OpMul: case OpDiv: case OpMod: - return RealType; + return NumberType; case OpLShift: case OpRShift: @@ -364,7 +371,7 @@ case MathAbsBuiltinFunction: //### type could also be Int if input was Int case MathMaxBuiltinFunction: case MathMinBuiltinFunction: - return RealType; + return NumberType; case MathRoundBultinFunction: case MathFloorBultinFunction: @@ -601,6 +608,12 @@ break; } } + } else if (op == OpAdd) { + if (String *s1 = left->asString()) { + if (String *s2 = right->asString()) { + return STRING(function->newString(s1->value.toString() + s2->value)); + } + } } } diff -Nru qt5-declarative-0.1~git20120402/src/qml/qml/v4/qv4ir_p.h qt5-declarative-0.1~git20120423/src/qml/qml/v4/qv4ir_p.h --- qt5-declarative-0.1~git20120402/src/qml/qml/v4/qv4ir_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/qml/qml/v4/qv4ir_p.h 2012-04-23 11:44:59.000000000 +0000 @@ -146,14 +146,18 @@ SGAnchorLineType, AttachType, ObjectType, + VariantType, + VarType, FirstNumberType, BoolType = FirstNumberType, IntType, - RealType, - RealNaNType + FloatType, + NumberType }; Type maxType(IR::Type left, IR::Type right); +bool isRealType(IR::Type type); +const char *typeName(IR::Type t); struct ExprVisitor { virtual ~ExprVisitor() {} diff -Nru qt5-declarative-0.1~git20120402/src/qml/qml/v4/qv4program_p.h qt5-declarative-0.1~git20120423/src/qml/qml/v4/qv4program_p.h --- qt5-declarative-0.1~git20120402/src/qml/qml/v4/qv4program_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/qml/qml/v4/qv4program_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -65,7 +65,6 @@ quint32 signalTableOffset; quint32 exceptionDataOffset; quint16 subscriptions; - quint16 identifiers; quint16 instructionCount; struct BindingReference { @@ -87,7 +86,8 @@ UndefinedType, NullType, QObjectStarType, - QRealType, + NumberType, + FloatType, IntType, BoolType, diff -Nru qt5-declarative-0.1~git20120402/src/qml/qml/v8/qjsconverter_impl_p.h qt5-declarative-0.1~git20120423/src/qml/qml/v8/qjsconverter_impl_p.h --- qt5-declarative-0.1~git20120402/src/qml/qml/v8/qjsconverter_impl_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/qml/qml/v8/qjsconverter_impl_p.h 2012-04-23 11:44:59.000000000 +0000 @@ -40,6 +40,7 @@ ****************************************************************************/ #include "qjsconverter_p.h" +#include #ifndef QJSCONVERTER_IMPL_P_H #define QJSCONVERTER_IMPL_P_H diff -Nru qt5-declarative-0.1~git20120402/src/qml/qml/v8/qjsvalue_p.h qt5-declarative-0.1~git20120423/src/qml/qml/v8/qjsvalue_p.h --- qt5-declarative-0.1~git20120402/src/qml/qml/v8/qjsvalue_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/qml/qml/v8/qjsvalue_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -177,7 +177,7 @@ CBool, CNull, CUndefined, - JSValue = 0x2000, // V8 values are equal or higher then this value. + JSValue = 0x2000 // V8 values are equal or higher then this value. // JSPrimitive, // JSObject } m_state; diff -Nru qt5-declarative-0.1~git20120402/src/qml/qml/v8/qv8engine.cpp qt5-declarative-0.1~git20120423/src/qml/qml/v8/qv8engine.cpp --- qt5-declarative-0.1~git20120402/src/qml/qml/v8/qv8engine.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/qml/qml/v8/qv8engine.cpp 2012-04-23 11:44:59.000000000 +0000 @@ -48,7 +48,6 @@ #include "qv8sequencewrapper_p.h" #include "qv8include_p.h" #include "qjsengine_p.h" -#include "../../../3rdparty/javascriptcore/DateMath.h" #include #include @@ -763,23 +762,19 @@ double QV8Engine::qtDateTimeToJsDate(const QDateTime &dt) { - // from QScriptEngine::DateTimeToMs() if (!dt.isValid()) { return qSNaN(); } - QDateTime utc = dt.toUTC(); - QDate date = utc.date(); - QTime time = utc.time(); - QV8DateConverter::JSC::GregorianDateTime tm; - tm.year = date.year() - 1900; - tm.month = date.month() - 1; - tm.monthDay = date.day(); - tm.weekDay = date.dayOfWeek(); - tm.yearDay = date.dayOfYear(); - tm.hour = time.hour(); - tm.minute = time.minute(); - tm.second = time.second(); - return QV8DateConverter::JSC::gregorianDateTimeToMS(tm, time.msec()); + + return dt.toMSecsSinceEpoch(); +} + +QDateTime QV8Engine::qtDateTimeFromJsDate(double jsDate) +{ + if (qIsNaN(jsDate)) + return QDateTime(); + + return QDateTime::fromMSecsSinceEpoch(jsDate); } v8::Persistent *QV8Engine::findOwnerAndStrength(QObject *object, bool *shouldBeStrong) @@ -813,24 +808,6 @@ } } -QDateTime QV8Engine::qtDateTimeFromJsDate(double jsDate) -{ - // from QScriptEngine::MsToDateTime() - if (qIsNaN(jsDate)) - return QDateTime(); - QV8DateConverter::JSC::GregorianDateTime tm; - QV8DateConverter::JSC::msToGregorianDateTime(jsDate, tm); - - // from QScriptEngine::MsFromTime() - int ms = int(::fmod(jsDate, 1000.0)); - if (ms < 0) - ms += int(1000.0); - - QDateTime convertedUTC = QDateTime(QDate(tm.year + 1900, tm.month + 1, tm.monthDay), - QTime(tm.hour, tm.minute, tm.second, ms), Qt::UTC); - return convertedUTC.toLocalTime(); -} - void QV8Engine::addRelationshipForGC(QObject *object, v8::Persistent handle) { if (handle.IsEmpty()) diff -Nru qt5-declarative-0.1~git20120402/src/qml/qml/v8/qv8qobjectwrapper.cpp qt5-declarative-0.1~git20120423/src/qml/qml/v8/qv8qobjectwrapper.cpp --- qt5-declarative-0.1~git20120402/src/qml/qml/v8/qv8qobjectwrapper.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/qml/qml/v8/qv8qobjectwrapper.cpp 2012-04-23 11:44:59.000000000 +0000 @@ -63,7 +63,7 @@ QT_BEGIN_NAMESPACE -#if defined(__GNUC__) +#if defined(__GNUC__) && !defined(__INTEL_COMPILER) # if (__GNUC__ * 100 + __GNUC_MINOR__) >= 405 // The code in this file does not violate strict aliasing, but GCC thinks it does // so turn off the warnings for us to have a clean build @@ -269,7 +269,7 @@ QV8QObjectResource *resource = v8_resource_check(This); QObject *object = resource->object; - if (!object) return v8::Undefined(); + if (QQmlData::wasDeleted(object)) return v8::Undefined(); QQmlPropertyData *property = (QQmlPropertyData *)v8::External::Unwrap(info.Data()); @@ -300,8 +300,8 @@ #define FAST_GETTER_FUNCTION(property, cpptype) \ (property->hasAccessors()?((v8::AccessorGetter)GenericValueGetter):(property->isDirect()?((v8::AccessorGetter)GenericValueGetter):((v8::AccessorGetter)GenericValueGetter))) -static quint32 toStringHash = -1; -static quint32 destroyHash = -1; +static quint32 toStringHash = quint32(-1); +static quint32 destroyHash = quint32(-1); void QV8QObjectWrapper::init(QV8Engine *engine) { @@ -476,6 +476,7 @@ objectHandle?*objectHandle:engine->newQObject(object), v8::Integer::New(index) }; + Q_ASSERT(argv[0]->IsObject()); return engine->qobjectWrapper()->m_methodConstructor->Call(engine->global(), 2, argv); } static v8::Handle createWithGlobal(QV8Engine *engine, QObject *object, @@ -486,10 +487,14 @@ v8::Integer::New(index), v8::Context::GetCallingQmlGlobal() }; + Q_ASSERT(argv[0]->IsObject()); return engine->qobjectWrapper()->m_methodConstructor->Call(engine->global(), 3, argv); } }; + if (QQmlData::wasDeleted(object)) + return v8::Handle(); + { // Comparing the hash first actually makes a measurable difference here, at least on x86 quint32 hash = property.hash(); @@ -665,6 +670,9 @@ engine->qobjectWrapper()->m_destroyString == property) return true; + if (QQmlData::wasDeleted(object)) + return false; + QQmlPropertyData local; QQmlPropertyData *result = 0; result = QQmlPropertyCache::property(engine->engine(), object, property, local); @@ -695,7 +703,7 @@ { QV8QObjectResource *resource = v8_resource_check(info.This()); - if (resource->object.isNull()) + if (QQmlData::wasDeleted(resource->object)) return v8::Handle(); QObject *object = resource->object; @@ -739,7 +747,7 @@ { QV8QObjectResource *resource = v8_resource_check(info.This()); - if (resource->object.isNull()) + if (QQmlData::wasDeleted(resource->object)) return value; QObject *object = resource->object; @@ -833,7 +841,7 @@ { QV8QObjectResource *resource = v8_resource_check(info.This()); - if (resource->object.isNull()) + if (QQmlData::wasDeleted(resource->object)) return; QObject *object = resource->object; @@ -860,7 +868,7 @@ { QV8QObjectResource *resource = v8_resource_check(info.This()); - if (resource->object.isNull()) + if (QQmlData::wasDeleted(resource->object)) return; QV8Engine *v8engine = resource->engine; @@ -1040,20 +1048,13 @@ */ v8::Handle QV8QObjectWrapper::newQObject(QObject *object) { - if (!object) + if (QQmlData::wasDeleted(object)) return v8::Null(); - if (QObjectPrivate::get(object)->wasDeleted) - return v8::Null(); - QQmlData *ddata = QQmlData::get(object, true); - if (!ddata) return v8::Undefined(); - if (ddata->isQueuedForDeletion) - return v8::Null(); - if (ddata->v8objectid == m_id && !ddata->v8object.IsEmpty()) { // We own the v8object return v8::Local::New(ddata->v8object); diff -Nru qt5-declarative-0.1~git20120402/src/qml/qml/v8/v8.pri qt5-declarative-0.1~git20120423/src/qml/qml/v8/v8.pri --- qt5-declarative-0.1~git20120402/src/qml/qml/v8/v8.pri 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/qml/qml/v8/v8.pri 2012-04-23 11:44:59.000000000 +0000 @@ -1,5 +1,3 @@ -INCLUDEPATH += $$PWD/../../../3rdparty/javascriptcore - include(script.pri) HEADERS += \ @@ -20,7 +18,6 @@ $$PWD/qv8include_p.h \ $$PWD/qv8worker_p.h \ $$PWD/qv8bindings_p.h \ - $$PWD/../../../3rdparty/javascriptcore/DateMath.h \ $$PWD/qv8engine_impl_p.h \ $$PWD/qv8domerrors_p.h \ $$PWD/qv8sqlerrors_p.h \ @@ -39,7 +36,6 @@ $$PWD/qv8include.cpp \ $$PWD/qv8worker.cpp \ $$PWD/qv8bindings.cpp \ - $$PWD/../../../3rdparty/javascriptcore/DateMath.cpp \ $$PWD/qv8domerrors.cpp \ $$PWD/qv8sqlerrors.cpp \ - $$PWD/qqmlbuiltinfunctions.cpp \ No newline at end of file + $$PWD/qqmlbuiltinfunctions.cpp diff -Nru qt5-declarative-0.1~git20120402/src/qmltest/qmltest.pro qt5-declarative-0.1~git20120423/src/qmltest/qmltest.pro --- qt5-declarative-0.1~git20120402/src/qmltest/qmltest.pro 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/qmltest/qmltest.pro 2012-04-23 11:32:40.000000000 +0000 @@ -33,4 +33,4 @@ $$PWD/qtestoptions_p.h -DEFINES += QT_BUILD_QUICK_TEST_LIB +DEFINES += QT_BUILD_QUICK_TEST_LIB QT_QML_DEBUG_NO_WARNING \ No newline at end of file diff -Nru qt5-declarative-0.1~git20120402/src/quick/items/context2d/qquickcontext2d.cpp qt5-declarative-0.1~git20120423/src/quick/items/context2d/qquickcontext2d.cpp --- qt5-declarative-0.1~git20120402/src/quick/items/context2d/qquickcontext2d.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/items/context2d/qquickcontext2d.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -184,7 +184,7 @@ if (*p != ')') return QColor(); if (isRgb) return QColor::fromRgba(qRgba(qClamp(rh, 0, 255), qClamp(gs, 0, 255), qClamp(bl, 0, 255), qClamp(alpha, 0, 255))); - else + else if (isHsl) return QColor::fromHsl(qClamp(rh, 0, 255), qClamp(gs, 0, 255), qClamp(bl, 0, 255), qClamp(alpha, 0, 255)); } return QColor(); diff -Nru qt5-declarative-0.1~git20120402/src/quick/items/qquickcanvas.cpp qt5-declarative-0.1~git20120423/src/quick/items/qquickcanvas.cpp --- qt5-declarative-0.1~git20120402/src/quick/items/qquickcanvas.cpp 2012-04-02 11:02:55.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/items/qquickcanvas.cpp 2012-04-23 11:44:59.000000000 +0000 @@ -155,6 +155,10 @@ // #define TOUCH_DEBUG // #define DIRTY_DEBUG +#ifdef FOCUS_DEBUG +void printFocusTree(QQuickItem *item, QQuickItem *scope = 0, int depth = 1); +#endif + QQuickItem::UpdatePaintNodeData::UpdatePaintNodeData() : transformNode(0) { @@ -1088,8 +1092,12 @@ QQuickMouseEventEx me(event->type(), transform.map(event->windowPos()), event->windowPos(), event->screenPos(), event->button(), event->buttons(), event->modifiers()); - if (QQuickMouseEventEx::extended(event)) - me.setVelocity(QQuickMouseEventEx::extended(event)->velocity()); + QQuickMouseEventEx *eventEx = QQuickMouseEventEx::extended(event); + if (eventEx) { + me.setVelocity(eventEx->velocity()); + me.setCapabilities(eventEx->capabilities()); + } + me.setTimestamp(event->timestamp()); me.accept(); q->sendEvent(mouseGrabberItem, &me); event->setAccepted(me.isAccepted()); diff -Nru qt5-declarative-0.1~git20120402/src/quick/items/qquickflickable.cpp qt5-declarative-0.1~git20120423/src/quick/items/qquickflickable.cpp --- qt5-declarative-0.1~git20120402/src/quick/items/qquickflickable.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/items/qquickflickable.cpp 2012-04-23 11:44:59.000000000 +0000 @@ -1108,7 +1108,8 @@ d->clearDelayedPress(); d->handleMouseReleaseEvent(event); event->accept(); - ungrabMouse(); + if (canvas() && canvas()->mouseGrabberItem() == this) + ungrabMouse(); } else { QQuickItem::mouseReleaseEvent(event); } diff -Nru qt5-declarative-0.1~git20120402/src/quick/items/qquickgridview.cpp qt5-declarative-0.1~git20120423/src/quick/items/qquickgridview.cpp --- qt5-declarative-0.1~git20120402/src/quick/items/qquickgridview.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/items/qquickgridview.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -92,7 +92,7 @@ } qreal size() const { - return view->flow() == QQuickGridView::LeftToRight ? view->cellHeight() : view->cellWidth(); + return view->flow() == QQuickGridView::FlowLeftToRight ? view->cellHeight() : view->cellWidth(); } qreal sectionSize() const { @@ -100,14 +100,14 @@ } qreal rowPos() const { - if (view->flow() == QQuickGridView::LeftToRight) - return itemY(); + if (view->flow() == QQuickGridView::FlowLeftToRight) + return (view->verticalLayoutDirection() == QQuickItemView::BottomToTop ? -view->cellHeight()-itemY() : itemY()); else return (view->effectiveLayoutDirection() == Qt::RightToLeft ? -view->cellWidth()-itemX() : itemX()); } qreal colPos() const { - if (view->flow() == QQuickGridView::LeftToRight) { + if (view->flow() == QQuickGridView::FlowLeftToRight) { if (view->effectiveLayoutDirection() == Qt::RightToLeft) { qreal colSize = view->cellWidth(); int columns = view->width()/colSize; @@ -116,12 +116,19 @@ return itemX(); } } else { - return itemY(); + if (view->verticalLayoutDirection() == QQuickItemView::BottomToTop) { + return -view->cellHeight() - itemY(); + } else { + return itemY(); + } } } qreal endRowPos() const { - if (view->flow() == QQuickGridView::LeftToRight) { - return itemY() + view->cellHeight(); + if (view->flow() == QQuickGridView::FlowLeftToRight) { + if (view->verticalLayoutDirection() == QQuickItemView::BottomToTop) + return -itemY(); + else + return itemY() + view->cellHeight(); } else { if (view->effectiveLayoutDirection() == Qt::RightToLeft) return -itemX(); @@ -141,19 +148,24 @@ private: QPointF pointForPosition(qreal col, qreal row) const { - if (view->effectiveLayoutDirection() == Qt::RightToLeft) { - if (view->flow() == QQuickGridView::LeftToRight) { + qreal x; + qreal y; + if (view->flow() == QQuickGridView::FlowLeftToRight) { + x = col; + y = row; + if (view->effectiveLayoutDirection() == Qt::RightToLeft) { int columns = view->width()/view->cellWidth(); - return QPointF(view->cellWidth() * (columns-1) - col, row); - } else { - return QPointF(-view->cellWidth() - row, col); + x = view->cellWidth() * (columns-1) - col; } } else { - if (view->flow() == QQuickGridView::LeftToRight) - return QPointF(col, row); - else - return QPointF(row, col); + x = row; + y = col; + if (view->effectiveLayoutDirection() == Qt::RightToLeft) + x = -view->cellWidth() - row; } + if (view->verticalLayoutDirection() == QQuickItemView::BottomToTop) + y = -view->cellHeight() - y; + return QPointF(x, y); } }; @@ -166,7 +178,6 @@ public: virtual Qt::Orientation layoutOrientation() const; virtual bool isContentFlowReversed() const; - bool isRightToLeftTopToBottom() const; virtual qreal positionAt(int index) const; virtual qreal endPositionAt(int index) const; @@ -180,6 +191,8 @@ qreal snapPosAt(qreal pos) const; FxViewItem *snapItemAt(qreal pos) const; int snapIndex() const; + qreal contentXForPosition(qreal pos) const; + qreal contentYForPosition(qreal pos) const; void resetColumns(); @@ -229,7 +242,7 @@ QSmoothedAnimation *highlightYAnimator; QQuickGridViewPrivate() - : flow(QQuickGridView::LeftToRight) + : flow(QQuickGridView::FlowLeftToRight) , cellWidth(100), cellHeight(100), columns(1) , snapMode(QQuickGridView::NoSnap) , highlightXAnimator(0), highlightYAnimator(0) @@ -243,18 +256,15 @@ Qt::Orientation QQuickGridViewPrivate::layoutOrientation() const { - return flow == QQuickGridView::LeftToRight ? Qt::Vertical : Qt::Horizontal; + return flow == QQuickGridView::FlowLeftToRight ? Qt::Vertical : Qt::Horizontal; } bool QQuickGridViewPrivate::isContentFlowReversed() const { - return isRightToLeftTopToBottom(); -} - -bool QQuickGridViewPrivate::isRightToLeftTopToBottom() const -{ Q_Q(const QQuickGridView); - return flow == QQuickGridView::TopToBottom && q->effectiveLayoutDirection() == Qt::RightToLeft; + + return (flow == QQuickGridView::FlowLeftToRight && verticalLayoutDirection == QQuickItemView::BottomToTop) + || (flow == QQuickGridView::FlowTopToBottom && q->effectiveLayoutDirection() == Qt::RightToLeft); } void QQuickGridViewPrivate::changedVisibleIndex(int newIndex) @@ -265,16 +275,8 @@ void QQuickGridViewPrivate::setPosition(qreal pos) { Q_Q(QQuickGridView); - if (flow == QQuickGridView::LeftToRight) { - q->QQuickFlickable::setContentY(pos); - q->QQuickFlickable::setContentX(0); - } else { - if (q->effectiveLayoutDirection() == Qt::LeftToRight) - q->QQuickFlickable::setContentX(pos); - else - q->QQuickFlickable::setContentX(-pos-size()); - q->QQuickFlickable::setContentY(0); - } + q->QQuickFlickable::setContentX(contentXForPosition(pos)); + q->QQuickFlickable::setContentY(contentYForPosition(pos)); } qreal QQuickGridViewPrivate::originPosition() const @@ -306,10 +308,10 @@ } qreal QQuickGridViewPrivate::rowSize() const { - return flow == QQuickGridView::LeftToRight ? cellHeight : cellWidth; + return flow == QQuickGridView::FlowLeftToRight ? cellHeight : cellWidth; } qreal QQuickGridViewPrivate::colSize() const { - return flow == QQuickGridView::LeftToRight ? cellWidth : cellHeight; + return flow == QQuickGridView::FlowLeftToRight ? cellWidth : cellHeight; } qreal QQuickGridViewPrivate::colPosAt(int modelIndex) const @@ -375,12 +377,12 @@ snapPos -= highlightStart; qreal maxExtent; qreal minExtent; - if (isRightToLeftTopToBottom()) { + if (isContentFlowReversed()) { maxExtent = q->minXExtent()-size(); minExtent = q->maxXExtent()-size(); } else { - maxExtent = flow == QQuickGridView::LeftToRight ? -q->maxYExtent() : -q->maxXExtent(); - minExtent = flow == QQuickGridView::LeftToRight ? -q->minYExtent() : -q->minXExtent(); + maxExtent = flow == QQuickGridView::FlowLeftToRight ? -q->maxYExtent() : -q->maxXExtent(); + minExtent = flow == QQuickGridView::FlowLeftToRight ? -q->minYExtent() : -q->minXExtent(); } if (snapPos > maxExtent) snapPos = maxExtent; @@ -421,10 +423,49 @@ return index; } +qreal QQuickGridViewPrivate::contentXForPosition(qreal pos) const +{ + Q_Q(const QQuickGridView); + if (flow == QQuickGridView::FlowLeftToRight) { + // vertical scroll + if (q->effectiveLayoutDirection() == Qt::LeftToRight) { + return 0; + } else { + qreal colSize = cellWidth; + int columns = q->width()/colSize; + return -q->width() + (cellWidth * columns); + } + } else { + // horizontal scroll + if (q->effectiveLayoutDirection() == Qt::LeftToRight) + return pos; + else + return -pos - q->width(); + } +} + +qreal QQuickGridViewPrivate::contentYForPosition(qreal pos) const +{ + Q_Q(const QQuickGridView); + if (flow == QQuickGridView::FlowLeftToRight) { + // vertical scroll + if (verticalLayoutDirection == QQuickItemView::TopToBottom) + return pos; + else + return -pos - q->height(); + } else { + // horizontal scroll + if (verticalLayoutDirection == QQuickItemView::TopToBottom) + return 0; + else + return -q->height(); + } +} + void QQuickGridViewPrivate::resetColumns() { Q_Q(QQuickGridView); - qreal length = flow == QQuickGridView::LeftToRight ? q->width() : q->height(); + qreal length = flow == QQuickGridView::FlowLeftToRight ? q->width() : q->height(); columns = (int)qMax((length + colSize()/2) / colSize(), qreal(1.)); } @@ -641,15 +682,22 @@ { Q_Q(QQuickGridView); qreal pos = position(); - if (flow == QQuickGridView::LeftToRight) { - if (item->y() + item->height() > pos && item->y() < pos + q->height()) - item->setPos(QPointF(colPosAt(index), rowPosAt(index))); + if (flow == QQuickGridView::FlowLeftToRight) { + if (item->y() + item->height() > pos && item->y() < pos + q->height()) { + qreal y = (verticalLayoutDirection == QQuickItemView::TopToBottom) + ? rowPosAt(index) + : -rowPosAt(index) - item->height(); + item->setPos(QPointF(colPosAt(index), y)); + } } else { if (item->x() + item->width() > pos && item->x() < pos + q->width()) { - if (isRightToLeftTopToBottom()) - item->setPos(QPointF(-rowPosAt(index)-item->width(), colPosAt(index))); + qreal y = (verticalLayoutDirection == QQuickItemView::TopToBottom) + ? colPosAt(index) + : -colPosAt(index) - item->height(); + if (flow == QQuickGridView::FlowTopToBottom && q->effectiveLayoutDirection() == Qt::RightToLeft) + item->setPos(QPointF(-rowPosAt(index)-item->width(), y)); else - item->setPos(QPointF(rowPosAt(index), colPosAt(index))); + item->setPos(QPointF(rowPosAt(index), y)); } } } @@ -744,14 +792,14 @@ { if (!header) return 0.0; - return flow == QQuickGridView::LeftToRight ? header->item->height() : header->item->width(); + return flow == QQuickGridView::FlowLeftToRight ? header->item->height() : header->item->width(); } qreal QQuickGridViewPrivate::footerSize() const { if (!footer) return 0.0; - return flow == QQuickGridView::LeftToRight? footer->item->height() : footer->item->width(); + return flow == QQuickGridView::FlowLeftToRight? footer->item->height() : footer->item->width(); } bool QQuickGridViewPrivate::showHeaderForIndex(int index) const @@ -781,17 +829,23 @@ qreal colOffset = 0; qreal rowOffset = 0; if (q->effectiveLayoutDirection() == Qt::RightToLeft) { - if (flow == QQuickGridView::TopToBottom) - rowOffset = gridItem->item->width() - cellWidth; + if (flow == QQuickGridView::FlowTopToBottom) + rowOffset += gridItem->item->width() - cellWidth; + else + colOffset += gridItem->item->width() - cellWidth; + } + if (verticalLayoutDirection == QQuickItemView::BottomToTop) { + if (flow == QQuickGridView::FlowTopToBottom) + colOffset += gridItem->item->height() - cellHeight; else - colOffset = gridItem->item->width() - cellWidth; + rowOffset += gridItem->item->height() - cellHeight; } if (visibleItems.count()) { qreal endPos = lastPosition(); if (findLastVisibleIndex() == model->count()-1) { gridItem->setPosition(colOffset, endPos + rowOffset); } else { - qreal visiblePos = isRightToLeftTopToBottom() ? -position() : position() + size(); + qreal visiblePos = isContentFlowReversed() ? -position() : position() + size(); if (endPos <= visiblePos || gridItem->endPosition() <= endPos + rowOffset) gridItem->setPosition(colOffset, endPos + rowOffset); } @@ -820,23 +874,29 @@ qreal colOffset = 0; qreal rowOffset = -headerSize(); if (q->effectiveLayoutDirection() == Qt::RightToLeft) { - if (flow == QQuickGridView::TopToBottom) - rowOffset += gridItem->item->width()-cellWidth; + if (flow == QQuickGridView::FlowTopToBottom) + rowOffset += gridItem->item->width() - cellWidth; else - colOffset = gridItem->item->width()-cellWidth; + colOffset += gridItem->item->width() - cellWidth; + } + if (verticalLayoutDirection == QQuickItemView::BottomToTop) { + if (flow == QQuickGridView::FlowTopToBottom) + colOffset += gridItem->item->height() - cellHeight; + else + rowOffset += gridItem->item->height() - cellHeight; } if (visibleItems.count()) { qreal startPos = originPosition(); if (visibleIndex == 0) { gridItem->setPosition(colOffset, startPos + rowOffset); } else { - qreal tempPos = isRightToLeftTopToBottom() ? -position()-size() : position(); - qreal headerPos = isRightToLeftTopToBottom() ? gridItem->rowPos() + cellWidth - headerSize() : gridItem->rowPos(); + qreal tempPos = isContentFlowReversed() ? -position()-size() : position(); + qreal headerPos = isContentFlowReversed() ? gridItem->rowPos() + cellWidth - headerSize() : gridItem->rowPos(); if (tempPos <= startPos || headerPos > startPos + rowOffset) gridItem->setPosition(colOffset, startPos + rowOffset); } } else { - if (isRightToLeftTopToBottom()) + if (isContentFlowReversed()) gridItem->setPosition(colOffset, rowOffset); else gridItem->setPosition(colOffset, -headerSize()); @@ -861,7 +921,7 @@ void QQuickGridViewPrivate::fixupPosition() { moveReason = Other; - if (flow == QQuickGridView::LeftToRight) + if (flow == QQuickGridView::FlowLeftToRight) fixupY(); else fixupX(); @@ -869,17 +929,17 @@ void QQuickGridViewPrivate::fixup(AxisData &data, qreal minExtent, qreal maxExtent) { - if ((flow == QQuickGridView::TopToBottom && &data == &vData) - || (flow == QQuickGridView::LeftToRight && &data == &hData)) + if ((flow == QQuickGridView::FlowTopToBottom && &data == &vData) + || (flow == QQuickGridView::FlowLeftToRight && &data == &hData)) return; fixupMode = moveReason == Mouse ? fixupMode : Immediate; - qreal viewPos = isRightToLeftTopToBottom() ? -position()-size() : position(); + qreal viewPos = isContentFlowReversed() ? -position()-size() : position(); bool strictHighlightRange = haveHighlightRange && highlightRange == QQuickGridView::StrictlyEnforceRange; if (snapMode != QQuickGridView::NoSnap) { - qreal tempPosition = isRightToLeftTopToBottom() ? -position()-size() : position(); + qreal tempPosition = isContentFlowReversed() ? -position()-size() : position(); if (snapMode == QQuickGridView::SnapOneRow && moveReason == Mouse) { // if we've been dragged < rowSize()/2 then bias towards the next row qreal dist = data.move.value() - (data.pressPos - data.dragStartOffset); @@ -888,7 +948,7 @@ bias = rowSize()/2; else if (data.velocity < 0 && dist < -QML_FLICK_SNAPONETHRESHOLD && dist > -rowSize()/2) bias = -rowSize()/2; - if (isRightToLeftTopToBottom()) + if (isContentFlowReversed()) bias = -bias; tempPosition -= bias; } @@ -909,15 +969,15 @@ if (topItem && (isInBounds || strictHighlightRange)) { qreal headerPos = header ? static_cast(header)->rowPos() : 0; if (topItem->index == 0 && header && tempPosition+highlightRangeStart < headerPos+headerSize()/2 && !strictHighlightRange) { - pos = isRightToLeftTopToBottom() ? - headerPos + highlightRangeStart - size() : headerPos - highlightRangeStart; + pos = isContentFlowReversed() ? - headerPos + highlightRangeStart - size() : headerPos - highlightRangeStart; } else { - if (isRightToLeftTopToBottom()) + if (isContentFlowReversed()) pos = qMax(qMin(-topItem->position() + highlightRangeStart - size(), -maxExtent), -minExtent); else pos = qMax(qMin(topItem->position() - highlightRangeStart, -maxExtent), -minExtent); } } else if (bottomItem && isInBounds) { - if (isRightToLeftTopToBottom()) + if (isContentFlowReversed()) pos = qMax(qMin(-bottomItem->position() + highlightRangeEnd - size(), -maxExtent), -minExtent); else pos = qMax(qMin(bottomItem->position() - highlightRangeEnd, -maxExtent), -minExtent); @@ -945,7 +1005,7 @@ viewPos = pos + rowSize() - highlightRangeEnd; if (viewPos > pos - highlightRangeStart) viewPos = pos - highlightRangeStart; - if (isRightToLeftTopToBottom()) + if (isContentFlowReversed()) viewPos = -viewPos-size(); timeline.reset(data.move); if (viewPos != position()) { @@ -977,7 +1037,7 @@ return; } qreal maxDistance = 0; - qreal dataValue = isRightToLeftTopToBottom() ? -data.move.value()+size() : data.move.value(); + qreal dataValue = isContentFlowReversed() ? -data.move.value()+size() : data.move.value(); // -ve velocity means list is moving up/left if (velocity > 0) { if (data.move.value() < minExtent) { @@ -985,7 +1045,7 @@ // if we've been dragged < averageSize/2 then bias towards the next item qreal dist = data.move.value() - (data.pressPos - data.dragStartOffset); qreal bias = dist < rowSize()/2 ? rowSize()/2 : 0; - if (isRightToLeftTopToBottom()) + if (isContentFlowReversed()) bias = -bias; data.flickTarget = -snapPosAt(-dataValue - bias); maxDistance = qAbs(data.flickTarget - data.move.value()); @@ -1002,7 +1062,7 @@ // if we've been dragged < averageSize/2 then bias towards the next item qreal dist = data.move.value() - (data.pressPos - data.dragStartOffset); qreal bias = -dist < rowSize()/2 ? rowSize()/2 : 0; - if (isRightToLeftTopToBottom()) + if (isContentFlowReversed()) bias = -bias; data.flickTarget = -snapPosAt(-dataValue + bias); maxDistance = qAbs(data.flickTarget - data.move.value()); @@ -1034,10 +1094,10 @@ if (v > 0) dist = -dist; if (snapMode != QQuickGridView::SnapOneRow) { - qreal distTemp = isRightToLeftTopToBottom() ? -dist : dist; + qreal distTemp = isContentFlowReversed() ? -dist : dist; data.flickTarget = -snapPosAt(-dataValue + distTemp); } - data.flickTarget = isRightToLeftTopToBottom() ? -data.flickTarget+size() : data.flickTarget; + data.flickTarget = isContentFlowReversed() ? -data.flickTarget+size() : data.flickTarget; if (overShoot) { if (data.flickTarget >= minExtent) { overshootDist = overShootDistance(vSize); @@ -1159,6 +1219,60 @@ to set this property to true in order to clip the items that are partially or fully outside the view. + + \section1 GridView layouts + + The layout of the items in a GridView can be controlled by these properties: + + \list + \li \l flow - controls whether items flow from left to right (as a series of rows) + or from top to bottom (as a series of columns). This value can be either + GridView.LeftToRight or GridView.TopToBottom. + \li \l layoutDirection - controls the horizontal layout direction: that is, whether items + are laid out from the left side of the view to the right, or vice-versa. This value can + be either Qt.LeftToRight or Qt.RightToLeft. + \li \l verticalLayoutDirection - controls the vertical layout direction: that is, whether items + are laid out from the top of the view down towards the bottom of the view, or vice-versa. + This value can be either GridView.TopToBottom or GridView.BottomToTop. + \endlist + + By default, a GridView flows from left to right, and items are laid out from left to right + horizontally, and from top to bottom vertically. + + These properties can be combined to produce a variety of layouts, as shown in the table below. + The GridViews in the first row all have a \l flow value of GridView.LeftToRight, but use + different combinations of horizontal and vertical layout directions (specified by \l layoutDirection + and \l verticalLayoutDirection respectively). Similarly, the GridViews in the second row below + all have a \l flow value of GridView.TopToBottom, but use different combinations of horizontal and + vertical layout directions to lay out their items in different ways. + + \table + \header + \li {4, 1} + \bold GridViews with GridView.LeftToRight flow + \row + \li \bold (H) Left to right \bold (V) Top to bottom + \image gridview-layout-lefttoright-ltr-ttb.png + \li \bold (H) Right to left \bold (V) Top to bottom + \image gridview-layout-lefttoright-rtl-ttb.png + \li \bold (H) Left to right \bold (V) Bottom to top + \image gridview-layout-lefttoright-ltr-btt.png + \li \bold (H) Right to left \bold (V) Bottom to top + \image gridview-layout-lefttoright-rtl-btt.png + \header + \li {4, 1} + \bold GridViews with GridView.TopToBottom flow + \row + \li \bold (H) Left to right \bold (V) Top to bottom + \image gridview-layout-toptobottom-ltr-ttb.png + \li \bold (H) Right to left \bold (V) Top to bottom + \image gridview-layout-toptobottom-rtl-ttb.png + \li \bold (H) Left to right \bold (V) Bottom to top + \image gridview-layout-toptobottom-ltr-btt.png + \li \bold (H) Right to left \bold (V) Bottom to top + \image gridview-layout-toptobottom-rtl-btt.png + \endtable + \sa {declarative/modelviews/gridview}{GridView example} */ @@ -1380,6 +1494,8 @@ \b Note: If GridView::flow is set to GridView.LeftToRight, this is not to be confused if GridView::layoutDirection is set to Qt.RightToLeft. The GridView.LeftToRight flow value simply indicates that the flow is horizontal. + + \sa GridView::effectiveLayoutDirection, GridView::verticalLayoutDirection */ @@ -1393,6 +1509,21 @@ \sa GridView::layoutDirection, {LayoutMirroring}{LayoutMirroring} */ + +/*! + \qmlproperty enumeration QtQuick2::GridView::verticalLayoutDirection + This property holds the vertical layout direction of the grid. + + Possible values: + + \list + \li GridView.TopToBottom (default) - Items are laid out from the top of the view down to the bottom of the view. + \li GridView.BottomToTop - Items are laid out from the bottom of the view up to the top of the view. + \endlist + + \sa GridView::layoutDirection +*/ + /*! \qmlproperty bool QtQuick2::GridView::keyNavigationWraps This property holds whether the grid wraps key navigation @@ -1461,7 +1592,7 @@ Q_D(QQuickGridView); if (d->flow != flow) { d->flow = flow; - if (d->flow == LeftToRight) { + if (d->flow == FlowLeftToRight) { setContentWidth(-1); setFlickableDirection(VerticalFlick); } else { @@ -1877,14 +2008,19 @@ return; d->inViewportMoved = true; - if (yflick()) - d->bufferMode = d->vData.smoothVelocity < 0 ? QQuickItemViewPrivate::BufferBefore : QQuickItemViewPrivate::BufferAfter; - else if (d->isRightToLeftTopToBottom()) - d->bufferMode = d->hData.smoothVelocity < 0 ? QQuickItemViewPrivate::BufferAfter : QQuickItemViewPrivate::BufferBefore; - else - d->bufferMode = d->hData.smoothVelocity < 0 ? QQuickItemViewPrivate::BufferBefore : QQuickItemViewPrivate::BufferAfter; + if (yflick()) { + if (d->isContentFlowReversed()) + d->bufferMode = d->vData.smoothVelocity < 0 ? QQuickItemViewPrivate::BufferAfter : QQuickItemViewPrivate::BufferBefore; + else + d->bufferMode = d->vData.smoothVelocity < 0 ? QQuickItemViewPrivate::BufferBefore : QQuickItemViewPrivate::BufferAfter; + } else { + if (d->isContentFlowReversed()) + d->bufferMode = d->hData.smoothVelocity < 0 ? QQuickItemViewPrivate::BufferAfter : QQuickItemViewPrivate::BufferBefore; + else + d->bufferMode = d->hData.smoothVelocity < 0 ? QQuickItemViewPrivate::BufferBefore : QQuickItemViewPrivate::BufferAfter; + } - d->refill(); + d->refillOrLayout(); // Set visibility of items to eliminate cost of items outside the visible area. qreal from = d->isContentFlowReversed() ? -d->position()-d->size() : d->position(); @@ -1904,7 +2040,7 @@ if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange && d->highlight) { // reposition highlight qreal pos = d->highlight->position(); - qreal viewPos = d->isRightToLeftTopToBottom() ? -d->position()-d->size() : d->position(); + qreal viewPos = d->isContentFlowReversed() ? -d->position()-d->size() : d->position(); if (pos > viewPos + d->highlightRangeEnd - d->highlight->size()) pos = viewPos + d->highlightRangeEnd - d->highlight->size(); if (pos < viewPos + d->highlightRangeStart) @@ -1923,7 +2059,7 @@ if (idx >= 0 && idx != d->currentIndex) { d->updateCurrent(idx); if (d->currentItem && static_cast(d->currentItem)->colPos() != static_cast(d->highlight)->colPos() && d->autoHighlight) { - if (d->flow == LeftToRight) + if (d->flow == FlowLeftToRight) d->highlightXAnimator->to = d->currentItem->itemX(); else d->highlightYAnimator->to = d->currentItem->itemY(); @@ -1970,6 +2106,16 @@ { Q_D(QQuickGridView); d->resetColumns(); + + if (newGeometry.width() != oldGeometry.width() + && newGeometry.height() != oldGeometry.height()) { + d->setPosition(d->position()); + } else if (newGeometry.width() != oldGeometry.width()) { + QQuickFlickable::setContentX(d->contentXForPosition(d->position())); + } else if (newGeometry.height() != oldGeometry.height()) { + QQuickFlickable::setContentY(d->contentYForPosition(d->position())); + } + QQuickItemView::geometryChanged(newGeometry, oldGeometry); } @@ -1990,15 +2136,29 @@ const int count = d->model ? d->model->count() : 0; if (!count) return; - if (d->flow == QQuickGridView::LeftToRight) { - if (currentIndex() >= d->columns || d->wrap) { - int index = currentIndex() - d->columns; - setCurrentIndex((index >= 0 && index < count) ? index : count-1); + if (d->verticalLayoutDirection == QQuickItemView::TopToBottom) { + if (d->flow == QQuickGridView::FlowLeftToRight) { + if (currentIndex() >= d->columns || d->wrap) { + int index = currentIndex() - d->columns; + setCurrentIndex((index >= 0 && index < count) ? index : count-1); + } + } else { + if (currentIndex() > 0 || d->wrap) { + int index = currentIndex() - 1; + setCurrentIndex((index >= 0 && index < count) ? index : count-1); + } } } else { - if (currentIndex() > 0 || d->wrap) { - int index = currentIndex() - 1; - setCurrentIndex((index >= 0 && index < count) ? index : count-1); + if (d->flow == QQuickGridView::FlowLeftToRight) { + if (currentIndex() < count - d->columns || d->wrap) { + int index = currentIndex()+d->columns; + setCurrentIndex((index >= 0 && index < count) ? index : 0); + } + } else { + if (currentIndex() < count - 1 || d->wrap) { + int index = currentIndex() + 1; + setCurrentIndex((index >= 0 && index < count) ? index : 0); + } } } } @@ -2018,15 +2178,30 @@ const int count = d->model ? d->model->count() : 0; if (!count) return; - if (d->flow == QQuickGridView::LeftToRight) { - if (currentIndex() < count - d->columns || d->wrap) { - int index = currentIndex()+d->columns; - setCurrentIndex((index >= 0 && index < count) ? index : 0); + + if (d->verticalLayoutDirection == QQuickItemView::TopToBottom) { + if (d->flow == QQuickGridView::FlowLeftToRight) { + if (currentIndex() < count - d->columns || d->wrap) { + int index = currentIndex()+d->columns; + setCurrentIndex((index >= 0 && index < count) ? index : 0); + } + } else { + if (currentIndex() < count - 1 || d->wrap) { + int index = currentIndex() + 1; + setCurrentIndex((index >= 0 && index < count) ? index : 0); + } } } else { - if (currentIndex() < count - 1 || d->wrap) { - int index = currentIndex() + 1; - setCurrentIndex((index >= 0 && index < count) ? index : 0); + if (d->flow == QQuickGridView::FlowLeftToRight) { + if (currentIndex() >= d->columns || d->wrap) { + int index = currentIndex() - d->columns; + setCurrentIndex((index >= 0 && index < count) ? index : count-1); + } + } else { + if (currentIndex() > 0 || d->wrap) { + int index = currentIndex() - 1; + setCurrentIndex((index >= 0 && index < count) ? index : count-1); + } } } } @@ -2047,7 +2222,7 @@ if (!count) return; if (effectiveLayoutDirection() == Qt::LeftToRight) { - if (d->flow == QQuickGridView::LeftToRight) { + if (d->flow == QQuickGridView::FlowLeftToRight) { if (currentIndex() > 0 || d->wrap) { int index = currentIndex() - 1; setCurrentIndex((index >= 0 && index < count) ? index : count-1); @@ -2059,7 +2234,7 @@ } } } else { - if (d->flow == QQuickGridView::LeftToRight) { + if (d->flow == QQuickGridView::FlowLeftToRight) { if (currentIndex() < count - 1 || d->wrap) { int index = currentIndex() + 1; setCurrentIndex((index >= 0 && index < count) ? index : 0); @@ -2090,7 +2265,7 @@ if (!count) return; if (effectiveLayoutDirection() == Qt::LeftToRight) { - if (d->flow == QQuickGridView::LeftToRight) { + if (d->flow == QQuickGridView::FlowLeftToRight) { if (currentIndex() < count - 1 || d->wrap) { int index = currentIndex() + 1; setCurrentIndex((index >= 0 && index < count) ? index : 0); @@ -2102,7 +2277,7 @@ } } } else { - if (d->flow == QQuickGridView::LeftToRight) { + if (d->flow == QQuickGridView::FlowLeftToRight) { if (currentIndex() > 0 || d->wrap) { int index = currentIndex() - 1; setCurrentIndex((index >= 0 && index < count) ? index : count-1); @@ -2146,7 +2321,7 @@ } } - qreal tempPos = isRightToLeftTopToBottom() ? -position()-size()+q->width()+1 : position(); + qreal tempPos = isContentFlowReversed() ? -position()-size()+q->width()+1 : position(); qreal colPos = 0; qreal rowPos = 0; int colNum = 0; diff -Nru qt5-declarative-0.1~git20120402/src/quick/items/qquickgridview_p.h qt5-declarative-0.1~git20120423/src/quick/items/qquickgridview_p.h --- qt5-declarative-0.1~git20120402/src/quick/items/qquickgridview_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/items/qquickgridview_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -69,13 +69,17 @@ Q_CLASSINFO("DefaultProperty", "data") public: + enum Flow { + FlowLeftToRight = LeftToRight, + FlowTopToBottom = TopToBottom + }; + QQuickGridView(QQuickItem *parent=0); ~QQuickGridView(); virtual void setHighlightFollowsCurrentItem(bool); virtual void setHighlightMoveDuration(int); - enum Flow { LeftToRight, TopToBottom }; Flow flow() const; void setFlow(Flow); diff -Nru qt5-declarative-0.1~git20120402/src/quick/items/qquickimplicitsizeitem_p.h qt5-declarative-0.1~git20120423/src/quick/items/qquickimplicitsizeitem_p.h --- qt5-declarative-0.1~git20120402/src/quick/items/qquickimplicitsizeitem_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/items/qquickimplicitsizeitem_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -49,7 +49,7 @@ QT_BEGIN_NAMESPACE class QQuickImplicitSizeItemPrivate; -class Q_AUTOTEST_EXPORT QQuickImplicitSizeItem : public QQuickItem +class Q_QUICK_EXPORT QQuickImplicitSizeItem : public QQuickItem { Q_OBJECT Q_PROPERTY(qreal implicitWidth READ implicitWidth NOTIFY implicitWidthChanged) diff -Nru qt5-declarative-0.1~git20120402/src/quick/items/qquickitem.cpp qt5-declarative-0.1~git20120423/src/quick/items/qquickitem.cpp --- qt5-declarative-0.1~git20120402/src/quick/items/qquickitem.cpp 2012-04-02 11:02:55.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/items/qquickitem.cpp 2012-04-23 11:44:59.000000000 +0000 @@ -76,6 +76,7 @@ QT_BEGIN_NAMESPACE #ifdef FOCUS_DEBUG +void printFocusTree(QQuickItem *item, QQuickItem *scope = 0, int depth = 1); void printFocusTree(QQuickItem *item, QQuickItem *scope, int depth) { qWarning() @@ -1632,9 +1633,6 @@ if (item->d_func()->isAccessible) break; // already set - grandparents should have the flag set as well. - if (item->canvas() && item->canvas()->rootItem() == item) - break; // don't add a listener to the canvas root item - item->d_func()->isAccessible = true; item = item->d_func()->parentItem; } @@ -1958,6 +1956,8 @@ if (d->canvas) { QQuickCanvasPrivate::get(d->canvas)->clearFocusInScope(scopeItem, scopeFocusedItem, QQuickCanvasPrivate::DontChangeFocusProperty); + if (scopeFocusedItem != this) + QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(this, true); } else { QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(scopeItem, false); } @@ -4160,7 +4160,7 @@ for (int ii = 0; ii < childItems.count(); ++ii) { QQuickItemPrivate::get(childItems.at(ii))->setEffectiveEnableRecur( - flags & QQuickItem::ItemIsFocusScope ? q : scope, newEffectiveEnable); + (flags & QQuickItem::ItemIsFocusScope) && scope ? q : scope, newEffectiveEnable); } if (canvas && scope && effectiveEnable && focus) { @@ -4808,6 +4808,7 @@ QVarLengthArray changed; QQuickItem *oldSubFocusItem = QQuickItemPrivate::get(scope)->subFocusItem; if (oldSubFocusItem) { + QQuickItemPrivate::get(oldSubFocusItem)->updateSubFocusItem(scope, false); QQuickItemPrivate::get(oldSubFocusItem)->focus = false; changed << oldSubFocusItem; } @@ -5696,10 +5697,11 @@ Q_ASSERT(m_effectComponent); Q_ASSERT(!m_effect); - QObject *created = m_effectComponent->create(); + QObject *created = m_effectComponent->beginCreate(m_effectComponent->creationContext()); m_effect = qobject_cast(created); if (!m_effect) { qWarning("Item: layer.effect is not a QML Item."); + m_effectComponent->completeCreate(); delete created; return; } @@ -5710,6 +5712,7 @@ } m_effect->setVisible(m_item->isVisible()); m_effect->setProperty(m_name, qVariantFromValue(m_effectSource)); + m_effectComponent->completeCreate(); } void QQuickItemLayer::deactivateEffect() diff -Nru qt5-declarative-0.1~git20120402/src/quick/items/qquickitemview.cpp qt5-declarative-0.1~git20120423/src/quick/items/qquickitemview.cpp --- qt5-declarative-0.1~git20120402/src/quick/items/qquickitemview.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/items/qquickitemview.cpp 2012-04-23 11:44:59.000000000 +0000 @@ -442,7 +442,7 @@ d->buffer = b; if (isComponentComplete()) { d->bufferMode = QQuickItemViewPrivate::BufferBefore | QQuickItemViewPrivate::BufferAfter; - d->refill(); + d->refillOrLayout(); } emit cacheBufferChanged(); } @@ -475,6 +475,21 @@ return d->layoutDirection; } +QQuickItemView::VerticalLayoutDirection QQuickItemView::verticalLayoutDirection() const +{ + Q_D(const QQuickItemView); + return d->verticalLayoutDirection; +} + +void QQuickItemView::setVerticalLayoutDirection(VerticalLayoutDirection layoutDirection) +{ + Q_D(QQuickItemView); + if (d->verticalLayoutDirection != layoutDirection) { + d->verticalLayoutDirection = layoutDirection; + d->regenerate(); + emit verticalLayoutDirectionChanged(); + } +} QQmlComponent *QQuickItemView::header() const { @@ -818,7 +833,7 @@ FxViewItem *item = visibleItem(idx); qreal maxExtent; if (layoutOrientation() == Qt::Vertical) - maxExtent = -q->maxYExtent(); + maxExtent = isContentFlowReversed() ? q->minYExtent()-size(): -q->maxYExtent(); else maxExtent = isContentFlowReversed() ? q->minXExtent()-size(): -q->maxXExtent(); if (!item) { @@ -864,7 +879,7 @@ pos = qMin(pos, maxExtent); qreal minExtent; if (layoutOrientation() == Qt::Vertical) - minExtent = -q->minYExtent(); + minExtent = isContentFlowReversed() ? q->maxYExtent()-size(): -q->minYExtent(); else minExtent = isContentFlowReversed() ? q->maxXExtent()-size(): -q->minXExtent(); pos = qMax(pos, minExtent); @@ -948,6 +963,89 @@ return -1; } +qreal QQuickItemViewPrivate::minExtentForAxis(const AxisData &axisData, bool forXAxis) const +{ + Q_Q(const QQuickItemView); + + qreal highlightStart; + qreal highlightEnd; + qreal endPositionFirstItem = 0; + qreal extent = -startPosition() + axisData.startMargin; + if (isContentFlowReversed()) { + if (model && model->count()) + endPositionFirstItem = positionAt(model->count()-1); + else + extent += headerSize(); + highlightStart = highlightRangeEndValid ? size() - highlightRangeEnd : size(); + highlightEnd = highlightRangeStartValid ? size() - highlightRangeStart : size(); + extent += footerSize(); + qreal maxExtentAlongAxis = forXAxis ? q->maxXExtent() : q->maxYExtent(); + if (extent < maxExtentAlongAxis) + extent = maxExtentAlongAxis; + } else { + endPositionFirstItem = endPositionAt(0); + highlightStart = highlightRangeStart; + highlightEnd = highlightRangeEnd; + extent += headerSize(); + } + if (haveHighlightRange && highlightRange == QQuickItemView::StrictlyEnforceRange) { + extent += highlightStart; + FxViewItem *firstItem = visibleItem(0); + if (firstItem) + extent -= firstItem->sectionSize(); + extent = isContentFlowReversed() + ? qMin(extent, endPositionFirstItem + highlightEnd) + : qMax(extent, -(endPositionFirstItem - highlightEnd)); + } + return extent; +} + +qreal QQuickItemViewPrivate::maxExtentForAxis(const AxisData &axisData, bool forXAxis) const +{ + Q_Q(const QQuickItemView); + + qreal highlightStart; + qreal highlightEnd; + qreal lastItemPosition = 0; + qreal extent = 0; + if (isContentFlowReversed()) { + highlightStart = highlightRangeEndValid ? size() - highlightRangeEnd : size(); + highlightEnd = highlightRangeStartValid ? size() - highlightRangeStart : size(); + lastItemPosition = endPosition(); + } else { + highlightStart = highlightRangeStart; + highlightEnd = highlightRangeEnd; + if (model && model->count()) + lastItemPosition = positionAt(model->count()-1); + } + if (!model || !model->count()) { + if (!isContentFlowReversed()) + maxExtent = header ? -headerSize() : 0; + extent += forXAxis ? q->width() : q->height(); + } else if (haveHighlightRange && highlightRange == QQuickItemView::StrictlyEnforceRange) { + extent = -(lastItemPosition - highlightStart); + if (highlightEnd != highlightStart) { + extent = isContentFlowReversed() + ? qMax(extent, -(endPosition() - highlightEnd)) + : qMin(extent, -(endPosition() - highlightEnd)); + } + } else { + extent = -(endPosition() - (forXAxis ? q->width() : q->height())); + } + if (isContentFlowReversed()) { + extent -= headerSize(); + extent -= axisData.endMargin; + } else { + extent -= footerSize(); + extent -= axisData.endMargin; + qreal minExtentAlongAxis = forXAxis ? q->minXExtent() : q->minYExtent(); + if (extent > minExtentAlongAxis) + extent = minExtentAlongAxis; + } + + return extent; +} + // for debugging only void QQuickItemViewPrivate::checkVisible() const { @@ -1075,7 +1173,7 @@ { Q_D(QQuickItemView); d->bufferMode = QQuickItemViewPrivate::BufferBefore | QQuickItemViewPrivate::BufferAfter; - d->refill(); + d->refillOrLayout(); if (d->haveHighlightRange && d->highlightRange == QQuickItemView::StrictlyEnforceRange) d->updateHighlight(); } @@ -1119,12 +1217,17 @@ toItemEndPos -= startOffset; } else if (d->showFooterForIndex(d->currentIndex)) { qreal endOffset = d->footerSize(); - if (d->layoutOrientation() == Qt::Vertical) - endOffset += d->vData.endMargin; - else if (d->isContentFlowReversed()) - endOffset += d->hData.startMargin; - else - endOffset += d->hData.endMargin; + if (d->layoutOrientation() == Qt::Vertical) { + if (d->isContentFlowReversed()) + endOffset += d->vData.startMargin; + else + endOffset += d->vData.endMargin; + } else { + if (d->isContentFlowReversed()) + endOffset += d->hData.startMargin; + else + endOffset += d->hData.endMargin; + } trackedPos += endOffset; trackedEndPos += endOffset; toItemPos += endOffset; @@ -1166,7 +1269,6 @@ QQuickFlickable::geometryChanged(newGeometry, oldGeometry); } - qreal QQuickItemView::minYExtent() const { Q_D(const QQuickItemView); @@ -1174,15 +1276,7 @@ return QQuickFlickable::minYExtent(); if (d->vData.minExtentDirty) { - d->minExtent = d->vData.startMargin-d->startPosition(); - if (d->header) - d->minExtent += d->headerSize(); - if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { - d->minExtent += d->highlightRangeStart; - if (d->visibleItem(0)) - d->minExtent -= d->visibleItem(0)->sectionSize(); - d->minExtent = qMax(d->minExtent, -(d->endPositionAt(0) - d->highlightRangeEnd)); - } + d->minExtent = d->minExtentForAxis(d->vData, false); d->vData.minExtentDirty = false; } @@ -1196,25 +1290,10 @@ return height(); if (d->vData.maxExtentDirty) { - if (!d->model || !d->model->count()) { - d->maxExtent = d->header ? -d->headerSize() : 0; - d->maxExtent += height(); - } else if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { - d->maxExtent = -(d->positionAt(d->model->count()-1) - d->highlightRangeStart); - if (d->highlightRangeEnd != d->highlightRangeStart) - d->maxExtent = qMin(d->maxExtent, -(d->endPosition() - d->highlightRangeEnd)); - } else { - d->maxExtent = -(d->endPosition() - height()); - } - - if (d->footer) - d->maxExtent -= d->footerSize(); - d->maxExtent -= d->vData.endMargin; - qreal minY = minYExtent(); - if (d->maxExtent > minY) - d->maxExtent = minY; + d->maxExtent = d->maxExtentForAxis(d->vData, false); d->vData.maxExtentDirty = false; } + return d->maxExtent; } @@ -1225,35 +1304,7 @@ return QQuickFlickable::minXExtent(); if (d->hData.minExtentDirty) { - d->minExtent = -d->startPosition() + d->hData.startMargin; - qreal highlightStart; - qreal highlightEnd; - qreal endPositionFirstItem = 0; - if (d->isContentFlowReversed()) { - if (d->model && d->model->count()) - endPositionFirstItem = d->positionAt(d->model->count()-1); - else if (d->header) - d->minExtent += d->headerSize(); - highlightStart = d->highlightRangeEndValid ? d->size() - d->highlightRangeEnd : d->size(); - highlightEnd = d->highlightRangeStartValid ? d->size() - d->highlightRangeStart : d->size(); - if (d->footer) - d->minExtent += d->footerSize(); - qreal maxX = maxXExtent(); - if (d->minExtent < maxX) - d->minExtent = maxX; - } else { - endPositionFirstItem = d->endPositionAt(0); - highlightStart = d->highlightRangeStart; - highlightEnd = d->highlightRangeEnd; - if (d->header) - d->minExtent += d->headerSize(); - } - if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { - d->minExtent += highlightStart; - d->minExtent = d->isContentFlowReversed() - ? qMin(d->minExtent, endPositionFirstItem + highlightEnd) - : qMax(d->minExtent, -(endPositionFirstItem - highlightEnd)); - } + d->minExtent = d->minExtentForAxis(d->hData, true); d->hData.minExtentDirty = false; } @@ -1267,46 +1318,7 @@ return width(); if (d->hData.maxExtentDirty) { - qreal highlightStart; - qreal highlightEnd; - qreal lastItemPosition = 0; - d->maxExtent = 0; - if (d->isContentFlowReversed()) { - highlightStart = d->highlightRangeEndValid ? d->size() - d->highlightRangeEnd : d->size(); - highlightEnd = d->highlightRangeStartValid ? d->size() - d->highlightRangeStart : d->size(); - lastItemPosition = d->endPosition(); - } else { - highlightStart = d->highlightRangeStart; - highlightEnd = d->highlightRangeEnd; - if (d->model && d->model->count()) - lastItemPosition = d->positionAt(d->model->count()-1); - } - if (!d->model || !d->model->count()) { - if (!d->isContentFlowReversed()) - d->maxExtent = d->header ? -d->headerSize() : 0; - d->maxExtent += width(); - } else if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { - d->maxExtent = -(lastItemPosition - highlightStart); - if (highlightEnd != highlightStart) { - d->maxExtent = d->isContentFlowReversed() - ? qMax(d->maxExtent, -(d->endPosition() - highlightEnd)) - : qMin(d->maxExtent, -(d->endPosition() - highlightEnd)); - } - } else { - d->maxExtent = -(d->endPosition() - width()); - } - if (d->isContentFlowReversed()) { - if (d->header) - d->maxExtent -= d->headerSize(); - d->maxExtent -= d->hData.endMargin; - } else { - if (d->footer) - d->maxExtent -= d->footerSize(); - d->maxExtent -= d->hData.endMargin; - qreal minX = minXExtent(); - if (d->maxExtent > minX) - d->maxExtent = minX; - } + d->maxExtent = d->maxExtentForAxis(d->hData, true); d->hData.maxExtentDirty = false; } @@ -1338,6 +1350,15 @@ return -minXExtent() + d->hData.startMargin; } +qreal QQuickItemView::yOrigin() const +{ + Q_D(const QQuickItemView); + if (d->isContentFlowReversed()) + return -maxYExtent() + d->size() - d->vData.endMargin; + else + return -minYExtent() + d->vData.startMargin; +} + void QQuickItemView::updatePolish() { Q_D(QQuickItemView); @@ -1385,7 +1406,7 @@ QQuickItemViewPrivate::QQuickItemViewPrivate() : itemCount(0) , buffer(0), bufferMode(BufferBefore | BufferAfter) - , layoutDirection(Qt::LeftToRight) + , layoutDirection(Qt::LeftToRight), verticalLayoutDirection(QQuickItemView::TopToBottom) , moveReason(Other) , visibleIndex(0) , currentIndex(-1), currentItem(0) @@ -1442,13 +1463,17 @@ qreal QQuickItemViewPrivate::contentStartOffset() const { qreal pos = -headerSize(); - if (layoutOrientation() == Qt::Vertical) - pos -= vData.startMargin; - else if (isContentFlowReversed()) - pos -= hData.endMargin; - else - pos -= hData.startMargin; - + if (layoutOrientation() == Qt::Vertical) { + if (isContentFlowReversed()) + pos -= vData.endMargin; + else + pos -= vData.startMargin; + } else { + if (isContentFlowReversed()) + pos -= hData.endMargin; + else + pos -= hData.startMargin; + } return pos; } @@ -1777,7 +1802,7 @@ bool QQuickItemViewPrivate::applyModelChanges(ChangeResult *totalInsertionResult, ChangeResult *totalRemovalResult) { Q_Q(QQuickItemView); - if (!q->isComponentComplete() || (!currentChanges.hasPendingChanges() && !bufferedChanges.hasPendingChanges() && !runDelayedRemoveTransition) || disableLayout) + if (!q->isComponentComplete() || !hasPendingChanges() || disableLayout) return false; disableLayout = true; diff -Nru qt5-declarative-0.1~git20120402/src/quick/items/qquickitemview_p.h qt5-declarative-0.1~git20120423/src/quick/items/qquickitemview_p.h --- qt5-declarative-0.1~git20120402/src/quick/items/qquickitemview_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/items/qquickitemview_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -70,6 +70,7 @@ Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection NOTIFY layoutDirectionChanged) Q_PROPERTY(Qt::LayoutDirection effectiveLayoutDirection READ effectiveLayoutDirection NOTIFY effectiveLayoutDirectionChanged) + Q_PROPERTY(VerticalLayoutDirection verticalLayoutDirection READ verticalLayoutDirection WRITE setVerticalLayoutDirection NOTIFY verticalLayoutDirectionChanged) Q_PROPERTY(QQmlComponent *header READ header WRITE setHeader NOTIFY headerChanged) Q_PROPERTY(QQuickItem *headerItem READ headerItem NOTIFY headerItemChanged) @@ -95,8 +96,25 @@ Q_ENUMS(HighlightRangeMode) Q_ENUMS(PositionMode) + Q_ENUMS(VerticalLayoutDirection) + Q_ENUMS(LayoutDirection) public: + // this holds all layout enum values so they can be referred to by other enums + // to ensure consistent values - e.g. QML references to GridView.TopToBottom flow + // and GridView.TopToBottom vertical layout direction should have same value + enum LayoutDirection { + LeftToRight = Qt::LeftToRight, + RightToLeft = Qt::RightToLeft, + VerticalTopToBottom, + VerticalBottomToTop + }; + + enum VerticalLayoutDirection { + TopToBottom = VerticalTopToBottom, + BottomToTop = VerticalBottomToTop + }; + QQuickItemView(QQuickFlickablePrivate &dd, QQuickItem *parent = 0); ~QQuickItemView(); @@ -123,6 +141,9 @@ void setLayoutDirection(Qt::LayoutDirection); Qt::LayoutDirection effectiveLayoutDirection() const; + VerticalLayoutDirection verticalLayoutDirection() const; + void setVerticalLayoutDirection(VerticalLayoutDirection layoutDirection); + QQmlComponent *footer() const; void setFooter(QQmlComponent *); QQuickItem *footerItem() const; @@ -189,6 +210,7 @@ virtual void setContentX(qreal pos); virtual void setContentY(qreal pos); virtual qreal xOrigin() const; + virtual qreal yOrigin() const; signals: void modelChanged(); @@ -202,6 +224,7 @@ void layoutDirectionChanged(); void effectiveLayoutDirectionChanged(); + void verticalLayoutDirectionChanged(); void headerChanged(); void footerChanged(); diff -Nru qt5-declarative-0.1~git20120402/src/quick/items/qquickitemview_p_p.h qt5-declarative-0.1~git20120423/src/quick/items/qquickitemview_p_p.h --- qt5-declarative-0.1~git20120402/src/quick/items/qquickitemview_p_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/items/qquickitemview_p_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -204,6 +204,10 @@ void updateUnrequestedPositions(); void updateVisibleIndex(); void positionViewAtIndex(int index, int mode); + + qreal minExtentForAxis(const AxisData &axisData, bool forXAxis) const; + qreal maxExtentForAxis(const AxisData &axisData, bool forXAxis) const; + void applyPendingChanges(); bool applyModelChanges(ChangeResult *insertionResult, ChangeResult *removalResult); bool applyRemovalChange(const QQuickChangeSet::Remove &removal, ChangeResult *changeResult, int *removedCount); @@ -229,12 +233,26 @@ hData.markExtentsDirty(); } + bool hasPendingChanges() const { + return currentChanges.hasPendingChanges() + || bufferedChanges.hasPendingChanges() + ||runDelayedRemoveTransition; + } + + void refillOrLayout() { + if (hasPendingChanges()) + layout(); + else + refill(); + } + QQmlGuard model; QVariant modelVariant; int itemCount; int buffer; int bufferMode; Qt::LayoutDirection layoutDirection; + QQuickItemView::VerticalLayoutDirection verticalLayoutDirection; MovementReason moveReason; diff -Nru qt5-declarative-0.1~git20120402/src/quick/items/qquicklistview.cpp qt5-declarative-0.1~git20120423/src/quick/items/qquicklistview.cpp --- qt5-declarative-0.1~git20120402/src/quick/items/qquicklistview.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/items/qquicklistview.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -73,6 +73,7 @@ virtual Qt::Orientation layoutOrientation() const; virtual bool isContentFlowReversed() const; bool isRightToLeft() const; + bool isBottomToTop() const; virtual qreal positionAt(int index) const; virtual qreal endPositionAt(int index) const; @@ -265,7 +266,7 @@ qreal position() const { if (section()) { if (view->orientation() == QQuickListView::Vertical) - return section()->y(); + return (view->verticalLayoutDirection() == QQuickItemView::BottomToTop ? -section()->height()-section()->y() : section()->y()); else return (view->effectiveLayoutDirection() == Qt::RightToLeft ? -section()->width()-section()->x() : section()->x()); } else { @@ -274,7 +275,7 @@ } qreal itemPosition() const { if (view->orientation() == QQuickListView::Vertical) - return itemY(); + return (view->verticalLayoutDirection() == QQuickItemView::BottomToTop ? -item->height()-itemY() : itemY()); else return (view->effectiveLayoutDirection() == Qt::RightToLeft ? -item->width()-itemX() : itemX()); } @@ -294,7 +295,9 @@ } qreal endPosition() const { if (view->orientation() == QQuickListView::Vertical) { - return itemY() + item->height(); + return (view->verticalLayoutDirection() == QQuickItemView::BottomToTop + ? -itemY() + : itemY() + item->height()); } else { return (view->effectiveLayoutDirection() == Qt::RightToLeft ? -itemX() @@ -305,7 +308,10 @@ // position the section immediately even if there is a transition if (section()) { if (view->orientation() == QQuickListView::Vertical) { - section()->setY(pos); + if (view->verticalLayoutDirection() == QQuickItemView::BottomToTop) + section()->setY(-section()->height()-pos); + else + section()->setY(pos); } else { if (view->effectiveLayoutDirection() == Qt::RightToLeft) section()->setX(-section()->width()-pos); @@ -331,9 +337,15 @@ private: QPointF pointForPosition(qreal pos) const { if (view->orientation() == QQuickListView::Vertical) { - if (section()) - pos += section()->height(); - return QPointF(itemX(), pos); + if (view->verticalLayoutDirection() == QQuickItemView::BottomToTop) { + if (section()) + pos += section()->height(); + return QPointF(itemX(), -item->height() - pos); + } else { + if (section()) + pos += section()->height(); + return QPointF(itemX(), pos); + } } else { if (view->effectiveLayoutDirection() == Qt::RightToLeft) { if (section()) @@ -352,7 +364,7 @@ bool QQuickListViewPrivate::isContentFlowReversed() const { - return isRightToLeft(); + return isRightToLeft() || isBottomToTop(); } Qt::Orientation QQuickListViewPrivate::layoutOrientation() const @@ -366,6 +378,11 @@ return orient == QQuickListView::Horizontal && q->effectiveLayoutDirection() == Qt::RightToLeft; } +bool QQuickListViewPrivate::isBottomToTop() const +{ + return orient == QQuickListView::Vertical && verticalLayoutDirection == QQuickItemView::BottomToTop; +} + // Returns the item before modelIndex, if created. // May return an item marked for removal. FxViewItem *QQuickListViewPrivate::itemBefore(int modelIndex) const @@ -391,7 +408,10 @@ { Q_Q(QQuickListView); if (orient == QQuickListView::Vertical) { - q->QQuickFlickable::setContentY(pos); + if (isBottomToTop()) + q->QQuickFlickable::setContentY(-pos-size()); + else + q->QQuickFlickable::setContentY(pos); } else { if (isRightToLeft()) q->QQuickFlickable::setContentX(-pos-size()); @@ -797,8 +817,12 @@ Q_Q(QQuickListView); qreal pos = position(); if (orient == QQuickListView::Vertical) { - if (item->y() + item->height() > pos && item->y() < pos + q->height()) - item->setY(positionAt(index)); + if (item->y() + item->height() > pos && item->y() < pos + q->height()) { + if (isBottomToTop()) + item->setY(-positionAt(index)-item->height()); + else + item->setY(positionAt(index)); + } } else { if (item->x() + item->width() > pos && item->x() < pos + q->width()) { if (isRightToLeft()) @@ -880,7 +904,7 @@ if (currentItem && autoHighlight && highlight && (!strictHighlight || !pressed)) { // auto-update highlight FxListItemSG *listItem = static_cast(currentItem); - highlightPosAnimator->to = isRightToLeft() + highlightPosAnimator->to = isContentFlowReversed() ? -listItem->itemPosition()-listItem->itemSize() : listItem->itemPosition(); highlightSizeAnimator->to = listItem->itemSize(); @@ -987,8 +1011,8 @@ || (!sectionCriteria->labelPositioning() && !currentSectionItem && !nextSectionItem)) return; - bool isRtl = isRightToLeft(); - qreal viewPos = isRightToLeft() ? -position()-size() : position(); + bool isFlowReversed = isContentFlowReversed(); + qreal viewPos = isFlowReversed ? -position()-size() : position(); QQuickItem *sectionItem = 0; QQuickItem *lastSectionItem = 0; int index = 0; @@ -1000,14 +1024,14 @@ qreal sectionSize = orient == QQuickListView::Vertical ? section->height() : section->width(); bool visTop = true; if (sectionCriteria->labelPositioning() & QQuickViewSection::CurrentLabelAtStart) - visTop = isRtl ? -sectionPos-sectionSize >= viewPos : sectionPos >= viewPos; + visTop = isFlowReversed ? -sectionPos-sectionSize >= viewPos : sectionPos >= viewPos; bool visBot = true; if (sectionCriteria->labelPositioning() & QQuickViewSection::NextLabelAtEnd) - visBot = isRtl ? -sectionPos <= viewPos + size() : sectionPos + sectionSize < viewPos + size(); + visBot = isFlowReversed ? -sectionPos <= viewPos + size() : sectionPos + sectionSize < viewPos + size(); section->setVisible(visBot && visTop); if (visTop && !sectionItem) sectionItem = section; - if (isRtl) { + if (isFlowReversed) { if (-sectionPos <= viewPos + size()) lastSectionItem = section; } else { @@ -1031,17 +1055,18 @@ return; qreal sectionSize = orient == QQuickListView::Vertical ? currentSectionItem->height() : currentSectionItem->width(); - bool atBeginning = orient == QQuickListView::Vertical ? vData.atBeginning : (isRightToLeft() ? hData.atEnd : hData.atBeginning); + bool atBeginning = orient == QQuickListView::Vertical ? (isBottomToTop() ? vData.atEnd : vData.atBeginning) : (isRightToLeft() ? hData.atEnd : hData.atBeginning); + currentSectionItem->setVisible(!atBeginning && (!header || header->endPosition() < viewPos)); - qreal pos = isRtl ? position() + size() - sectionSize : viewPos; + qreal pos = isFlowReversed ? position() + size() - sectionSize : viewPos; if (sectionItem) { qreal sectionPos = orient == QQuickListView::Vertical ? sectionItem->y() : sectionItem->x(); - pos = isRtl ? qMax(pos, sectionPos + sectionSize) : qMin(pos, sectionPos - sectionSize); + pos = isFlowReversed ? qMax(pos, sectionPos + sectionSize) : qMin(pos, sectionPos - sectionSize); } if (header) - pos = isRtl ? qMin(header->endPosition(), pos) : qMax(header->endPosition(), pos); + pos = isFlowReversed ? qMin(header->endPosition(), pos) : qMax(header->endPosition(), pos); if (footer) - pos = isRtl ? qMax(-footer->position(), pos) : qMin(footer->position() - sectionSize, pos); + pos = isFlowReversed ? qMax(-footer->position(), pos) : qMin(footer->position() - sectionSize, pos); if (orient == QQuickListView::Vertical) currentSectionItem->setY(pos); else @@ -1065,13 +1090,13 @@ qreal sectionSize = orient == QQuickListView::Vertical ? nextSectionItem->height() : nextSectionItem->width(); nextSectionItem->setVisible(!nextSection.isEmpty()); - qreal pos = isRtl ? position() : viewPos + size() - sectionSize; + qreal pos = isFlowReversed ? position() : viewPos + size() - sectionSize; if (lastSectionItem) { qreal sectionPos = orient == QQuickListView::Vertical ? lastSectionItem->y() : lastSectionItem->x(); - pos = isRtl ? qMin(pos, sectionPos - sectionSize) : qMax(pos, sectionPos + sectionSize); + pos = isFlowReversed ? qMin(pos, sectionPos - sectionSize) : qMax(pos, sectionPos + sectionSize); } if (header) - pos = isRtl ? qMin(header->endPosition() - sectionSize, pos) : qMax(header->endPosition(), pos); + pos = isFlowReversed ? qMin(header->endPosition() - sectionSize, pos) : qMax(header->endPosition(), pos); if (orient == QQuickListView::Vertical) nextSectionItem->setY(pos); else @@ -1162,7 +1187,7 @@ // section when that changes. Clearing lastVisibleSection will also // force searching. QString lastSection = currentSection; - qreal endPos = isRightToLeft() ? -position() : position() + size(); + qreal endPos = isContentFlowReversed() ? -position() : position() + size(); if (nextSectionItem && !inlineSections) endPos -= orient == QQuickListView::Vertical ? nextSectionItem->height() : nextSectionItem->width(); while (index < visibleItems.count() && static_cast(visibleItems.at(index))->itemPosition() < endPos) { @@ -1341,10 +1366,10 @@ fixupMode = moveReason == Mouse ? fixupMode : Immediate; bool strictHighlightRange = haveHighlightRange && highlightRange == QQuickListView::StrictlyEnforceRange; - qreal viewPos = isRightToLeft() ? -position()-size() : position(); + qreal viewPos = isContentFlowReversed() ? -position()-size() : position(); if (snapMode != QQuickListView::NoSnap && moveReason != QQuickListViewPrivate::SetIndex) { - qreal tempPosition = isRightToLeft() ? -position()-size() : position(); + qreal tempPosition = isContentFlowReversed() ? -position()-size() : position(); if (snapMode == QQuickListView::SnapOneItem && moveReason == Mouse) { // if we've been dragged < averageSize/2 then bias towards the next item qreal dist = data.move.value() - (data.pressPos - data.dragStartOffset); @@ -1353,7 +1378,7 @@ bias = averageSize/2; else if (data.velocity < 0 && dist < -QML_FLICK_SNAPONETHRESHOLD && dist > -averageSize/2) bias = -averageSize/2; - if (isRightToLeft()) + if (isContentFlowReversed()) bias = -bias; tempPosition -= bias; } @@ -1373,15 +1398,15 @@ bool isInBounds = -position() > maxExtent && -position() <= minExtent; if (topItem && (isInBounds || strictHighlightRange)) { if (topItem->index == 0 && header && tempPosition+highlightRangeStart < header->position()+header->size()/2 && !strictHighlightRange) { - pos = isRightToLeft() ? - header->position() + highlightRangeStart - size() : header->position() - highlightRangeStart; + pos = isContentFlowReversed() ? - header->position() + highlightRangeStart - size() : header->position() - highlightRangeStart; } else { - if (isRightToLeft()) + if (isContentFlowReversed()) pos = qMax(qMin(-topItem->position() + highlightRangeStart - size(), -maxExtent), -minExtent); else pos = qMax(qMin(topItem->position() - highlightRangeStart, -maxExtent), -minExtent); } } else if (bottomItem && isInBounds) { - if (isRightToLeft()) + if (isContentFlowReversed()) pos = qMax(qMin(-bottomItem->position() + highlightRangeEnd - size(), -maxExtent), -minExtent); else pos = qMax(qMin(bottomItem->position() - highlightRangeEnd, -maxExtent), -minExtent); @@ -1408,7 +1433,7 @@ viewPos = pos + static_cast(currentItem)->itemSize() - highlightRangeEnd; if (viewPos > pos - highlightRangeStart) viewPos = pos - highlightRangeStart; - if (isRightToLeft()) + if (isContentFlowReversed()) viewPos = -viewPos-size(); timeline.reset(data.move); @@ -1441,7 +1466,7 @@ return; } qreal maxDistance = 0; - qreal dataValue = isRightToLeft() ? -data.move.value()+size() : data.move.value(); + qreal dataValue = isContentFlowReversed() ? -data.move.value()+size() : data.move.value(); // -ve velocity means list is moving up/left if (velocity > 0) { @@ -1450,7 +1475,7 @@ // if we've been dragged < averageSize/2 then bias towards the next item qreal dist = data.move.value() - (data.pressPos - data.dragStartOffset); qreal bias = dist < averageSize/2 ? averageSize/2 : 0; - if (isRightToLeft()) + if (isContentFlowReversed()) bias = -bias; data.flickTarget = -snapPosAt(-(dataValue - highlightRangeStart) - bias) + highlightRangeStart; maxDistance = qAbs(data.flickTarget - data.move.value()); @@ -1467,7 +1492,7 @@ // if we've been dragged < averageSize/2 then bias towards the next item qreal dist = data.move.value() - (data.pressPos - data.dragStartOffset); qreal bias = -dist < averageSize/2 ? averageSize/2 : 0; - if (isRightToLeft()) + if (isContentFlowReversed()) bias = -bias; data.flickTarget = -snapPosAt(-(dataValue - highlightRangeStart) + bias) + highlightRangeStart; maxDistance = qAbs(data.flickTarget - data.move.value()); @@ -1505,10 +1530,10 @@ dist = -dist; if ((maxDistance > 0.0 && v2 / (2.0f * maxDistance) < accel) || snapMode == QQuickListView::SnapOneItem) { if (snapMode != QQuickListView::SnapOneItem) { - qreal distTemp = isRightToLeft() ? -dist : dist; + qreal distTemp = isContentFlowReversed() ? -dist : dist; data.flickTarget = -snapPosAt(-(dataValue - highlightRangeStart) + distTemp) + highlightRangeStart; } - data.flickTarget = isRightToLeft() ? -data.flickTarget+size() : data.flickTarget; + data.flickTarget = isContentFlowReversed() ? -data.flickTarget+size() : data.flickTarget; if (overShoot) { if (data.flickTarget >= minExtent) { overshootDist = overShootDistance(vSize); @@ -1561,9 +1586,9 @@ // reevaluate the target boundary. qreal newtarget = data.flickTarget; if (snapMode != QQuickListView::NoSnap || highlightRange == QQuickListView::StrictlyEnforceRange) { - qreal tempFlickTarget = isRightToLeft() ? -data.flickTarget+size() : data.flickTarget; + qreal tempFlickTarget = isContentFlowReversed() ? -data.flickTarget+size() : data.flickTarget; newtarget = -snapPosAt(-(tempFlickTarget - highlightRangeStart)) + highlightRangeStart; - newtarget = isRightToLeft() ? -newtarget+size() : newtarget; + newtarget = isContentFlowReversed() ? -newtarget+size() : newtarget; } if (velocity < 0 && newtarget <= maxExtent) newtarget = maxExtent - overshootDist; @@ -1655,6 +1680,45 @@ to set \e {clip: true} in order to have the out of view items clipped nicely. + + \section1 ListView layouts + + The layout of the items in a ListView can be controlled by these properties: + + \list + \li \l orientation - controls whether items flow horizontally or vertically. + This value can be either Qt.Horizontal or Qt.Vertical. + \li \l layoutDirection - controls the horizontal layout direction for a + horizontally-oriented view: that is, whether items are laid out from the left side of + the view to the right, or vice-versa. This value can be either Qt.LeftToRight or Qt.RightToLeft. + \li \l verticalLayoutDirection - controls the vertical layout direction for a vertically-oriented + view: that is, whether items are laid out from the top of the view down towards the bottom of + the view, or vice-versa. This value can be either ListView.TopToBottom or ListView.BottomToTop. + \endlist + + By default, a ListView has a vertical orientation, and items are laid out from top to bottom. The + table below shows the different layouts that a ListView can have, depending on the values of + the properties listed above. + + \table + \header + \li {2, 1} + \bold ListViews with Qt.Vertical orientation + \row + \li Top to bottom + \image listview-layout-toptobottom.png + \li Bottom to top + \image listview-layout-bottomtotop.png + \header + \li {2, 1} + \bold ListViews with Qt.Horizontal orientation + \row + \li Left to right + \image listview-layout-lefttoright.png + \li Right to left + \image listview-layout-righttoleft.png + \endtable + \sa {QML Data Models}, GridView, {declarative/modelviews/listview}{ListView examples} */ QQuickListView::QQuickListView(QQuickItem *parent) @@ -1956,7 +2020,7 @@ /*! \qmlproperty enumeration QtQuick2::ListView::layoutDirection - This property holds the layout direction of the horizontal list. + This property holds the layout direction of a horizontally-oriented list. Possible values: @@ -1965,13 +2029,15 @@ \li Qt.RightToLeft - Items will be laid out from right to let. \endlist - \sa ListView::effectiveLayoutDirection + Setting this property has no effect if the \l orientation is Qt.Vertical. + + \sa ListView::effectiveLayoutDirection, ListView::verticalLayoutDirection */ /*! \qmlproperty enumeration QtQuick2::ListView::effectiveLayoutDirection - This property holds the effective layout direction of the horizontal list. + This property holds the effective layout direction of a horizontally-oriented list. When using the attached property \l {LayoutMirroring::enabled}{LayoutMirroring::enabled} for locale layouts, the visual layout direction of the horizontal list will be mirrored. However, the @@ -1980,6 +2046,24 @@ \sa ListView::layoutDirection, {LayoutMirroring}{LayoutMirroring} */ + +/*! + \qmlproperty enumeration QtQuick2::ListView::verticalLayoutDirection + This property holds the layout direction of a vertically-oriented list. + + Possible values: + + \list + \li ListView.TopToBottom (default) - Items are laid out from the top of the view down to the bottom of the view. + \li ListView.BottomToTop - Items are laid out from the bottom of the view up to the top of the view. + \endlist + + Setting this property has no effect if the \l orientation is Qt.Horizontal. + + \sa ListView::layoutDirection +*/ + + /*! \qmlproperty bool QtQuick2::ListView::keyNavigationWraps This property holds whether the list wraps key navigation. @@ -2550,14 +2634,19 @@ return; d->inViewportMoved = true; - if (yflick()) - d->bufferMode = d->vData.smoothVelocity < 0 ? QQuickListViewPrivate::BufferBefore : QQuickListViewPrivate::BufferAfter; - else if (d->isRightToLeft()) - d->bufferMode = d->hData.smoothVelocity < 0 ? QQuickListViewPrivate::BufferAfter : QQuickListViewPrivate::BufferBefore; - else - d->bufferMode = d->hData.smoothVelocity < 0 ? QQuickListViewPrivate::BufferBefore : QQuickListViewPrivate::BufferAfter; + if (yflick()) { + if (d->isBottomToTop()) + d->bufferMode = d->vData.smoothVelocity < 0 ? QQuickListViewPrivate::BufferAfter : QQuickListViewPrivate::BufferBefore; + else + d->bufferMode = d->vData.smoothVelocity < 0 ? QQuickListViewPrivate::BufferBefore : QQuickListViewPrivate::BufferAfter; + } else { + if (d->isRightToLeft()) + d->bufferMode = d->hData.smoothVelocity < 0 ? QQuickListViewPrivate::BufferAfter : QQuickListViewPrivate::BufferBefore; + else + d->bufferMode = d->hData.smoothVelocity < 0 ? QQuickListViewPrivate::BufferBefore : QQuickListViewPrivate::BufferAfter; + } - d->refill(); + d->refillOrLayout(); // Set visibility of items to eliminate cost of items outside the visible area. qreal from = d->isContentFlowReversed() ? -d->position()-d->size() : d->position(); @@ -2575,7 +2664,7 @@ if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange && d->highlight) { // reposition highlight qreal pos = d->highlight->position(); - qreal viewPos = d->isRightToLeft() ? -d->position()-d->size() : d->position(); + qreal viewPos = d->isContentFlowReversed() ? -d->position()-d->size() : d->position(); if (pos > viewPos + d->highlightRangeEnd - d->highlight->size()) pos = viewPos + d->highlightRangeEnd - d->highlight->size(); if (pos < viewPos + d->highlightRangeStart) @@ -2641,7 +2730,8 @@ if (d->model && d->model->count() && d->interactive) { if ((d->orient == QQuickListView::Horizontal && !d->isRightToLeft() && event->key() == Qt::Key_Left) || (d->orient == QQuickListView::Horizontal && d->isRightToLeft() && event->key() == Qt::Key_Right) - || (d->orient == QQuickListView::Vertical && event->key() == Qt::Key_Up)) { + || (d->orient == QQuickListView::Vertical && !d->isBottomToTop() && event->key() == Qt::Key_Up) + || (d->orient == QQuickListView::Vertical && d->isBottomToTop() && event->key() == Qt::Key_Down)) { if (currentIndex() > 0 || (d->wrap && !event->isAutoRepeat())) { decrementCurrentIndex(); event->accept(); @@ -2652,7 +2742,8 @@ } } else if ((d->orient == QQuickListView::Horizontal && !d->isRightToLeft() && event->key() == Qt::Key_Right) || (d->orient == QQuickListView::Horizontal && d->isRightToLeft() && event->key() == Qt::Key_Left) - || (d->orient == QQuickListView::Vertical && event->key() == Qt::Key_Down)) { + || (d->orient == QQuickListView::Vertical && !d->isBottomToTop() && event->key() == Qt::Key_Down) + || (d->orient == QQuickListView::Vertical && d->isBottomToTop() && event->key() == Qt::Key_Up)) { if (currentIndex() < d->model->count() - 1 || (d->wrap && !event->isAutoRepeat())) { incrementCurrentIndex(); event->accept(); @@ -2670,10 +2761,14 @@ void QQuickListView::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) { Q_D(QQuickListView); - if (d->isRightToLeft() && d->orient == QQuickListView::Horizontal) { + if (d->isRightToLeft()) { // maintain position relative to the right edge int dx = newGeometry.width() - oldGeometry.width(); setContentX(contentX() - dx); + } else if (d->isBottomToTop()) { + // maintain position relative to the bottom edge + int dy = newGeometry.height() - oldGeometry.height(); + setContentY(contentY() - dy); } QQuickItemView::geometryChanged(newGeometry, oldGeometry); } @@ -2740,7 +2835,7 @@ int modelIndex = change.index; int count = change.count; - qreal tempPos = isRightToLeft() ? -position()-size() : position(); + qreal tempPos = isContentFlowReversed() ? -position()-size() : position(); int index = visibleItems.count() ? mapFromModel(modelIndex) : 0; if (index < 0) { diff -Nru qt5-declarative-0.1~git20120402/src/quick/items/qquickloader.cpp qt5-declarative-0.1~git20120423/src/quick/items/qquickloader.cpp --- qt5-declarative-0.1~git20120402/src/quick/items/qquickloader.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/items/qquickloader.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -309,6 +309,13 @@ loadFromSourceComponent(); } } else { + // cancel any current incubation + if (d->incubator) { + d->incubator->clear(); + delete d->itemContext; + d->itemContext = 0; + } + if (d->item) { QQuickItemPrivate *p = QQuickItemPrivate::get(d->item); p->removeItemChangeListener(d, watchedChanges); @@ -642,7 +649,8 @@ emit q->sourceComponentChanged(); emit q->statusChanged(); emit q->progressChanged(); - emit q->loaded(); + if (status == QQmlIncubator::Ready) + emit q->loaded(); disposeInitialPropertyValues(); // cleanup } diff -Nru qt5-declarative-0.1~git20120402/src/quick/items/qquickmultipointtoucharea.cpp qt5-declarative-0.1~git20120423/src/quick/items/qquickmultipointtoucharea.cpp --- qt5-declarative-0.1~git20120402/src/quick/items/qquickmultipointtoucharea.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/items/qquickmultipointtoucharea.cpp 2012-04-23 11:44:59.000000000 +0000 @@ -236,7 +236,7 @@ \list \li setting \c touchPoints to provide touch point objects with properties that can be bound to - \li using the onTouchUpdated or onTouchPointsPressed, onTouchPointsUpdated and onTouchPointsReleased handlers + \li using the onTouchUpdated or onPressed, onUpdated and onReleased handlers \endlist While a MultiPointTouchArea \e can take exclusive ownership of certain touch points, it is also possible to have diff -Nru qt5-declarative-0.1~git20120402/src/quick/items/qquickpathview.cpp qt5-declarative-0.1~git20120423/src/quick/items/qquickpathview.cpp --- qt5-declarative-0.1~git20120402/src/quick/items/qquickpathview.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/items/qquickpathview.cpp 2012-04-23 11:44:59.000000000 +0000 @@ -58,13 +58,13 @@ // The number of samples to use in calculating the velocity of a flick #ifndef QML_FLICK_SAMPLEBUFFER -#define QML_FLICK_SAMPLEBUFFER 3 +#define QML_FLICK_SAMPLEBUFFER 1 #endif // The number of samples to discard when calculating the flick velocity. // Touch panels often produce inaccurate results as the finger is lifted. #ifndef QML_FLICK_DISCARDSAMPLES -#define QML_FLICK_DISCARDSAMPLES 1 +#define QML_FLICK_DISCARDSAMPLES 0 #endif // The default maximum velocity of a flick. @@ -114,8 +114,8 @@ } QQuickPathViewPrivate::QQuickPathViewPrivate() - : path(0), currentIndex(0), currentItemOffset(0.0), startPc(0), lastDist(0) - , lastElapsed(0), offset(0.0), offsetAdj(0.0), mappedRange(1.0) + : path(0), currentIndex(0), currentItemOffset(0.0), startPc(0) + , offset(0.0), offsetAdj(0.0), mappedRange(1.0) , stealMouse(false), ownModel(false), interactive(true), haveHighlightRange(true) , autoHighlight(true), highlightUp(false), layoutScheduled(false) , moving(false), flicking(false), requestedOnPath(false), inRequest(false) @@ -127,7 +127,7 @@ , highlightPosition(0) , highlightRangeStart(0), highlightRangeEnd(0) , highlightRangeMode(QQuickPathView::StrictlyEnforceRange) - , highlightMoveDuration(300), modelCount(0) + , highlightMoveDuration(300), modelCount(0), snapMode(QQuickPathView::NoSnap) { } @@ -139,7 +139,7 @@ q->setFlag(QQuickItem::ItemIsFocusScope); q->setFiltersChildMouseEvents(true); FAST_CONNECT(&tl, SIGNAL(updated()), q, SLOT(ticked())) - lastPosTime.invalidate(); + timer.invalidate(); FAST_CONNECT(&tl, SIGNAL(completed()), q, SLOT(movementEnding())) } @@ -266,7 +266,8 @@ if (model && index >= 0 && index < modelCount) { qreal start = 0.0; - if (haveHighlightRange && highlightRangeMode != QQuickPathView::NoHighlightRange) + if (haveHighlightRange && (highlightRangeMode != QQuickPathView::NoHighlightRange + || snapMode != QQuickPathView::NoSnap)) start = highlightRangeStart; qreal globalPos = index + offset; globalPos = qmlMod(globalPos, qreal(modelCount)) / modelCount; @@ -698,7 +699,7 @@ if (d->modelCount) { d->createCurrentItem(); if (d->haveHighlightRange && d->highlightRangeMode == QQuickPathView::StrictlyEnforceRange) - d->snapToCurrent(); + d->snapToIndex(d->currentIndex); d->currentItemOffset = d->positionOfIndex(d->currentIndex); d->updateHighlight(); } @@ -889,7 +890,7 @@ if (d->highlightRangeStart == start || start < 0 || start > 1.0) return; d->highlightRangeStart = start; - d->haveHighlightRange = d->highlightRangeMode != NoHighlightRange && d->highlightRangeStart <= d->highlightRangeEnd; + d->haveHighlightRange = d->highlightRangeStart <= d->highlightRangeEnd; refill(); emit preferredHighlightBeginChanged(); } @@ -906,7 +907,7 @@ if (d->highlightRangeEnd == end || end < 0 || end > 1.0) return; d->highlightRangeEnd = end; - d->haveHighlightRange = d->highlightRangeMode != NoHighlightRange && d->highlightRangeStart <= d->highlightRangeEnd; + d->haveHighlightRange = d->highlightRangeStart <= d->highlightRangeEnd; refill(); emit preferredHighlightEndChanged(); } @@ -923,10 +924,12 @@ if (d->highlightRangeMode == mode) return; d->highlightRangeMode = mode; - d->haveHighlightRange = d->highlightRangeMode != NoHighlightRange && d->highlightRangeStart <= d->highlightRangeEnd; + d->haveHighlightRange = d->highlightRangeStart <= d->highlightRangeEnd; if (d->haveHighlightRange) { d->regenerate(); - d->snapToCurrent(); + int index = d->highlightRangeMode != NoHighlightRange ? d->currentIndex : d->calcCurrentIndex(); + if (index >= 0) + d->snapToIndex(index); } emit highlightRangeModeChanged(); } @@ -1175,6 +1178,41 @@ emit pathItemCountChanged(); } +/*! + \qmlproperty enumeration QtQuick2::PathView::snapMode + + This property determines how the items will settle following a drag or flick. + The possible values are: + + \list + \li PathView.NoSnap (default) - the items stop anywhere along the path. + \li PathView.SnapToItem - the items settle with an item aligned with the \l preferredHighlightBegin. + \li PathView.SnapOneItem - the items settle no more than one item away from the item nearest + \l preferredHighlightBegin at the time the press is released. This mode is particularly + useful for moving one page at a time. + \endlist + + \c snapMode does not affect the \l currentIndex. To update the + \l currentIndex as the view is moved, set \l highlightRangeMode + to \c PathView.StrictlyEnforceRange (default for PathView). + + \sa highlightRangeMode +*/ +QQuickPathView::SnapMode QQuickPathView::snapMode() const +{ + Q_D(const QQuickPathView); + return d->snapMode; +} + +void QQuickPathView::setSnapMode(SnapMode mode) +{ + Q_D(QQuickPathView); + if (mode == d->snapMode) + return; + d->snapMode = mode; + emit snapModeChanged(); +} + QPointF QQuickPathViewPrivate::pointNear(const QPointF &point, qreal *nearPercent) const { qreal samples = qMin(path->path().length()/5, qreal(500.0)); @@ -1236,6 +1274,15 @@ return velocity; } +qint64 QQuickPathViewPrivate::computeCurrentTime(QInputEvent *event) +{ + if (0 != event->timestamp() && QQuickItemPrivate::consistentTime == -1) { + return event->timestamp(); + } + + return QQuickItemPrivate::elapsed(timer); +} + void QQuickPathView::mousePressEvent(QMouseEvent *event) { Q_D(QQuickPathView); @@ -1277,9 +1324,8 @@ else stealMouse = false; - lastElapsed = 0; - lastDist = 0; - QQuickItemPrivate::start(lastPosTime); + QQuickItemPrivate::start(timer); + lastPosTime = computeCurrentTime(event); tl.clear(); } @@ -1299,7 +1345,7 @@ void QQuickPathViewPrivate::handleMouseMoveEvent(QMouseEvent *event) { Q_Q(QQuickPathView); - if (!interactive || !lastPosTime.isValid() || !model || !modelCount) + if (!interactive || !timer.isValid() || !model || !modelCount) return; qreal newPc; @@ -1308,10 +1354,10 @@ QPointF delta = pathPoint - startPoint; if (qAbs(delta.x()) > qApp->styleHints()->startDragDistance() || qAbs(delta.y()) > qApp->styleHints()->startDragDistance()) { stealMouse = true; - startPc = newPc; } } + qint64 currentTimestamp = computeCurrentTime(event); if (stealMouse) { moveReason = QQuickPathViewPrivate::Mouse; qreal diff = (newPc - startPc)*modelCount*mappedRange; @@ -1323,10 +1369,9 @@ else if (diff < -modelCount/2) diff += modelCount; - lastElapsed = QQuickItemPrivate::restart(lastPosTime); - lastDist = diff; - startPc = newPc; - addVelocitySample(diff / (qreal(lastElapsed) / 1000.)); + qint64 elapsed = currentTimestamp - lastPosTime; + if (elapsed > 0) + addVelocitySample(diff / (qreal(elapsed) / 1000.)); } if (!moving) { moving = true; @@ -1334,6 +1379,8 @@ emit q->movementStarted(); } } + startPc = newPc; + lastPosTime = currentTimestamp; } void QQuickPathView::mouseReleaseEvent(QMouseEvent *event) @@ -1353,8 +1400,8 @@ Q_Q(QQuickPathView); stealMouse = false; q->setKeepMouseGrab(false); - if (!interactive || !lastPosTime.isValid() || !model || !modelCount) { - lastPosTime.invalidate(); + if (!interactive || !timer.isValid() || !model || !modelCount) { + timer.invalidate(); if (!tl.isActive()) q->movementEnding(); return; @@ -1364,7 +1411,7 @@ qreal count = modelCount*mappedRange; qreal pixelVelocity = (path->path().length()/count) * velocity; if (qAbs(pixelVelocity) > MinimumFlickVelocity) { - if (qAbs(pixelVelocity) > maximumFlickVelocity) { + if (qAbs(pixelVelocity) > maximumFlickVelocity || snapMode == QQuickPathView::SnapOneItem) { // limit velocity qreal maxVel = velocity < 0 ? -maximumFlickVelocity : maximumFlickVelocity; velocity = maxVel / (path->path().length()/count); @@ -1373,14 +1420,24 @@ qreal v2 = velocity*velocity; qreal accel = deceleration/10; qreal dist = 0; - if (haveHighlightRange && highlightRangeMode == QQuickPathView::StrictlyEnforceRange) { - // + 0.25 to encourage moving at least one item in the flick direction - dist = qMin(qreal(modelCount-1), qreal(v2 / (accel * 2.0) + 0.25)); - // round to nearest item. - if (velocity > 0.) - dist = qRound(dist + offset) - offset; - else - dist = qRound(dist - offset) + offset; + if (haveHighlightRange && (highlightRangeMode == QQuickPathView::StrictlyEnforceRange + || snapMode != QQuickPathView::NoSnap)) { + if (snapMode == QQuickPathView::SnapOneItem) { + // encourage snapping one item in direction of motion + if (velocity > 0.) + dist = qRound(0.5 + offset) - offset; + else + dist = qRound(0.5 - offset) + offset; + } else { + // + 0.25 to encourage moving at least one item in the flick direction + dist = qMin(qreal(modelCount-1), qreal(v2 / (accel * 2.0) + 0.25)); + + // round to nearest item. + if (velocity > 0.) + dist = qRound(dist + offset) - offset; + else + dist = qRound(dist - offset) + offset; + } // Calculate accel required to stop on item boundary if (dist <= 0.) { dist = 0.; @@ -1405,7 +1462,7 @@ fixOffset(); } - lastPosTime.invalidate(); + timer.invalidate(); if (!tl.isActive()) q->movementEnding(); } @@ -1441,8 +1498,8 @@ grabMouse(); return d->stealMouse; - } else if (d->lastPosTime.isValid()) { - d->lastPosTime.invalidate(); + } else if (d->timer.isValid()) { + d->timer.invalidate(); d->fixOffset(); } if (event->type() == QEvent::MouseButtonRelease) @@ -1476,7 +1533,7 @@ // fix our state d->stealMouse = false; setKeepMouseGrab(false); - d->lastPosTime.invalidate(); + d->timer.invalidate(); d->fixOffset(); if (!d->tl.isActive()) movementEnding(); @@ -1557,7 +1614,8 @@ if (d->items.count() < count) { int idx = qRound(d->modelCount - d->offset) % d->modelCount; qreal startPos = 0.0; - if (d->haveHighlightRange && d->highlightRangeMode != QQuickPathView::NoHighlightRange) + if (d->haveHighlightRange && (d->highlightRangeMode != QQuickPathView::NoHighlightRange + || d->snapMode != QQuickPathView::NoSnap)) startPos = d->highlightRangeStart; if (d->firstIndex >= 0) { startPos = d->positionOfIndex(d->firstIndex); @@ -1833,22 +1891,23 @@ { Q_Q(QQuickPathView); if (model && items.count()) { - if (haveHighlightRange && highlightRangeMode == QQuickPathView::StrictlyEnforceRange) { + if (haveHighlightRange && (highlightRangeMode == QQuickPathView::StrictlyEnforceRange + || snapMode != QQuickPathView::NoSnap)) { int curr = calcCurrentIndex(); - if (curr != currentIndex) + if (curr != currentIndex && highlightRangeMode == QQuickPathView::StrictlyEnforceRange) q->setCurrentIndex(curr); else - snapToCurrent(); + snapToIndex(curr); } } } -void QQuickPathViewPrivate::snapToCurrent() +void QQuickPathViewPrivate::snapToIndex(int index) { if (!model || modelCount <= 0) return; - qreal targetOffset = qmlMod(modelCount - currentIndex, modelCount); + qreal targetOffset = qmlMod(modelCount - index, modelCount); if (offset == targetOffset) return; diff -Nru qt5-declarative-0.1~git20120402/src/quick/items/qquickpathview_p.h qt5-declarative-0.1~git20120423/src/quick/items/qquickpathview_p.h --- qt5-declarative-0.1~git20120402/src/quick/items/qquickpathview_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/items/qquickpathview_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -83,8 +83,10 @@ Q_PROPERTY(int count READ count NOTIFY countChanged) Q_PROPERTY(QQmlComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged) Q_PROPERTY(int pathItemCount READ pathItemCount WRITE setPathItemCount NOTIFY pathItemCountChanged) + Q_PROPERTY(SnapMode snapMode READ snapMode WRITE setSnapMode NOTIFY snapModeChanged) Q_ENUMS(HighlightRangeMode) + Q_ENUMS(SnapMode) public: QQuickPathView(QQuickItem *parent=0); @@ -144,6 +146,10 @@ int pathItemCount() const; void setPathItemCount(int); + enum SnapMode { NoSnap, SnapToItem, SnapOneItem }; + SnapMode snapMode() const; + void setSnapMode(SnapMode mode); + static QQuickPathViewAttached *qmlAttachedProperties(QObject *); public Q_SLOTS: @@ -176,6 +182,7 @@ void movementEnded(); void flickStarted(); void flickEnded(); + void snapModeChanged(); protected: virtual void updatePolish(); diff -Nru qt5-declarative-0.1~git20120402/src/quick/items/qquickpathview_p_p.h qt5-declarative-0.1~git20120423/src/quick/items/qquickpathview_p_p.h --- qt5-declarative-0.1~git20120402/src/quick/items/qquickpathview_p_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/items/qquickpathview_p_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -122,10 +122,11 @@ void setAdjustedOffset(qreal offset); void regenerate(); void updateItem(QQuickItem *, qreal); - void snapToCurrent(); + void snapToIndex(int index); QPointF pointNear(const QPointF &point, qreal *nearPercent=0) const; void addVelocitySample(qreal v); qreal calcVelocity() const; + qint64 computeCurrentTime(QInputEvent *event); QQuickPath *path; int currentIndex; @@ -133,8 +134,6 @@ qreal currentItemOffset; qreal startPc; QPointF startPoint; - qreal lastDist; - int lastElapsed; qreal offset; qreal offsetAdj; qreal mappedRange; @@ -149,7 +148,8 @@ bool flicking : 1; bool requestedOnPath : 1; bool inRequest : 1; - QElapsedTimer lastPosTime; + QElapsedTimer timer; + qint64 lastPosTime; QPointF lastPos; qreal dragMargin; qreal deceleration; @@ -180,6 +180,7 @@ int highlightMoveDuration; int modelCount; QPODVector velocityBuffer; + QQuickPathView::SnapMode snapMode; }; QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/quick/items/qquickshadereffect.cpp qt5-declarative-0.1~git20120423/src/quick/items/qquickshadereffect.cpp --- qt5-declarative-0.1~git20120402/src/quick/items/qquickshadereffect.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/items/qquickshadereffect.cpp 2012-04-23 11:44:59.000000000 +0000 @@ -88,6 +88,446 @@ return qt_texcoord_attribute_name; } +namespace { + + enum VariableQualifier { + AttributeQualifier, + UniformQualifier + }; + + inline bool qt_isalpha(char c) + { + char ch = c | 0x20; + return (ch >= 'a' && ch <= 'z') || c == '_'; + } + + inline bool qt_isalnum(char c) + { + return qt_isalpha(c) || (c >= '0' && c <= '9'); + } + + inline bool qt_isspace(char c) + { + return c == ' ' || (c >= 0x09 && c <= 0x0d); + } + + // Returns -1 if not found, returns index to first character after the name if found. + int qt_search_for_variable(const char *s, int length, int index, VariableQualifier &decl, + int &typeIndex, int &typeLength, + int &nameIndex, int &nameLength) + { + enum Identifier { + QualifierIdentifier, // Base state + PrecisionIdentifier, + TypeIdentifier, + NameIdentifier + }; + Identifier expected = QualifierIdentifier; + bool compilerDirectiveExpected = index == 0; + + while (index < length) { + // Skip whitespace. + while (qt_isspace(s[index])) { + compilerDirectiveExpected |= s[index] == '\n'; + ++index; + } + + if (qt_isalpha(s[index])) { + // Read identifier. + int idIndex = index; + ++index; + while (qt_isalnum(s[index])) + ++index; + int idLength = index - idIndex; + + const int attrLen = sizeof("attribute") - 1; + const int uniLen = sizeof("uniform") - 1; + const int loLen = sizeof("lowp") - 1; + const int medLen = sizeof("mediump") - 1; + const int hiLen = sizeof("highp") - 1; + + switch (expected) { + case QualifierIdentifier: + if (idLength == attrLen && qstrncmp("attribute", s + idIndex, attrLen) == 0) { + decl = AttributeQualifier; + expected = PrecisionIdentifier; + } else if (idLength == uniLen && qstrncmp("uniform", s + idIndex, uniLen) == 0) { + decl = UniformQualifier; + expected = PrecisionIdentifier; + } + break; + case PrecisionIdentifier: + if ((idLength == loLen && qstrncmp("lowp", s + idIndex, loLen) == 0) + || (idLength == medLen && qstrncmp("mediump", s + idIndex, medLen) == 0) + || (idLength == hiLen && qstrncmp("highp", s + idIndex, hiLen) == 0)) + { + expected = TypeIdentifier; + break; + } + // Fall through. + case TypeIdentifier: + typeIndex = idIndex; + typeLength = idLength; + expected = NameIdentifier; + break; + case NameIdentifier: + nameIndex = idIndex; + nameLength = idLength; + return index; // Attribute or uniform declaration found. Return result. + default: + break; + } + } else if (s[index] == '#' && compilerDirectiveExpected) { + // Skip compiler directives. + ++index; + while (index < length && (s[index] != '\n' || s[index - 1] == '\\')) + ++index; + } else if (s[index] == '/' && s[index + 1] == '/') { + // Skip comments. + index += 2; + while (index < length && s[index] != '\n') + ++index; + } else if (s[index] == '/' && s[index + 1] == '*') { + // Skip comments. + index += 2; + while (index < length && (s[index] != '*' || s[index + 1] != '/')) + ++index; + if (index < length) + index += 2; // Skip star-slash. + } else { + expected = QualifierIdentifier; + ++index; + } + compilerDirectiveExpected = false; + } + return -1; + } +} + + + +QQuickShaderEffectCommon::~QQuickShaderEffectCommon() +{ + for (int shaderType = 0; shaderType < Key::ShaderTypeCount; ++shaderType) + qDeleteAll(signalMappers[shaderType]); +} + +void QQuickShaderEffectCommon::disconnectPropertySignals(QQuickItem *item, Key::ShaderType shaderType) +{ + for (int i = 0; i < uniformData[shaderType].size(); ++i) { + if (signalMappers[shaderType].at(i) == 0) + continue; + const UniformData &d = uniformData[shaderType].at(i); + QSignalMapper *mapper = signalMappers[shaderType].at(i); + QObject::disconnect(item, 0, mapper, SLOT(map())); + QObject::disconnect(mapper, SIGNAL(mapped(int)), item, SLOT(propertyChanged(int))); + if (d.specialType == UniformData::Sampler) { + QQuickItem *source = qobject_cast(qVariantValue(d.value)); + if (source) { + if (item->canvas()) + QQuickItemPrivate::get(source)->derefCanvas(); + QObject::disconnect(source, SIGNAL(destroyed(QObject*)), item, SLOT(sourceDestroyed(QObject*))); + } + } + } +} + +void QQuickShaderEffectCommon::connectPropertySignals(QQuickItem *item, Key::ShaderType shaderType) +{ + for (int i = 0; i < uniformData[shaderType].size(); ++i) { + if (signalMappers[shaderType].at(i) == 0) + continue; + const UniformData &d = uniformData[shaderType].at(i); + int pi = item->metaObject()->indexOfProperty(d.name.constData()); + if (pi >= 0) { + QMetaProperty mp = item->metaObject()->property(pi); + if (!mp.hasNotifySignal()) + qWarning("QQuickShaderEffect: property '%s' does not have notification method!", d.name.constData()); + QByteArray signalName("2"); + signalName.append(mp.notifySignal().signature()); + QSignalMapper *mapper = signalMappers[shaderType].at(i); + QObject::connect(item, signalName, mapper, SLOT(map())); + QObject::connect(mapper, SIGNAL(mapped(int)), item, SLOT(propertyChanged(int))); + } else { + // If the source is set via a dynamic property, like the layer is, then we need this + // check to disable the warning. + if (!item->property(d.name.constData()).isValid()) + qWarning("QQuickShaderEffect: '%s' does not have a matching property!", d.name.constData()); + } + + if (d.specialType == UniformData::Sampler) { + QQuickItem *source = qobject_cast(qVariantValue(d.value)); + if (source) { + if (item->canvas()) + QQuickItemPrivate::get(source)->refCanvas(item->canvas()); + QObject::connect(source, SIGNAL(destroyed(QObject*)), item, SLOT(sourceDestroyed(QObject*))); + } + } + } +} + +void QQuickShaderEffectCommon::updateParseLog(bool ignoreAttributes) +{ + parseLog.clear(); + if (!ignoreAttributes) { + if (!attributes.contains(qt_position_attribute_name)) { + parseLog += QLatin1String("Warning: Missing reference to \'"); + parseLog += QLatin1String(qt_position_attribute_name); + parseLog += QLatin1String("\'.\n"); + } + if (!attributes.contains(qt_texcoord_attribute_name)) { + parseLog += QLatin1String("Warning: Missing reference to \'"); + parseLog += QLatin1String(qt_texcoord_attribute_name); + parseLog += QLatin1String("\'.\n"); + } + } + bool respectsMatrix = false; + bool respectsOpacity = false; + for (int i = 0; i < uniformData[Key::VertexShader].size(); ++i) + respectsMatrix |= uniformData[Key::VertexShader].at(i).specialType == UniformData::Matrix; + for (int shaderType = 0; shaderType < Key::ShaderTypeCount; ++shaderType) { + for (int i = 0; i < uniformData[shaderType].size(); ++i) + respectsOpacity |= uniformData[shaderType].at(i).specialType == UniformData::Opacity; + } + if (!respectsMatrix) + parseLog += QLatin1String("Warning: Vertex shader is missing reference to \'qt_Matrix\'.\n"); + if (!respectsOpacity) + parseLog += QLatin1String("Warning: Shaders are missing reference to \'qt_Opacity\'.\n"); +} + +void QQuickShaderEffectCommon::lookThroughShaderCode(QQuickItem *item, Key::ShaderType shaderType, const QByteArray &code) +{ + int index = 0; + int typeIndex, typeLength, nameIndex, nameLength; + const char *s = code.constData(); + VariableQualifier decl; + while ((index = qt_search_for_variable(s, code.size(), index, decl, typeIndex, typeLength, + nameIndex, nameLength)) != -1) + { + if (decl == AttributeQualifier) { + if (shaderType == Key::VertexShader) + attributes.append(QByteArray(s + nameIndex, nameLength)); + } else { + Q_ASSERT(decl == UniformQualifier); + + const int sampLen = sizeof("sampler2D") - 1; + const int opLen = sizeof("qt_Opacity") - 1; + const int matLen = sizeof("qt_Matrix") - 1; + + UniformData d; + QSignalMapper *mapper = 0; + d.name = QByteArray(s + nameIndex, nameLength); + if (nameLength == opLen && qstrncmp("qt_Opacity", s + nameIndex, opLen) == 0) { + d.specialType = UniformData::Opacity; + } else if (nameLength == matLen && qstrncmp("qt_Matrix", s + nameIndex, matLen) == 0) { + d.specialType = UniformData::Matrix; + } else { + mapper = new QSignalMapper; + mapper->setMapping(item, uniformData[shaderType].size() | (shaderType << 16)); + d.value = item->property(d.name.constData()); + bool sampler = typeLength == sampLen && qstrncmp("sampler2D", s + typeIndex, sampLen) == 0; + d.specialType = sampler ? UniformData::Sampler : UniformData::None; + } + uniformData[shaderType].append(d); + signalMappers[shaderType].append(mapper); + } + } +} + +void QQuickShaderEffectCommon::updateShader(QQuickItem *item, Key::ShaderType shaderType) +{ + disconnectPropertySignals(item, shaderType); + qDeleteAll(signalMappers[shaderType]); + uniformData[shaderType].clear(); + signalMappers[shaderType].clear(); + if (shaderType == Key::VertexShader) + attributes.clear(); + + const QByteArray &code = source.sourceCode[shaderType]; + if (code.isEmpty()) { + // Optimize for default code. + if (shaderType == Key::VertexShader) { + attributes.append(QByteArray(qt_position_attribute_name)); + attributes.append(QByteArray(qt_texcoord_attribute_name)); + UniformData d; + d.name = "qt_Matrix"; + d.specialType = UniformData::Matrix; + uniformData[Key::VertexShader].append(d); + signalMappers[Key::VertexShader].append(0); + } else if (shaderType == Key::FragmentShader) { + UniformData d; + d.name = "qt_Opacity"; + d.specialType = UniformData::Opacity; + uniformData[Key::FragmentShader].append(d); + signalMappers[Key::FragmentShader].append(0); + QSignalMapper *mapper = new QSignalMapper; + mapper->setMapping(item, 1 | (Key::FragmentShader << 16)); + const char *sourceName = "source"; + d.name = sourceName; + d.value = item->property(sourceName); + d.specialType = UniformData::Sampler; + uniformData[Key::FragmentShader].append(d); + signalMappers[Key::FragmentShader].append(mapper); + } + } else { + lookThroughShaderCode(item, shaderType, code); + } + + connectPropertySignals(item, shaderType); +} + +void QQuickShaderEffectCommon::updateMaterial(QQuickShaderEffectNode *node, + QQuickShaderEffectMaterial *material, + bool updateUniforms, bool updateUniformValues, + bool updateTextureProviders) +{ + if (updateUniforms) { + for (int i = 0; i < material->textureProviders.size(); ++i) { + QSGTextureProvider *t = material->textureProviders.at(i).second; + if (t) { + QObject::disconnect(t, SIGNAL(textureChanged()), node, SLOT(markDirtyTexture())); + QObject::disconnect(t, SIGNAL(destroyed(QObject*)), node, SLOT(textureProviderDestroyed(QObject*))); + } + } + material->textureProviders.clear(); + + for (int shaderType = 0; shaderType < Key::ShaderTypeCount; ++shaderType) { + for (int i = 0; i < uniformData[shaderType].size(); ++i) { + const UniformData &d = uniformData[shaderType].at(i); + // First make room in the textureProviders array. Set to proper value further down. + if (d.specialType == UniformData::Sampler) + material->textureProviders.append(qMakePair(d.name, (QSGTextureProvider *)0)); + } + material->uniforms[shaderType] = uniformData[shaderType]; + } + updateUniformValues = false; + updateTextureProviders = true; + } + + if (updateUniformValues) { + for (int shaderType = 0; shaderType < Key::ShaderTypeCount; ++shaderType) { + Q_ASSERT(uniformData[shaderType].size() == material->uniforms[shaderType].size()); + for (int i = 0; i < uniformData[shaderType].size(); ++i) + material->uniforms[shaderType][i].value = uniformData[shaderType].at(i).value; + } + } + + if (updateTextureProviders) { + int index = 0; + for (int shaderType = 0; shaderType < Key::ShaderTypeCount; ++shaderType) { + for (int i = 0; i < uniformData[shaderType].size(); ++i) { + const UniformData &d = uniformData[shaderType].at(i); + if (d.specialType != UniformData::Sampler) + continue; + Q_ASSERT(material->textureProviders.at(index).first == d.name); + QSGTextureProvider *oldProvider = material->textureProviders.at(index).second; + QSGTextureProvider *newProvider = 0; + QQuickItem *source = qobject_cast(qVariantValue(d.value)); + if (source && source->isTextureProvider()) + newProvider = source->textureProvider(); + if (newProvider != oldProvider) { + if (oldProvider) { + QObject::disconnect(oldProvider, SIGNAL(textureChanged()), node, SLOT(markDirtyTexture())); + QObject::disconnect(oldProvider, SIGNAL(destroyed(QObject*)), node, SLOT(textureProviderDestroyed(QObject*))); + } + if (newProvider) { + Q_ASSERT_X(newProvider->thread() == QThread::currentThread(), + "QQuickShaderEffect::updatePaintNode", + "Texture provider must belong to the rendering thread"); + QObject::connect(newProvider, SIGNAL(textureChanged()), node, SLOT(markDirtyTexture())); + QObject::connect(newProvider, SIGNAL(destroyed(QObject*)), node, SLOT(textureProviderDestroyed(QObject*))); + } else { + const char *typeName = source ? source->metaObject()->className() : d.value.typeName(); + qWarning("ShaderEffect: Property '%s' is not assigned a valid texture provider (%s).", + d.name.constData(), typeName); + } + material->textureProviders[index].second = newProvider; + } + ++index; + } + } + Q_ASSERT(index == material->textureProviders.size()); + } +} + +void QQuickShaderEffectCommon::updateCanvas(QQuickCanvas *canvas) +{ + // See comment in QQuickShaderEffectCommon::propertyChanged(). + if (canvas) { + for (int shaderType = 0; shaderType < Key::ShaderTypeCount; ++shaderType) { + for (int i = 0; i < uniformData[shaderType].size(); ++i) { + const UniformData &d = uniformData[shaderType].at(i); + if (d.specialType == UniformData::Sampler) { + QQuickItem *source = qobject_cast(qVariantValue(d.value)); + if (source) + QQuickItemPrivate::get(source)->refCanvas(canvas); + } + } + } + } else { + for (int shaderType = 0; shaderType < Key::ShaderTypeCount; ++shaderType) { + for (int i = 0; i < uniformData[shaderType].size(); ++i) { + const UniformData &d = uniformData[shaderType].at(i); + if (d.specialType == UniformData::Sampler) { + QQuickItem *source = qobject_cast(qVariantValue(d.value)); + if (source) + QQuickItemPrivate::get(source)->derefCanvas(); + } + } + } + } +} + +void QQuickShaderEffectCommon::sourceDestroyed(QObject *object) +{ + for (int shaderType = 0; shaderType < Key::ShaderTypeCount; ++shaderType) { + for (int i = 0; i < uniformData[shaderType].size(); ++i) { + UniformData &d = uniformData[shaderType][i]; + if (d.specialType == UniformData::Sampler && qVariantCanConvert(d.value)) { + if (qVariantValue(d.value) == object) + d.value = QVariant(); + } + } + } +} + + +void QQuickShaderEffectCommon::propertyChanged(QQuickItem *item, int mappedId, + bool *textureProviderChanged) +{ + Key::ShaderType shaderType = Key::ShaderType(mappedId >> 16); + int index = mappedId & 0xffff; + UniformData &d = uniformData[shaderType][index]; + if (d.specialType == UniformData::Sampler) { + QQuickItem *source = qobject_cast(qVariantValue(d.value)); + if (source) { + if (item->canvas()) + QQuickItemPrivate::get(source)->derefCanvas(); + QObject::disconnect(source, SIGNAL(destroyed(QObject*)), item, SLOT(sourceDestroyed(QObject*))); + } + + d.value = item->property(d.name.constData()); + + source = qobject_cast(qVariantValue(d.value)); + if (source) { + // 'source' needs a canvas to get a scene graph node. It usually gets one through its + // parent, but if the source item is "inline" rather than a reference -- i.e. + // "property variant source: Image { }" instead of "property variant source: foo" -- it + // will not get a parent. In those cases, 'source' should get the canvas from 'item'. + if (item->canvas()) + QQuickItemPrivate::get(source)->refCanvas(item->canvas()); + QObject::connect(source, SIGNAL(destroyed(QObject*)), item, SLOT(sourceDestroyed(QObject*))); + } + if (textureProviderChanged) + *textureProviderChanged = true; + } else { + d.value = item->property(d.name.constData()); + if (textureProviderChanged) + *textureProviderChanged = false; + } +} + + /*! \qmlclass ShaderEffect QQuickShaderEffect \inqmlmodule QtQuick 2 @@ -187,18 +627,21 @@ , m_cullMode(NoCulling) , m_status(Uncompiled) , m_blending(true) - , m_dirtyData(true) - , m_programDirty(true) + , m_dirtyUniforms(true) + , m_dirtyUniformValues(true) + , m_dirtyTextureProviders(true) + , m_dirtyProgram(true) + , m_dirtyParseLog(true) , m_dirtyMesh(true) , m_dirtyGeometry(true) - , m_complete(false) { setFlag(QQuickItem::ItemHasContents); } QQuickShaderEffect::~QQuickShaderEffect() { - reset(); + for (int shaderType = 0; shaderType < Key::ShaderTypeCount; ++shaderType) + m_common.disconnectPropertySignals(this, Key::ShaderType(shaderType)); } /*! @@ -211,11 +654,16 @@ void QQuickShaderEffect::setFragmentShader(const QByteArray &code) { - if (m_source.fragmentCode.constData() == code.constData()) + if (m_common.source.sourceCode[Key::FragmentShader].constData() == code.constData()) return; - m_source.fragmentCode = code; + m_common.source.sourceCode[Key::FragmentShader] = code; + m_dirtyProgram = true; + m_dirtyParseLog = true; + + if (isComponentComplete()) + m_common.updateShader(this, Key::FragmentShader); + update(); - m_complete = false; if (m_status != Uncompiled) { m_status = Uncompiled; emit statusChanged(); @@ -234,11 +682,16 @@ void QQuickShaderEffect::setVertexShader(const QByteArray &code) { - if (m_source.vertexCode.constData() == code.constData()) + if (m_common.source.sourceCode[Key::VertexShader].constData() == code.constData()) return; - m_source.vertexCode = code; + m_common.source.sourceCode[Key::VertexShader] = code; + m_dirtyProgram = true; + m_dirtyParseLog = true; + + if (isComponentComplete()) + m_common.updateShader(this, Key::VertexShader); + update(); - m_complete = false; if (m_status != Uncompiled) { m_status = Uncompiled; emit statusChanged(); @@ -316,6 +769,7 @@ } m_dirtyMesh = true; + m_dirtyParseLog = true; update(); emit meshChanged(); } @@ -343,6 +797,34 @@ emit cullModeChanged(); } +QString QQuickShaderEffect::parseLog() +{ + if (m_dirtyParseLog) { + m_common.updateParseLog(m_mesh != 0); + m_dirtyParseLog = false; + } + return m_common.parseLog; +} + +bool QQuickShaderEffect::event(QEvent *event) +{ + if (event->type() == QEvent::DynamicPropertyChange) { + QDynamicPropertyChangeEvent *e = static_cast(event); + for (int shaderType = 0; shaderType < Key::ShaderTypeCount; ++shaderType) { + for (int i = 0; i < m_common.uniformData[shaderType].size(); ++i) { + if (m_common.uniformData[shaderType].at(i).name == e->propertyName()) { + bool textureProviderChanged; + m_common.propertyChanged(this, (shaderType << 16) | i, &textureProviderChanged); + m_dirtyTextureProviders |= textureProviderChanged; + m_dirtyUniformValues = true; + update(); + } + } + } + } + return QQuickItem::event(event); +} + /*! \qmlproperty enumeration QtQuick2::ShaderEffect::status @@ -371,19 +853,6 @@ \sa status */ -void QQuickShaderEffect::changeSource(int index) -{ - Q_ASSERT(index >= 0 && index < m_sources.size()); - QVariant v = property(m_sources.at(index).name.constData()); - setSource(v, index); -} - -void QQuickShaderEffect::updateData() -{ - m_dirtyData = true; - update(); -} - void QQuickShaderEffect::updateGeometry() { m_dirtyGeometry = true; @@ -392,7 +861,7 @@ void QQuickShaderEffect::updateLogAndStatus(const QString &log, int status) { - m_log = m_parseLog + log; + m_log = parseLog() + log; m_status = Status(status); emit logChanged(); emit statusChanged(); @@ -400,341 +869,17 @@ void QQuickShaderEffect::sourceDestroyed(QObject *object) { - for (int i = 0; i < m_sources.size(); ++i) { - SourceData &source = m_sources[i]; - if (object == source.sourceObject) - source.sourceObject = 0; - } -} - -void QQuickShaderEffect::setSource(const QVariant &var, int index) -{ - Q_ASSERT(index >= 0 && index < m_sources.size()); - - SourceData &source = m_sources[index]; - - if (source.sourceObject) { - if (canvas()) - QQuickItemPrivate::get(source.sourceObject)->derefCanvas(); - disconnect(source.sourceObject, SIGNAL(destroyed(QObject*)), this, SLOT(sourceDestroyed(QObject*))); - } - - source.sourceObject = 0; - if (var.isNull()) { - return; - } else if (!qVariantCanConvert(var)) { - qWarning("Could not assign source of type '%s' to property '%s'.", var.typeName(), source.name.constData()); - return; - } - - QObject *obj = qVariantValue(var); - if (!obj) - return; - QQuickItem *item = qobject_cast(obj); - if (!item || !item->isTextureProvider()) { - qWarning("ShaderEffect: source uniform [%s] is not assigned a valid texture provider: %s [%s]", - source.name.constData(), qPrintable(obj->objectName()), obj->metaObject()->className()); - return; - } - - source.sourceObject = item; - - if (item) { - // 'item' needs a canvas to get a scene graph node. It usually gets one through its - // parent, but if the source item is "inline" rather than a reference -- i.e. - // "property variant source: Image { }" instead of "property variant source: foo" -- it - // will not get a parent. In those cases, 'item' should get the canvas from 'this'. - if (canvas()) - QQuickItemPrivate::get(item)->refCanvas(canvas()); - connect(item, SIGNAL(destroyed(QObject*)), this, SLOT(sourceDestroyed(QObject*))); - } -} - -void QQuickShaderEffect::disconnectPropertySignals() -{ - disconnect(this, 0, this, SLOT(updateData())); - for (int i = 0; i < m_sources.size(); ++i) { - SourceData &source = m_sources[i]; - disconnect(this, 0, source.mapper, 0); - disconnect(source.mapper, 0, this, 0); - } + m_common.sourceDestroyed(object); } -void QQuickShaderEffect::connectPropertySignals() -{ - QSet::const_iterator it; - for (it = m_source.uniformNames.begin(); it != m_source.uniformNames.end(); ++it) { - int pi = metaObject()->indexOfProperty(it->constData()); - if (pi >= 0) { - QMetaProperty mp = metaObject()->property(pi); - if (!mp.hasNotifySignal()) - qWarning("QQuickShaderEffect: property '%s' does not have notification method!", it->constData()); - QByteArray signalName("2"); - signalName.append(mp.notifySignal().signature()); - connect(this, signalName, this, SLOT(updateData())); - } else { - // If the source is set via a dynamic property, like the layer is, then we need this check - // to disable the warning. - if (property(it->constData()).isValid()) - continue; - qWarning("QQuickShaderEffect: '%s' does not have a matching property!", it->constData()); - } - } - for (int i = 0; i < m_sources.size(); ++i) { - SourceData &source = m_sources[i]; - int pi = metaObject()->indexOfProperty(source.name.constData()); - if (pi >= 0) { - QMetaProperty mp = metaObject()->property(pi); - QByteArray signalName("2"); - signalName.append(mp.notifySignal().signature()); - connect(this, signalName, source.mapper, SLOT(map())); - source.mapper->setMapping(this, i); - connect(source.mapper, SIGNAL(mapped(int)), this, SLOT(changeSource(int))); - } else { - // If the source is set via a dynamic property, like the layer is, then we need this check - // to disable the warning. - if (property(source.name.constData()).isValid()) - continue; - qWarning("QQuickShaderEffect: '%s' does not have a matching source!", source.name.constData()); - } - } -} - - -void QQuickShaderEffect::ensureCompleted() -{ - if (!m_complete) { - reset(); - updateProperties(); - m_complete = true; - } -} - - -void QQuickShaderEffect::reset() -{ - disconnectPropertySignals(); - - m_source.attributeNames.clear(); - m_source.uniformNames.clear(); - m_source.respectsOpacity = false; - m_source.respectsMatrix = false; - m_source.className = metaObject()->className(); - - for (int i = 0; i < m_sources.size(); ++i) { - const SourceData &source = m_sources.at(i); - delete source.mapper; - if (source.sourceObject) { - if (canvas()) - QQuickItemPrivate::get(source.sourceObject)->derefCanvas(); - disconnect(source.sourceObject, SIGNAL(destroyed(QObject*)), this, SLOT(sourceDestroyed(QObject*))); - } - } - m_sources.clear(); - m_log.clear(); - m_parseLog.clear(); - m_programDirty = true; - m_dirtyMesh = true; -} - -void QQuickShaderEffect::updateProperties() -{ - if (m_source.vertexCode.isEmpty()) { - m_source.attributeNames.append(QByteArray(qt_position_attribute_name)); - m_source.attributeNames.append(QByteArray(qt_texcoord_attribute_name)); - m_source.respectsMatrix = true; - } else { - lookThroughShaderCode(m_source.vertexCode); - } - if (m_source.fragmentCode.isEmpty()) { - m_source.respectsOpacity = true; - QByteArray name("source"); - m_source.uniformNames.insert(name); - SourceData d; - d.mapper = new QSignalMapper; - d.name = name; - d.sourceObject = 0; - m_sources.append(d); - } else { - lookThroughShaderCode(m_source.fragmentCode); - } - - if (!m_mesh && !m_source.attributeNames.contains(qt_position_attribute_name)) { - m_parseLog += QLatin1String("Warning: Missing reference to \'"); - m_parseLog += QLatin1String(qt_position_attribute_name); - m_parseLog += QLatin1String("\'.\n"); - } - if (!m_mesh && !m_source.attributeNames.contains(qt_texcoord_attribute_name)) { - m_parseLog += QLatin1String("Warning: Missing reference to \'"); - m_parseLog += QLatin1String(qt_texcoord_attribute_name); - m_parseLog += QLatin1String("\'.\n"); - } - if (!m_source.respectsMatrix) { - m_parseLog += QLatin1String("Warning: Missing reference to \'qt_Matrix\'.\n"); - } - if (!m_source.respectsOpacity) { - m_parseLog += QLatin1String("Warning: Missing reference to \'qt_Opacity\'.\n"); - } - - for (int i = 0; i < m_sources.size(); ++i) { - QVariant v = property(m_sources.at(i).name); - setSource(v, i); - } - - connectPropertySignals(); -} - -namespace { - - enum VariableQualifier { - AttributeQualifier, - UniformQualifier - }; - - inline bool qt_isalpha(char c) - { - char ch = c | 0x20; - return (ch >= 'a' && ch <= 'z') || c == '_'; - } - - inline bool qt_isalnum(char c) - { - return qt_isalpha(c) || (c >= '0' && c <= '9'); - } - - inline bool qt_isspace(char c) - { - return c == ' ' || (c >= 0x09 && c <= 0x0d); - } - - // Returns -1 if not found, returns index to first character after the name if found. - int qt_search_for_variable(const char *s, int length, int index, VariableQualifier &decl, - int &typeIndex, int &typeLength, - int &nameIndex, int &nameLength) - { - enum Identifier { - QualifierIdentifier, // Base state - PrecisionIdentifier, - TypeIdentifier, - NameIdentifier - }; - Identifier expected = QualifierIdentifier; - bool compilerDirectiveExpected = index == 0; - - while (index < length) { - // Skip whitespace. - while (qt_isspace(s[index])) { - compilerDirectiveExpected |= s[index] == '\n'; - ++index; - } - - if (qt_isalpha(s[index])) { - // Read identifier. - int idIndex = index; - ++index; - while (qt_isalnum(s[index])) - ++index; - int idLength = index - idIndex; - - const int attrLen = sizeof("attribute") - 1; - const int uniLen = sizeof("uniform") - 1; - const int loLen = sizeof("lowp") - 1; - const int medLen = sizeof("mediump") - 1; - const int hiLen = sizeof("highp") - 1; - switch (expected) { - case QualifierIdentifier: - if (idLength == attrLen && qstrncmp("attribute", s + idIndex, attrLen) == 0) { - decl = AttributeQualifier; - expected = PrecisionIdentifier; - } else if (idLength == uniLen && qstrncmp("uniform", s + idIndex, uniLen) == 0) { - decl = UniformQualifier; - expected = PrecisionIdentifier; - } - break; - case PrecisionIdentifier: - if ((idLength == loLen && qstrncmp("lowp", s + idIndex, loLen) == 0) - || (idLength == medLen && qstrncmp("mediump", s + idIndex, medLen) == 0) - || (idLength == hiLen && qstrncmp("highp", s + idIndex, hiLen) == 0)) - { - expected = TypeIdentifier; - break; - } - // Fall through. - case TypeIdentifier: - typeIndex = idIndex; - typeLength = idLength; - expected = NameIdentifier; - break; - case NameIdentifier: - nameIndex = idIndex; - nameLength = idLength; - return index; // Attribute or uniform declaration found. Return result. - default: - break; - } - } else if (s[index] == '#' && compilerDirectiveExpected) { - // Skip compiler directives. - ++index; - while (index < length && (s[index] != '\n' || s[index - 1] == '\\')) - ++index; - } else if (s[index] == '/' && s[index + 1] == '/') { - // Skip comments. - index += 2; - while (index < length && s[index] != '\n') - ++index; - } else if (s[index] == '/' && s[index + 1] == '*') { - // Skip comments. - index += 2; - while (index < length && (s[index] != '*' || s[index + 1] != '/')) - ++index; - if (index < length) - index += 2; // Skip star-slash. - } else { - expected = QualifierIdentifier; - ++index; - } - compilerDirectiveExpected = false; - } - return -1; - } -} - -void QQuickShaderEffect::lookThroughShaderCode(const QByteArray &code) +void QQuickShaderEffect::propertyChanged(int mappedId) { - int index = 0; - int typeIndex, typeLength, nameIndex, nameLength; - const char *s = code.constData(); - VariableQualifier decl; - while ((index = qt_search_for_variable(s, code.size(), index, decl, typeIndex, typeLength, - nameIndex, nameLength)) != -1) - { - if (decl == AttributeQualifier) { - m_source.attributeNames.append(QByteArray(s + nameIndex, nameLength)); - } else { - Q_ASSERT(decl == UniformQualifier); - - const int matLen = sizeof("qt_Matrix") - 1; - const int opLen = sizeof("qt_Opacity") - 1; - const int sampLen = sizeof("sampler2D") - 1; - - if (nameLength == matLen && qstrncmp("qt_Matrix", s + nameIndex, matLen) == 0) { - m_source.respectsMatrix = true; - } else if (nameLength == opLen && qstrncmp("qt_Opacity", s + nameIndex, opLen) == 0) { - m_source.respectsOpacity = true; - } else { - QByteArray name(s + nameIndex, nameLength); - m_source.uniformNames.insert(name); - if (typeLength == sampLen && qstrncmp("sampler2D", s + typeIndex, sampLen) == 0) { - SourceData d; - d.mapper = new QSignalMapper; - d.name = name; - d.sourceObject = 0; - m_sources.append(d); - } - } - } - } + bool textureProviderChanged; + m_common.propertyChanged(this, mappedId, &textureProviderChanged); + m_dirtyTextureProviders |= textureProviderChanged; + m_dirtyUniformValues = true; + update(); } void QQuickShaderEffect::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) @@ -747,10 +892,8 @@ { QQuickShaderEffectNode *node = static_cast(oldNode); - ensureCompleted(); - // In the case of a bad vertex shader, don't try to create a node... - if (m_source.attributeNames.isEmpty()) { + if (m_common.attributes.isEmpty()) { if (node) delete node; return 0; @@ -758,14 +901,14 @@ if (!node) { node = new QQuickShaderEffectNode; - m_programDirty = true; - m_dirtyData = true; + node->setMaterial(new QQuickShaderEffectMaterial(node)); + node->setFlag(QSGNode::OwnsMaterial, true); + m_dirtyProgram = true; + m_dirtyUniforms = true; m_dirtyGeometry = true; connect(node, SIGNAL(logAndStatusChanged(QString,int)), this, SLOT(updateLogAndStatus(QString,int))); } - QQuickShaderEffectMaterial *material = node->shaderMaterial(); - if (m_dirtyMesh) { node->setGeometry(0); m_dirtyMesh = false; @@ -778,11 +921,11 @@ QRectF rect(0, 0, width(), height()); QQuickShaderEffectMesh *mesh = m_mesh ? m_mesh : &m_defaultMesh; - geometry = mesh->updateGeometry(geometry, m_source.attributeNames, rect); + geometry = mesh->updateGeometry(geometry, m_common.attributes, rect); if (!geometry) { QString log = mesh->log(); if (!log.isNull()) { - m_log = m_parseLog; + m_log = parseLog(); m_log += QLatin1String("*** Mesh ***\n"); m_log += log; m_status = Error; @@ -799,18 +942,7 @@ m_dirtyGeometry = false; } - if (m_programDirty) { - QQuickShaderEffectProgram s = m_source; - if (s.fragmentCode.isEmpty()) - s.fragmentCode = qt_default_fragment_code; - if (s.vertexCode.isEmpty()) - s.vertexCode = qt_default_vertex_code; - s.className = metaObject()->className(); - - material->setProgramSource(s); - node->markDirty(QSGNode::DirtyMaterial); - m_programDirty = false; - } + QQuickShaderEffectMaterial *material = static_cast(node->material()); // Update blending if (bool(material->flags() & QSGMaterial::Blending) != m_blending) { @@ -818,66 +950,48 @@ node->markDirty(QSGNode::DirtyMaterial); } - if (int(material->cullMode()) != int(m_cullMode)) { - material->setCullMode(QQuickShaderEffectMaterial::CullMode(m_cullMode)); + if (int(material->cullMode) != int(m_cullMode)) { + material->cullMode = QQuickShaderEffectMaterial::CullMode(m_cullMode); node->markDirty(QSGNode::DirtyMaterial); } - if (m_dirtyData) { - QVector > values; - QVector > textures; - const QVector > &oldTextures = material->textureProviders(); - - for (QSet::const_iterator it = m_source.uniformNames.begin(); - it != m_source.uniformNames.end(); ++it) { - values.append(qMakePair(*it, property(*it))); - } - for (int i = 0; i < oldTextures.size(); ++i) { - QSGTextureProvider *t = oldTextures.at(i).second; - if (t) { - disconnect(t, SIGNAL(textureChanged()), node, SLOT(markDirtyTexture())); - disconnect(t, SIGNAL(destroyed(QObject*)), node, SLOT(textureProviderDestroyed(QObject*))); - } - } - for (int i = 0; i < m_sources.size(); ++i) { - const SourceData &source = m_sources.at(i); - QSGTextureProvider *t = source.sourceObject ? source.sourceObject->textureProvider() : 0; - textures.append(qMakePair(source.name, t)); - if (t) { - Q_ASSERT_X(t->thread() == QThread::currentThread(), - "QQuickShaderEffect::updatePaintNode", - "Texture provider must belong to the rendering thread"); - connect(t, SIGNAL(textureChanged()), node, SLOT(markDirtyTexture())); - connect(t, SIGNAL(destroyed(QObject*)), node, SLOT(textureProviderDestroyed(QObject*))); - } - } - material->setUniforms(values); - material->setTextureProviders(textures); + if (m_dirtyProgram) { + Key s = m_common.source; + if (s.sourceCode[Key::FragmentShader].isEmpty()) + s.sourceCode[Key::FragmentShader] = qt_default_fragment_code; + if (s.sourceCode[Key::VertexShader].isEmpty()) + s.sourceCode[Key::VertexShader] = qt_default_vertex_code; + s.className = metaObject()->className(); + + material->setProgramSource(s); + material->attributes = m_common.attributes; node->markDirty(QSGNode::DirtyMaterial); - m_dirtyData = false; + m_dirtyProgram = false; + m_dirtyUniforms = true; + } + + if (m_dirtyUniforms || m_dirtyUniformValues || m_dirtyTextureProviders) { + m_common.updateMaterial(node, material, m_dirtyUniforms, m_dirtyUniformValues, + m_dirtyTextureProviders); + node->markDirty(QSGNode::DirtyMaterial); + m_dirtyUniforms = m_dirtyUniformValues = m_dirtyTextureProviders = false; } return node; } +void QQuickShaderEffect::componentComplete() +{ + m_common.updateShader(this, Key::VertexShader); + m_common.updateShader(this, Key::FragmentShader); + QQuickItem::componentComplete(); +} + void QQuickShaderEffect::itemChange(ItemChange change, const ItemChangeData &value) { - if (change == QQuickItem::ItemSceneChange) { - // See comment in QQuickShaderEffect::setSource(). - if (value.canvas) { - for (int i = 0; i < m_sources.size(); ++i) { - if (m_sources.at(i).sourceObject) - QQuickItemPrivate::get(m_sources.at(i).sourceObject)->refCanvas(value.canvas); - } - } else { - for (int i = 0; i < m_sources.size(); ++i) { - if (m_sources.at(i).sourceObject) - QQuickItemPrivate::get(m_sources.at(i).sourceObject)->derefCanvas(); - } - } - } + if (change == QQuickItem::ItemSceneChange) + m_common.updateCanvas(value.canvas); QQuickItem::itemChange(change, value); } - QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/quick/items/qquickshadereffectnode.cpp qt5-declarative-0.1~git20120423/src/quick/items/qquickshadereffectnode.cpp --- qt5-declarative-0.1~git20120402/src/quick/items/qquickshadereffectnode.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/items/qquickshadereffectnode.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -60,7 +60,6 @@ friend class QQuickShaderEffectNode; virtual void compile(); - virtual void initialize(); virtual const char *vertexShader() const; virtual const char *fragmentShader() const; @@ -70,17 +69,15 @@ QString m_log; bool m_compiled; - QVector m_uniformLocs; - int m_opacityLoc; - int m_matrixLoc; - uint m_textureIndicesSet; + QVector m_uniformLocs[QQuickShaderEffectMaterialKey::ShaderTypeCount]; + uint m_initialized : 1; }; QQuickCustomMaterialShader::QQuickCustomMaterialShader(const QQuickShaderEffectMaterialKey &key, const QVector &attributes) : m_key(key) , m_attributes(attributes) , m_compiled(false) - , m_textureIndicesSet(false) + , m_initialized(false) { for (int i = 0; i < attributes.count(); ++i) m_attributeNames.append(attributes.at(i).constData()); @@ -104,24 +101,25 @@ : QQuickShaderEffect::Error); } - if (!m_textureIndicesSet) { - for (int i = 0; i < material->m_textures.size(); ++i) - program()->setUniformValue(material->m_textures.at(i).first.constData(), i); - m_textureIndicesSet = true; - } - - if (m_uniformLocs.size() != material->m_uniformValues.size()) { - m_uniformLocs.reserve(material->m_uniformValues.size()); - for (int i = 0; i < material->m_uniformValues.size(); ++i) { - const QByteArray &name = material->m_uniformValues.at(i).first; - m_uniformLocs.append(program()->uniformLocation(name.constData())); + if (!m_initialized) { + for (int i = 0; i < material->textureProviders.size(); ++i) + program()->setUniformValue(material->textureProviders.at(i).first.constData(), i); + + for (int shaderType = 0; shaderType < QQuickShaderEffectMaterialKey::ShaderTypeCount; ++shaderType) { + Q_ASSERT(m_uniformLocs[shaderType].isEmpty()); + m_uniformLocs[shaderType].reserve(material->uniforms[shaderType].size()); + for (int i = 0; i < material->uniforms[shaderType].size(); ++i) { + const QByteArray &name = material->uniforms[shaderType].at(i).name; + m_uniformLocs[shaderType].append(program()->uniformLocation(name.constData())); + } } + m_initialized = true; } QOpenGLFunctions *functions = state.context()->functions(); - for (int i = material->m_textures.size() - 1; i >= 0; --i) { + for (int i = material->textureProviders.size() - 1; i >= 0; --i) { functions->glActiveTexture(GL_TEXTURE0 + i); - if (QSGTextureProvider *provider = material->m_textures.at(i).second) { + if (QSGTextureProvider *provider = material->textureProviders.at(i).second) { if (QSGTexture *texture = provider->texture()) { texture->bind(); continue; @@ -131,57 +129,67 @@ glBindTexture(GL_TEXTURE_2D, 0); } - if (material->m_source.respectsOpacity) - program()->setUniformValue(m_opacityLoc, state.opacity()); - - for (int i = 0; i < material->m_uniformValues.count(); ++i) { - const QVariant &v = material->m_uniformValues.at(i).second; - - switch (v.type()) { - case QMetaType::QColor: - program()->setUniformValue(m_uniformLocs.at(i), qt_premultiply_color(qvariant_cast(v))); - break; - case QMetaType::Float: - program()->setUniformValue(m_uniformLocs.at(i), qvariant_cast(v)); - break; - case QMetaType::Double: - program()->setUniformValue(m_uniformLocs.at(i), (float) qvariant_cast(v)); - break; - case QMetaType::QTransform: - program()->setUniformValue(m_uniformLocs.at(i), qvariant_cast(v)); - break; - case QMetaType::Int: - program()->setUniformValue(m_uniformLocs.at(i), v.toInt()); - break; - case QMetaType::Bool: - program()->setUniformValue(m_uniformLocs.at(i), GLint(v.toBool())); - break; - case QMetaType::QSize: - case QMetaType::QSizeF: - program()->setUniformValue(m_uniformLocs.at(i), v.toSizeF()); - break; - case QMetaType::QPoint: - case QMetaType::QPointF: - program()->setUniformValue(m_uniformLocs.at(i), v.toPointF()); - break; - case QMetaType::QRect: - case QMetaType::QRectF: - { - QRectF r = v.toRectF(); - program()->setUniformValue(m_uniformLocs.at(i), r.x(), r.y(), r.width(), r.height()); + for (int shaderType = 0; shaderType < QQuickShaderEffectMaterialKey::ShaderTypeCount; ++shaderType) { + for (int i = 0; i < material->uniforms[shaderType].size(); ++i) { + const QQuickShaderEffectMaterial::UniformData &d = material->uniforms[shaderType].at(i); + int loc = m_uniformLocs[shaderType].at(i); + + if (d.specialType == QQuickShaderEffectMaterial::UniformData::Opacity) { + program()->setUniformValue(loc, state.opacity()); + } if (d.specialType == QQuickShaderEffectMaterial::UniformData::Matrix) { + if (state.isMatrixDirty()) + program()->setUniformValue(loc, state.combinedMatrix()); + } else { + switch (d.value.type()) { + case QMetaType::QColor: + program()->setUniformValue(loc, qt_premultiply_color(qvariant_cast(d.value))); + break; + case QMetaType::Float: + program()->setUniformValue(loc, qvariant_cast(d.value)); + break; + case QMetaType::Double: + program()->setUniformValue(loc, (float) qvariant_cast(d.value)); + break; + case QMetaType::QTransform: + program()->setUniformValue(loc, qvariant_cast(d.value)); + break; + case QMetaType::Int: + program()->setUniformValue(loc, d.value.toInt()); + break; + case QMetaType::Bool: + program()->setUniformValue(loc, GLint(d.value.toBool())); + break; + case QMetaType::QSize: + case QMetaType::QSizeF: + program()->setUniformValue(loc, d.value.toSizeF()); + break; + case QMetaType::QPoint: + case QMetaType::QPointF: + program()->setUniformValue(loc, d.value.toPointF()); + break; + case QMetaType::QRect: + case QMetaType::QRectF: + { + QRectF r = d.value.toRectF(); + program()->setUniformValue(loc, r.x(), r.y(), r.width(), r.height()); + } + break; + case QMetaType::QVector3D: + program()->setUniformValue(loc, qvariant_cast(d.value)); + break; + case QMetaType::QVector4D: + program()->setUniformValue(loc, qvariant_cast(d.value)); + break; + default: + break; + } } - break; - case QMetaType::QVector3D: - program()->setUniformValue(m_uniformLocs.at(i), qvariant_cast(v)); - break; - default: - break; } } const QQuickShaderEffectMaterial *oldMaterial = static_cast(oldEffect); - if (oldEffect == 0 || material->cullMode() != oldMaterial->cullMode()) { - switch (material->cullMode()) { + if (oldEffect == 0 || material->cullMode != oldMaterial->cullMode) { + switch (material->cullMode) { case QQuickShaderEffectMaterial::FrontFaceCulling: glEnable(GL_CULL_FACE); glCullFace(GL_FRONT); @@ -195,9 +203,6 @@ break; } } - - if ((state.isMatrixDirty()) && material->m_source.respectsMatrix) - program()->setUniformValue(m_matrixLoc, state.combinedMatrix()); } char const *const *QQuickCustomMaterialShader::attributeNames() const @@ -277,38 +282,42 @@ } } -void QQuickCustomMaterialShader::initialize() -{ - m_opacityLoc = program()->uniformLocation("qt_Opacity"); - m_matrixLoc = program()->uniformLocation("qt_Matrix"); -} - const char *QQuickCustomMaterialShader::vertexShader() const { - return m_key.vertexCode.constData(); + return m_key.sourceCode[QQuickShaderEffectMaterialKey::VertexShader].constData(); } const char *QQuickCustomMaterialShader::fragmentShader() const { - return m_key.fragmentCode.constData(); + return m_key.sourceCode[QQuickShaderEffectMaterialKey::FragmentShader].constData(); } bool QQuickShaderEffectMaterialKey::operator == (const QQuickShaderEffectMaterialKey &other) const { - return vertexCode == other.vertexCode && fragmentCode == other.fragmentCode && className == other.className; + if (className != other.className) + return false; + for (int shaderType = 0; shaderType < ShaderTypeCount; ++shaderType) { + if (sourceCode[shaderType] != other.sourceCode[shaderType]) + return false; + } + return true; } uint qHash(const QQuickShaderEffectMaterialKey &key) { - return qHash(qMakePair(qMakePair(key.vertexCode, key.fragmentCode), key.className)); + uint hash = qHash((void *)key.className); + typedef QQuickShaderEffectMaterialKey Key; + for (int shaderType = 0; shaderType < Key::ShaderTypeCount; ++shaderType) + hash = hash * 31337 + qHash(key.sourceCode[shaderType]); + return hash; } QHash > QQuickShaderEffectMaterial::materialMap; QQuickShaderEffectMaterial::QQuickShaderEffectMaterial(QQuickShaderEffectNode *node) - : m_cullMode(NoCulling) + : cullMode(NoCulling) , m_node(node) , m_emittedLogChanged(false) { @@ -322,7 +331,7 @@ QSGMaterialShader *QQuickShaderEffectMaterial::createShader() const { - return new QQuickCustomMaterialShader(m_source, m_source.attributeNames); + return new QQuickCustomMaterialShader(m_source, attributes); } int QQuickShaderEffectMaterial::compare(const QSGMaterial *other) const @@ -330,17 +339,7 @@ return this - static_cast(other); } -void QQuickShaderEffectMaterial::setCullMode(QQuickShaderEffectMaterial::CullMode face) -{ - m_cullMode = face; -} - -QQuickShaderEffectMaterial::CullMode QQuickShaderEffectMaterial::cullMode() const -{ - return m_cullMode; -} - -void QQuickShaderEffectMaterial::setProgramSource(const QQuickShaderEffectProgram &source) +void QQuickShaderEffectMaterial::setProgramSource(const QQuickShaderEffectMaterialKey &source) { m_source = source; m_emittedLogChanged = false; @@ -351,25 +350,10 @@ } } -void QQuickShaderEffectMaterial::setUniforms(const QVector > &uniformValues) -{ - m_uniformValues = uniformValues; -} - -void QQuickShaderEffectMaterial::setTextureProviders(const QVector > &textures) -{ - m_textures = textures; -} - -const QVector > &QQuickShaderEffectMaterial::textureProviders() const -{ - return m_textures; -} - void QQuickShaderEffectMaterial::updateTextures() const { - for (int i = 0; i < m_textures.size(); ++i) { - if (QSGTextureProvider *provider = m_textures.at(i).second) { + for (int i = 0; i < textureProviders.size(); ++i) { + if (QSGTextureProvider *provider = textureProviders.at(i).second) { if (QSGDynamicTexture *texture = qobject_cast(provider->texture())) texture->updateTexture(); } @@ -378,18 +362,16 @@ void QQuickShaderEffectMaterial::invalidateTextureProvider(QSGTextureProvider *provider) { - for (int i = 0; i < m_textures.size(); ++i) { - if (provider == m_textures.at(i).second) - m_textures[i].second = 0; + for (int i = 0; i < textureProviders.size(); ++i) { + if (provider == textureProviders.at(i).second) + textureProviders[i].second = 0; } } QQuickShaderEffectNode::QQuickShaderEffectNode() - : m_material(this) { QSGNode::setFlag(UsePreprocess, true); - setMaterial(&m_material); #ifdef QML_RUNTIME_TESTING description = QLatin1String("shadereffect"); @@ -407,7 +389,8 @@ void QQuickShaderEffectNode::textureProviderDestroyed(QObject *object) { - m_material.invalidateTextureProvider(static_cast(object)); + Q_ASSERT(material()); + static_cast(material())->invalidateTextureProvider(static_cast(object)); } void QQuickShaderEffectNode::preprocess() diff -Nru qt5-declarative-0.1~git20120402/src/quick/items/qquickshadereffectnode_p.h qt5-declarative-0.1~git20120423/src/quick/items/qquickshadereffectnode_p.h --- qt5-declarative-0.1~git20120402/src/quick/items/qquickshadereffectnode_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/items/qquickshadereffectnode_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -46,6 +46,7 @@ #include #include #include +#include #include #include @@ -55,8 +56,14 @@ QT_BEGIN_NAMESPACE struct QQuickShaderEffectMaterialKey { - QByteArray vertexCode; - QByteArray fragmentCode; + enum ShaderType + { + VertexShader, + FragmentShader, + ShaderTypeCount + }; + + QByteArray sourceCode[ShaderTypeCount]; const char *className; bool operator == (const QQuickShaderEffectMaterialKey &other) const; @@ -64,24 +71,21 @@ uint qHash(const QQuickShaderEffectMaterialKey &key); -// TODO: Implement support for multisampling. -struct QQuickShaderEffectProgram : public QQuickShaderEffectMaterialKey -{ - QQuickShaderEffectProgram() : respectsOpacity(false), respectsMatrix(false) {} - - QVector attributeNames; - QSet uniformNames; - - uint respectsOpacity : 1; - uint respectsMatrix : 1; -}; - class QQuickCustomMaterialShader; class QQuickShaderEffectNode; -class QQuickShaderEffectMaterial : public QSGMaterial +class Q_QUICK_PRIVATE_EXPORT QQuickShaderEffectMaterial : public QSGMaterial { public: + struct UniformData + { + enum SpecialType { None, Sampler, Opacity, Matrix }; + + QByteArray name; + QVariant value; + SpecialType specialType; + }; + enum CullMode { NoCulling, @@ -94,13 +98,12 @@ virtual QSGMaterialShader *createShader() const; virtual int compare(const QSGMaterial *other) const; - void setCullMode(CullMode face); - CullMode cullMode() const; + QVector attributes; + QVector uniforms[QQuickShaderEffectMaterialKey::ShaderTypeCount]; + QVector > textureProviders; + CullMode cullMode; - void setProgramSource(const QQuickShaderEffectProgram &); - void setUniforms(const QVector > &uniformValues); - void setTextureProviders(const QVector > &textures); - const QVector > &textureProviders() const; + void setProgramSource(const QQuickShaderEffectMaterialKey &source); void updateTextures() const; void invalidateTextureProvider(QSGTextureProvider *provider); @@ -114,11 +117,8 @@ // one. To guarantee that the type pointer is unique, the type object must live as long as // there are any CustomMaterialShaders of that type. QSharedPointer m_type; + QQuickShaderEffectMaterialKey m_source; - QQuickShaderEffectProgram m_source; - QVector > m_uniformValues; - QVector > m_textures; - CullMode m_cullMode; QQuickShaderEffectNode *m_node; bool m_emittedLogChanged; @@ -128,7 +128,7 @@ class QSGShaderEffectMesh; -class QQuickShaderEffectNode : public QObject, public QSGGeometryNode +class Q_QUICK_PRIVATE_EXPORT QQuickShaderEffectNode : public QObject, public QSGGeometryNode { Q_OBJECT public: @@ -137,17 +137,12 @@ virtual void preprocess(); - QQuickShaderEffectMaterial *shaderMaterial() { return &m_material; } - Q_SIGNALS: void logAndStatusChanged(const QString &, int status); private Q_SLOTS: void markDirtyTexture(); void textureProviderDestroyed(QObject *object); - -private: - QQuickShaderEffectMaterial m_material; }; QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/quick/items/qquickshadereffect_p.h qt5-declarative-0.1~git20120423/src/quick/items/qquickshadereffect_p.h --- qt5-declarative-0.1~git20120402/src/quick/items/qquickshadereffect_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/items/qquickshadereffect_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -45,6 +45,7 @@ #include #include +#include #include #include #include "qquickshadereffectmesh_p.h" @@ -62,7 +63,35 @@ class QSignalMapper; class QQuickCustomMaterialShader; -class Q_AUTOTEST_EXPORT QQuickShaderEffect : public QQuickItem +// Common class for QQuickShaderEffect and QQuickCustomParticle. +struct Q_QUICK_PRIVATE_EXPORT QQuickShaderEffectCommon +{ + typedef QQuickShaderEffectMaterialKey Key; + typedef QQuickShaderEffectMaterial::UniformData UniformData; + + ~QQuickShaderEffectCommon(); + void disconnectPropertySignals(QQuickItem *item, Key::ShaderType shaderType); + void connectPropertySignals(QQuickItem *item, Key::ShaderType shaderType); + void updateParseLog(bool ignoreAttributes); + void lookThroughShaderCode(QQuickItem *item, Key::ShaderType shaderType, const QByteArray &code); + void updateShader(QQuickItem *item, Key::ShaderType shaderType); + void updateMaterial(QQuickShaderEffectNode *node, QQuickShaderEffectMaterial *material, + bool updateUniforms, bool updateUniformValues, bool updateTextureProviders); + void updateCanvas(QQuickCanvas *canvas); + + // Called by slots in QQuickShaderEffect: + void sourceDestroyed(QObject *object); + void propertyChanged(QQuickItem *item, int mappedId, bool *textureProviderChanged); + + Key source; + QVector attributes; + QVector uniformData[Key::ShaderTypeCount]; + QVector signalMappers[Key::ShaderTypeCount]; + QString parseLog; +}; + + +class Q_QUICK_EXPORT QQuickShaderEffect : public QQuickItem { Q_OBJECT Q_PROPERTY(QByteArray fragmentShader READ fragmentShader WRITE setFragmentShader NOTIFY fragmentShaderChanged) @@ -93,10 +122,10 @@ QQuickShaderEffect(QQuickItem *parent = 0); ~QQuickShaderEffect(); - QByteArray fragmentShader() const { return m_source.fragmentCode; } + QByteArray fragmentShader() const { return m_common.source.sourceCode[Key::FragmentShader]; } void setFragmentShader(const QByteArray &code); - QByteArray vertexShader() const { return m_source.vertexCode; } + QByteArray vertexShader() const { return m_common.source.sourceCode[Key::VertexShader]; } void setVertexShader(const QByteArray &code); bool blending() const { return m_blending; } @@ -111,8 +140,9 @@ QString log() const { return m_log; } Status status() const { return m_status; } - void ensureCompleted(); - QString parseLog() { return m_parseLog; } + QString parseLog(); + + virtual bool event(QEvent *); Q_SIGNALS: void fragmentShaderChanged(); @@ -126,27 +156,22 @@ protected: virtual void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry); virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *); + virtual void componentComplete(); virtual void itemChange(ItemChange change, const ItemChangeData &value); private Q_SLOTS: - void changeSource(int index); - void updateData(); void updateGeometry(); void updateLogAndStatus(const QString &log, int status); void sourceDestroyed(QObject *object); + void propertyChanged(int mappedId); private: friend class QQuickCustomMaterialShader; friend class QQuickShaderEffectNode; - void setSource(const QVariant &var, int index); - void disconnectPropertySignals(); - void connectPropertySignals(); - void reset(); - void updateProperties(); - void lookThroughShaderCode(const QByteArray &code); + typedef QQuickShaderEffectMaterialKey Key; + typedef QQuickShaderEffectMaterial::UniformData UniformData; - QQuickShaderEffectProgram m_source; QSize m_meshResolution; QQuickShaderEffectMesh *m_mesh; QQuickGridMesh m_defaultMesh; @@ -154,23 +179,16 @@ QString m_log; Status m_status; - struct SourceData - { - QSignalMapper *mapper; - QQuickItem *sourceObject; - QByteArray name; - }; - QVector m_sources; - QString m_parseLog; + QQuickShaderEffectCommon m_common; uint m_blending : 1; - uint m_dirtyData : 1; - - uint m_programDirty : 1; + uint m_dirtyUniforms : 1; + uint m_dirtyUniformValues : 1; + uint m_dirtyTextureProviders : 1; + uint m_dirtyProgram : 1; + uint m_dirtyParseLog : 1; uint m_dirtyMesh : 1; uint m_dirtyGeometry : 1; - - uint m_complete : 1; }; QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/quick/items/qquickspriteengine.cpp qt5-declarative-0.1~git20120423/src/quick/items/qquickspriteengine.cpp --- qt5-declarative-0.1~git20120402/src/quick/items/qquickspriteengine.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/items/qquickspriteengine.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -621,7 +621,7 @@ m_advanceTime.start(); m_addAdvance = true; if (m_stateUpdates.isEmpty()) - return -1; + return uint(-1); return m_stateUpdates.first().first; } diff -Nru qt5-declarative-0.1~git20120402/src/quick/items/qquickspriteengine_p.h qt5-declarative-0.1~git20120423/src/quick/items/qquickspriteengine_p.h --- qt5-declarative-0.1~git20120402/src/quick/items/qquickspriteengine_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/items/qquickspriteengine_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -50,14 +50,15 @@ #include #include #include -#include +#include +#include QT_BEGIN_HEADER QT_BEGIN_NAMESPACE class QQuickSprite; -class Q_AUTOTEST_EXPORT QQuickStochasticState : public QObject //Currently for internal use only - Sprite and ParticleGroup +class Q_QUICK_PRIVATE_EXPORT QQuickStochasticState : public QObject //Currently for internal use only - Sprite and ParticleGroup { Q_OBJECT Q_PROPERTY(int duration READ duration WRITE setDuration NOTIFY durationChanged) @@ -173,7 +174,7 @@ bool m_randomStart; }; -class Q_AUTOTEST_EXPORT QQuickStochasticEngine : public QObject +class Q_QUICK_PRIVATE_EXPORT QQuickStochasticEngine : public QObject { Q_OBJECT //TODO: Optimize single state case? @@ -252,7 +253,7 @@ bool m_addAdvance; }; -class QQuickSpriteEngine : public QQuickStochasticEngine +class Q_QUICK_PRIVATE_EXPORT QQuickSpriteEngine : public QQuickStochasticEngine { Q_OBJECT Q_PROPERTY(QQmlListProperty sprites READ sprites) diff -Nru qt5-declarative-0.1~git20120402/src/quick/items/qquicktextcontrol.cpp qt5-declarative-0.1~git20120423/src/quick/items/qquicktextcontrol.cpp --- qt5-declarative-0.1~git20120402/src/quick/items/qquicktextcontrol.cpp 2012-04-02 11:02:55.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/items/qquicktextcontrol.cpp 2012-04-23 11:44:59.000000000 +0000 @@ -44,8 +44,8 @@ #ifndef QT_NO_TEXTCONTROL +#include #include -#include #include #include #include @@ -59,8 +59,6 @@ #include "qtextlist.h" #include "qtextdocumentwriter.h" #include "private/qtextcursor_p.h" -#include "qpagedpaintdevice.h" -#include "private/qpagedpaintdevice_p.h" #include #include @@ -107,11 +105,12 @@ ignoreAutomaticScrollbarAdjustement(false), overwriteMode(false), acceptRichText(true), - hideCursor(false), + cursorVisible(false), hasFocus(false), isEnabled(true), hadSelectionOnMousePress(false), - wordSelectionEnabled(false) + wordSelectionEnabled(false), + hasImState(false) {} bool QQuickTextControlPrivate::cursorMoveKeyEvent(QKeyEvent *e) @@ -292,6 +291,8 @@ { Q_Q(QQuickTextControl); + cancelPreedit(); + // for use when called from setPlainText. we may want to re-use the currently // set char format then. const QTextCharFormat charFormatForInsertion = cursor.charFormat(); @@ -425,8 +426,11 @@ void QQuickTextControlPrivate::selectionChanged(bool forceEmitSelectionChanged /*=false*/) { Q_Q(QQuickTextControl); - if (forceEmitSelectionChanged) + if (forceEmitSelectionChanged) { + if (hasFocus) + qGuiApp->inputMethod()->update(Qt::ImCurrentSelection); emit q->selectionChanged(); + } bool current = cursor.hasSelection(); if (current == lastSelectionState) @@ -434,8 +438,11 @@ lastSelectionState = current; emit q->copyAvailable(current); - if (!forceEmitSelectionChanged) + if (!forceEmitSelectionChanged) { + if (hasFocus) + qGuiApp->inputMethod()->update(Qt::ImCurrentSelection); emit q->selectionChanged(); + } emit q->cursorRectangleChanged(); } @@ -1441,13 +1448,16 @@ QList overrides; const int oldPreeditCursor = preeditCursor; preeditCursor = e->preeditString().length(); - hideCursor = false; + hasImState = !e->preeditString().isEmpty(); + cursorVisible = true; for (int i = 0; i < e->attributes().size(); ++i) { const QInputMethodEvent::Attribute &a = e->attributes().at(i); if (a.type == QInputMethodEvent::Cursor) { + hasImState = true; preeditCursor = a.start; - hideCursor = !a.length; + cursorVisible = a.length != 0; } else if (a.type == QInputMethodEvent::TextFormat) { + hasImState = true; QTextCharFormat f = qvariant_cast(a.value).toCharFormat(); if (f.isValid()) { QTextLayout::FormatRange o; @@ -1514,6 +1524,37 @@ } } +bool QQuickTextControl::hasImState() const +{ + Q_D(const QQuickTextControl); + return d->hasImState; +} + +bool QQuickTextControl::cursorVisible() const +{ + Q_D(const QQuickTextControl); + return d->cursorVisible; +} + +void QQuickTextControl::setCursorVisible(bool visible) +{ + Q_D(QQuickTextControl); + d->cursorVisible = visible; + d->setBlinkingCursorEnabled(d->cursorVisible + && (d->interactionFlags & (Qt::TextEditable | Qt::TextSelectableByKeyboard))); +} + +QTextCursor QQuickTextControl::cursorForPosition(const QPointF &pos) const +{ + Q_D(const QQuickTextControl); + int cursorPos = hitTest(pos, Qt::FuzzyHit); + if (cursorPos == -1) + cursorPos = 0; + QTextCursor c(d->doc); + c.setPosition(cursorPos); + return c; +} + QRectF QQuickTextControl::cursorRect(const QTextCursor &cursor) const { Q_D(const QQuickTextControl); @@ -1727,21 +1768,31 @@ void QQuickTextControlPrivate::commitPreedit() { - if (!isPreediting()) + Q_Q(QQuickTextControl); + + if (!hasImState) return; qApp->inputMethod()->commit(); - if (!isPreediting()) + if (!hasImState) return; - cursor.beginEditBlock(); - preeditCursor = 0; - QTextBlock block = cursor.block(); - QTextLayout *layout = block.layout(); - layout->setPreeditArea(-1, QString()); - layout->clearAdditionalFormats(); - cursor.endEditBlock(); + QInputMethodEvent event; + QCoreApplication::sendEvent(q->parent(), &event); +} + +void QQuickTextControlPrivate::cancelPreedit() +{ + Q_Q(QQuickTextControl); + + if (!hasImState) + return; + + qApp->inputMethod()->reset(); + + QInputMethodEvent event; + QCoreApplication::sendEvent(q->parent(), &event); } void QQuickTextControl::setTextInteractionFlags(Qt::TextInteractionFlags flags) diff -Nru qt5-declarative-0.1~git20120402/src/quick/items/qquicktextcontrol_p.h qt5-declarative-0.1~git20120423/src/quick/items/qquicktextcontrol_p.h --- qt5-declarative-0.1~git20120402/src/quick/items/qquicktextcontrol_p.h 2012-04-02 11:02:55.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/items/qquicktextcontrol_p.h 2012-04-23 11:44:59.000000000 +0000 @@ -74,7 +74,6 @@ class QAbstractScrollArea; class QEvent; class QTimerEvent; -class QPagedPaintDevice; class Q_AUTOTEST_EXPORT QQuickTextControl : public QObject { @@ -98,6 +97,10 @@ QString toHtml() const; #endif + bool hasImState() const; + bool cursorVisible() const; + void setCursorVisible(bool visible); + QTextCursor cursorForPosition(const QPointF &pos) const; QRectF cursorRect(const QTextCursor &cursor) const; QRectF cursorRect() const; QRectF selectionRect(const QTextCursor &cursor) const; @@ -118,7 +121,6 @@ virtual int hitTest(const QPointF &point, Qt::HitTestAccuracy accuracy) const; virtual QRectF blockBoundingRect(const QTextBlock &block) const; - QAbstractTextDocumentLayout::PaintContext getPaintContext() const; public Q_SLOTS: void setPlainText(const QString &text); diff -Nru qt5-declarative-0.1~git20120402/src/quick/items/qquicktextcontrol_p_p.h qt5-declarative-0.1~git20120423/src/quick/items/qquicktextcontrol_p_p.h --- qt5-declarative-0.1~git20120402/src/quick/items/qquicktextcontrol_p_p.h 2012-04-02 11:02:55.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/items/qquicktextcontrol_p_p.h 2012-04-23 11:44:59.000000000 +0000 @@ -127,6 +127,7 @@ bool isPreediting() const; void commitPreedit(); + void cancelPreedit(); QPointF trippleClickPoint; QPointF mousePressPos; @@ -155,11 +156,12 @@ bool ignoreAutomaticScrollbarAdjustement : 1; bool overwriteMode : 1; bool acceptRichText : 1; - bool hideCursor : 1; // used to hide the cursor in the preedit area + bool cursorVisible : 1; // used to hide the cursor in the preedit area bool hasFocus : 1; bool isEnabled : 1; bool hadSelectionOnMousePress : 1; bool wordSelectionEnabled : 1; + bool hasImState : 1; void _q_copyLink(); void _q_updateBlock(const QTextBlock &); diff -Nru qt5-declarative-0.1~git20120402/src/quick/items/qquicktext.cpp qt5-declarative-0.1~git20120423/src/quick/items/qquicktext.cpp --- qt5-declarative-0.1~git20120402/src/quick/items/qquicktext.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/items/qquicktext.cpp 2012-04-23 11:44:59.000000000 +0000 @@ -382,6 +382,22 @@ } } +void QQuickTextPrivate::updateBaseline(qreal baseline, qreal dy) +{ + Q_Q(QQuickText); + + qreal yoff = 0; + + if (q->heightValid()) { + if (vAlign == QQuickText::AlignBottom) + yoff = dy; + else if (vAlign == QQuickText::AlignVCenter) + yoff = dy/2; + } + + q->setBaselineOffset(baseline + yoff); +} + void QQuickTextPrivate::updateSize() { Q_Q(QQuickText); @@ -398,9 +414,19 @@ return; } - QFontMetricsF fm(font); - if (text.isEmpty()) { - qreal fontHeight = fm.height(); + if (text.isEmpty() && !isLineLaidOutConnected() && fontSizeMode() == QQuickText::FixedSize) { + // How much more expensive is it to just do a full layout on an empty string here? + // There may be subtle differences in the height and baseline calculations between + // QTextLayout and QFontMetrics and the number of variables that can affect the size + // and position of a line is increasing. + QFontMetricsF fm(font); + qreal fontHeight = qCeil(fm.height()); // QScriptLine and therefore QTextLine rounds up + if (!richText) { // line height, so we will as well. + fontHeight = lineHeightMode() == QQuickText::FixedHeight + ? lineHeight() + : fontHeight * lineHeight(); + } + updateBaseline(fm.ascent(), q->height() - fontHeight); q->setImplicitSize(0, fontHeight); layedOutTextRect = QRectF(0, 0, 0, fontHeight); emit q->contentSizeChanged(); @@ -411,7 +437,6 @@ qreal naturalWidth = 0; - qreal dy = q->height(); QSizeF size(0, 0); QSizeF previousSize = layedOutTextRect.size(); #if defined(Q_OS_MAC) @@ -420,14 +445,15 @@ //setup instance of QTextLayout for all cases other than richtext if (!richText) { - QRectF textRect = setupTextLayout(&naturalWidth); + qreal baseline = 0; + QRectF textRect = setupTextLayout(&naturalWidth, &baseline); if (internalWidthUpdate) // probably the result of a binding loop, but by letting it return; // get this far we'll get a warning to that effect if it is. layedOutTextRect = textRect; size = textRect.size(); - dy -= size.height(); + updateBaseline(baseline, q->height() - size.height()); } else { singleline = false; // richtext can't elide or be optimized for single-line case ensureDoc(); @@ -458,20 +484,13 @@ extra->doc->setTextWidth(q->width()); else extra->doc->setTextWidth(extra->doc->idealWidth()); // ### Text does not align if width is not set (QTextDoc bug) - dy -= extra->doc->size().height(); QSizeF dsize = extra->doc->size(); layedOutTextRect = QRectF(QPointF(0,0), dsize); size = QSizeF(extra->doc->idealWidth(),dsize.height()); - } - qreal yoff = 0; - if (q->heightValid()) { - if (vAlign == QQuickText::AlignBottom) - yoff = dy; - else if (vAlign == QQuickText::AlignVCenter) - yoff = dy/2; + QFontMetricsF fm(font); + updateBaseline(fm.ascent(), q->height() - size.height()); } - q->setBaselineOffset(fm.ascent() + yoff); //### need to comfirm cost of always setting these for richText internalWidthUpdate = true; @@ -669,7 +688,7 @@ already absolutely positioned horizontally). */ -QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth) +QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth, qreal *const baseline) { Q_Q(QQuickText); layout.setCacheEnabled(true); @@ -712,9 +731,10 @@ internalWidthUpdate = wasInLayout; } - QFontMetrics fm(font); + QFontMetricsF fm(font); qreal height = (lineHeightMode() == QQuickText::FixedHeight) ? lineHeight() : fm.height() * lineHeight(); - return QRect(0, 0, 0, height); + *baseline = fm.ascent(); + return QRectF(0, 0, 0, height); } qreal lineWidth = q->widthValid() && q->width() > 0 ? q->width() : FLT_MAX; @@ -1024,6 +1044,12 @@ elideLayout = 0; } + QTextLine firstLine = visibleCount == 1 && elideLayout + ? elideLayout->lineAt(0) + : layout.lineAt(0); + Q_ASSERT(firstLine.isValid()); + *baseline = firstLine.y() + firstLine.ascent(); + if (!customLayout) br.setHeight(height); @@ -2359,9 +2385,6 @@ QQuickItem::componentComplete(); if (d->updateOnComponentComplete) d->updateLayout(); - - // Enable accessibility for text items. - d->setAccessibleFlagAndListener(); } diff -Nru qt5-declarative-0.1~git20120402/src/quick/items/qquicktextedit.cpp qt5-declarative-0.1~git20120423/src/quick/items/qquicktextedit.cpp --- qt5-declarative-0.1~git20120402/src/quick/items/qquicktextedit.cpp 2012-04-02 11:02:55.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/items/qquicktextedit.cpp 2012-04-23 11:44:59.000000000 +0000 @@ -871,10 +871,9 @@ if (d->cursorVisible == on) return; d->cursorVisible = on; - QFocusEvent focusEvent(on ? QEvent::FocusIn : QEvent::FocusOut); if (!on && !d->persistentSelection) d->control->setCursorIsFocusIndicator(true); - d->control->processEvent(&focusEvent, QPointF(0, -d->yoff)); + d->control->setCursorVisible(on); emit cursorVisibleChanged(d->cursorVisible); } @@ -1536,15 +1535,18 @@ Q_D(QQuickTextEdit); const bool wasComposing = isInputMethodComposing(); d->control->processEvent(event, QPointF(0, -d->yoff)); + setCursorVisible(d->control->cursorVisible()); if (wasComposing != isInputMethodComposing()) emit inputMethodComposingChanged(); } void QQuickTextEdit::itemChange(ItemChange change, const ItemChangeData &value) { + Q_D(QQuickTextEdit); if (change == ItemActiveFocusHasChanged) { setCursorVisible(value.boolValue); // ### refactor: focus handling && d->canvas && d->canvas->hasFocus()); - + QFocusEvent focusEvent(value.boolValue ? QEvent::FocusIn : QEvent::FocusOut); + d->control->processEvent(&focusEvent, QPointF(0, -d->yoff)); if (value.boolValue) { q_updateAlignment(); connect(qApp->inputMethod(), SIGNAL(inputDirectionChanged(Qt::LayoutDirection)), @@ -1729,9 +1731,7 @@ bool QQuickTextEdit::isInputMethodComposing() const { Q_D(const QQuickTextEdit); - if (QTextLayout *layout = d->control->textCursor().block().layout()) - return layout->preeditAreaText().length() > 0; - return false; + return d->control->hasImState(); } void QQuickTextEditPrivate::init() diff -Nru qt5-declarative-0.1~git20120402/src/quick/items/qquicktextinput.cpp qt5-declarative-0.1~git20120423/src/quick/items/qquicktextinput.cpp --- qt5-declarative-0.1~git20120402/src/quick/items/qquicktextinput.cpp 2012-04-02 11:02:55.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/items/qquicktextinput.cpp 2012-04-23 11:44:59.000000000 +0000 @@ -45,6 +45,7 @@ #include +#include #include #include #include @@ -124,8 +125,8 @@ Q_D(QQuickTextInput); if (s == text()) return; - if (d->composeMode()) - qApp->inputMethod()->reset(); + + d->cancelPreedit(); d->internalSetText(s, -1, false); } @@ -674,9 +675,7 @@ { Q_D(const QQuickTextInput); - int c = d->m_cursor; - if (d->m_preeditCursor != -1) - c += d->m_preeditCursor; + int c = d->m_cursor + d->m_preeditCursor; if (d->m_echoMode == NoEcho) c = 0; QTextLine l = d->m_textLayout.lineForTextPosition(c); @@ -1398,7 +1397,7 @@ void QQuickTextInput::inputMethodEvent(QInputMethodEvent *ev) { Q_D(QQuickTextInput); - const bool wasComposing = d->preeditAreaText().length() > 0; + const bool wasComposing = d->hasImState; if (d->m_readOnly) { ev->ignore(); } else { @@ -1407,7 +1406,7 @@ if (!ev->isAccepted()) QQuickImplicitSizeItem::inputMethodEvent(ev); - if (wasComposing != (d->m_textLayout.preeditAreaText().length() > 0)) + if (wasComposing != d->hasImState) emit inputMethodComposingChanged(); } @@ -2513,7 +2512,7 @@ bool QQuickTextInput::isInputMethodComposing() const { Q_D(const QQuickTextInput); - return d->preeditAreaText().length() > 0; + return d->hasImState; } void QQuickTextInputPrivate::init() @@ -2820,18 +2819,31 @@ */ void QQuickTextInputPrivate::commitPreedit() { - if (!composeMode()) + Q_Q(QQuickTextInput); + + if (!hasImState) return; qApp->inputMethod()->commit(); - if (!composeMode()) + if (!hasImState) + return; + + QInputMethodEvent ev; + QCoreApplication::sendEvent(q, &ev); +} + +void QQuickTextInputPrivate::cancelPreedit() +{ + Q_Q(QQuickTextInput); + + if (!hasImState) return; - m_preeditCursor = 0; - m_textLayout.setPreeditArea(-1, QString()); - m_textLayout.clearAdditionalFormats(); - updateLayout(); + qApp->inputMethod()->reset(); + + QInputMethodEvent ev; + QCoreApplication::sendEvent(q, &ev); } /*! @@ -3113,15 +3125,19 @@ m_textLayout.setPreeditArea(m_cursor, event->preeditString()); #endif //QT_NO_IM const int oldPreeditCursor = m_preeditCursor; + const bool oldCursorVisible = cursorVisible; m_preeditCursor = event->preeditString().length(); - m_hideCursor = false; + hasImState = !event->preeditString().isEmpty(); + cursorVisible = true; QList formats; for (int i = 0; i < event->attributes().size(); ++i) { const QInputMethodEvent::Attribute &a = event->attributes().at(i); if (a.type == QInputMethodEvent::Cursor) { + hasImState = true; m_preeditCursor = a.start; - m_hideCursor = !a.length; + cursorVisible = a.length != 0; } else if (a.type == QInputMethodEvent::TextFormat) { + hasImState = true; QTextCharFormat f = qvariant_cast(a.value).toCharFormat(); if (f.isValid()) { QTextLayout::FormatRange o; @@ -3144,6 +3160,9 @@ if (isGettingInput) finishChange(priorState); + if (cursorVisible != oldCursorVisible) + emit q->cursorVisibleChanged(cursorVisible); + if (selectionChange) { emit q->selectionChanged(); q->updateInputMethod(Qt::ImCursorRectangle | Qt::ImAnchorPosition diff -Nru qt5-declarative-0.1~git20120402/src/quick/items/qquicktextinput_p_p.h qt5-declarative-0.1~git20120423/src/quick/items/qquicktextinput_p_p.h --- qt5-declarative-0.1~git20120402/src/quick/items/qquicktextinput_p_p.h 2012-04-02 11:02:55.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/items/qquicktextinput_p_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -115,7 +115,7 @@ , selectPressed(false) , textLayoutDirty(true) , persistentSelection(false) - , m_hideCursor(false) + , hasImState(false) , m_separator(0) , m_readOnly(0) , m_textDirty(0) @@ -245,7 +245,7 @@ bool selectPressed:1; bool textLayoutDirty:1; bool persistentSelection:1; - bool m_hideCursor : 1; // used to hide the m_cursor inside preedit areas + bool hasImState : 1; bool m_separator : 1; bool m_readOnly : 1; bool m_textDirty : 1; @@ -319,6 +319,7 @@ #endif void commitPreedit(); + void cancelPreedit(); Qt::CursorMoveStyle cursorMoveStyle() const { return m_textLayout.cursorMoveStyle(); } void setCursorMoveStyle(Qt::CursorMoveStyle style) { m_textLayout.setCursorMoveStyle(style); } diff -Nru qt5-declarative-0.1~git20120402/src/quick/items/qquicktextnode.cpp qt5-declarative-0.1~git20120423/src/quick/items/qquicktextnode.cpp --- qt5-declarative-0.1~git20120402/src/quick/items/qquicktextnode.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/items/qquicktextnode.cpp 2012-04-23 11:44:59.000000000 +0000 @@ -254,9 +254,6 @@ decorations |= (backgroundColor.isValid() ? QQuickTextNode::Background : QQuickTextNode::NoDecoration); qreal ascent = glyphRun.rawFont().ascent(); - // ### QTBUG-22919 The bounding rect returned by QGlyphRun appears to start on the - // baseline, move it by the ascent so all bounding rects are at baseline - ascent. - searchRect.translate(0, -ascent); insert(binaryTree, BinaryTreeNode(glyphRun, selectionState, searchRect, decorations, textColor, backgroundColor, position, ascent)); } @@ -1219,12 +1216,6 @@ int textPos = block.position(); QTextBlock::iterator blockIterator = block.begin(); - if (blockIterator.atEnd() && preeditLength) { - engine.setPosition(blockPosition); - textPos = engine.addText(block, block.charFormat(), textColor, colorChanges, - textPos, textPos + preeditLength, - selectionStart, selectionEnd); - } while (!blockIterator.atEnd()) { QTextFragment fragment = blockIterator.fragment(); @@ -1275,6 +1266,19 @@ ++blockIterator; } + if (preeditLength >= 0 && textPos <= block.position() + preeditPosition) { + engine.setPosition(blockPosition); + textPos = block.position() + preeditPosition; + QTextLine line = block.layout()->lineForTextPosition(preeditPosition); + if (!engine.currentLine().isValid() + || line.lineNumber() != engine.currentLine().lineNumber()) { + engine.setCurrentLine(line); + } + textPos = engine.addText(block, block.charFormat(), textColor, colorChanges, + textPos, textPos + preeditLength, + selectionStart, selectionEnd); + } + engine.setCurrentLine(QTextLine()); // Reset current line because the text layout changed ++it; } diff -Nru qt5-declarative-0.1~git20120402/src/quick/items/qquicktext_p.h qt5-declarative-0.1~git20120423/src/quick/items/qquicktext_p.h --- qt5-declarative-0.1~git20120402/src/quick/items/qquicktext_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/items/qquicktext_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -245,7 +245,7 @@ }; class QTextLine; -class Q_AUTOTEST_EXPORT QQuickTextLine : public QObject +class Q_QUICK_EXPORT QQuickTextLine : public QObject { Q_OBJECT Q_PROPERTY(int number READ number) diff -Nru qt5-declarative-0.1~git20120402/src/quick/items/qquicktext_p_p.h qt5-declarative-0.1~git20120423/src/quick/items/qquicktext_p_p.h --- qt5-declarative-0.1~git20120402/src/quick/items/qquicktext_p_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/items/qquicktext_p_p.h 2012-04-23 11:44:59.000000000 +0000 @@ -75,6 +75,7 @@ ~QQuickTextPrivate(); void init(); + void updateBaseline(qreal baseline, qreal dy); void updateSize(); void updateLayout(); bool determineHorizontalAlignment(); @@ -163,7 +164,7 @@ void ensureDoc(); - QRectF setupTextLayout(qreal *const naturalWidth); + QRectF setupTextLayout(qreal *const naturalWidth, qreal * const baseline); void setupCustomLineGeometry(QTextLine &line, qreal &height, int lineOffset = 0); bool isLinkActivatedConnected(); QString anchorAt(const QPointF &pos); diff -Nru qt5-declarative-0.1~git20120402/src/quick/items/qquickwindowmanager.cpp qt5-declarative-0.1~git20120423/src/quick/items/qquickwindowmanager.cpp --- qt5-declarative-0.1~git20120402/src/quick/items/qquickwindowmanager.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/items/qquickwindowmanager.cpp 2012-04-23 11:44:59.000000000 +0000 @@ -404,7 +404,7 @@ CanvasData *data = new CanvasData; data->sizeWasChanged = false; data->windowSize = canvas->size(); - data->isVisible = canvas->visible(); + data->isVisible = canvas->isVisible(); m_rendered_windows[canvas] = data; isExternalUpdatePending = true; @@ -516,7 +516,7 @@ CanvasTracker &t = const_cast(m_tracked_windows.at(i)); QQuickCanvas *win = t.canvas; - Q_ASSERT(win->visible() || QQuickCanvasPrivate::get(win)->renderWithoutShowing || t.toBeRemoved); + Q_ASSERT(win->isVisible() || QQuickCanvasPrivate::get(win)->renderWithoutShowing || t.toBeRemoved); bool canvasVisible = win->width() > 0 && win->height() > 0; anyoneShowing |= (canvasVisible && !t.toBeRemoved); @@ -1121,7 +1121,7 @@ { lockInGui(); isExternalUpdatePending = true; - if (isRenderBlocked || isPostingSyncEvent) + if (isRenderBlocked) wake(); unlockInGui(); } @@ -1173,11 +1173,11 @@ CanvasData &data = const_cast(m_windows[canvas]); QQuickCanvas *masterCanvas = 0; - if (!canvas->visible()) { + if (!canvas->isVisible()) { // Find a "proper surface" to bind... for (QHash::const_iterator it = m_windows.constBegin(); it != m_windows.constEnd() && !masterCanvas; ++it) { - if (it.key()->visible()) + if (it.key()->isVisible()) masterCanvas = it.key(); } } else { @@ -1211,7 +1211,7 @@ data.grabOnly = false; } - if (alsoSwap && canvas->visible()) { + if (alsoSwap && canvas->isVisible()) { gl->swapBuffers(canvas); cd->fireFrameSwapped(); } diff -Nru qt5-declarative-0.1~git20120402/src/quick/items/qquickwindowmodule_p.h qt5-declarative-0.1~git20120423/src/quick/items/qquickwindowmodule_p.h --- qt5-declarative-0.1~git20120402/src/quick/items/qquickwindowmodule_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/items/qquickwindowmodule_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -42,14 +42,14 @@ #ifndef QQUICKWINDOWMODULE_H #define QQUICKWINDOWMODULE_H -#include +#include QT_BEGIN_HEADER QT_BEGIN_NAMESPACE -class QQuickWindowModule +class Q_QUICK_PRIVATE_EXPORT QQuickWindowModule { public: static void defineModule(); Binary files /tmp/39TcBOrOwX/qt5-declarative-0.1~git20120402/src/quick/particles/particleresources/noise.png and /tmp/4OL5ZoauBZ/qt5-declarative-0.1~git20120423/src/quick/particles/particleresources/noise.png differ diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/particles.pri qt5-declarative-0.1~git20120423/src/quick/particles/particles.pri --- qt5-declarative-0.1~git20120402/src/quick/particles/particles.pri 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/particles.pri 1970-01-01 00:00:00.000000000 +0000 @@ -1,69 +0,0 @@ -HEADERS += \ - $$PWD/qquickangledirection_p.h \ - $$PWD/qquickcustomparticle_p.h \ - $$PWD/qquickcustomaffector_p.h \ - $$PWD/qquickellipseextruder_p.h \ - $$PWD/qquicktrailemitter_p.h \ - $$PWD/qquickfriction_p.h \ - $$PWD/qquickgravity_p.h \ - $$PWD/qquickimageparticle_p.h \ - $$PWD/qquickitemparticle_p.h \ - $$PWD/qquickage_p.h \ - $$PWD/qquicklineextruder_p.h \ - $$PWD/qquickmaskextruder_p.h \ - $$PWD/qquickparticleaffector_p.h \ - $$PWD/qquickparticleemitter_p.h \ - $$PWD/qquickparticleextruder_p.h \ - $$PWD/qquickparticlepainter_p.h \ - $$PWD/qquickparticlesmodule_p.h \ - $$PWD/qquickparticlesystem_p.h \ - $$PWD/qquickpointattractor_p.h \ - $$PWD/qquickpointdirection_p.h \ - $$PWD/qquickspritegoal_p.h \ - $$PWD/qquickdirection_p.h \ - $$PWD/qquicktargetdirection_p.h \ - $$PWD/qquickturbulence_p.h \ - $$PWD/qquickwander_p.h \ - $$PWD/qquickcumulativedirection_p.h \ - $$PWD/qquickv8particledata_p.h \ - $$PWD/qquickrectangleextruder_p.h \ - $$PWD/qquickparticlegroup_p.h \ - $$PWD/qquickgroupgoal_p.h - -SOURCES += \ - $$PWD/qquickangledirection.cpp \ - $$PWD/qquickcustomparticle.cpp \ - $$PWD/qquickcustomaffector.cpp \ - $$PWD/qquickellipseextruder.cpp \ - $$PWD/qquicktrailemitter.cpp \ - $$PWD/qquickfriction.cpp \ - $$PWD/qquickgravity.cpp \ - $$PWD/qquickimageparticle.cpp \ - $$PWD/qquickitemparticle.cpp \ - $$PWD/qquickage.cpp \ - $$PWD/qquicklineextruder.cpp \ - $$PWD/qquickmaskextruder.cpp \ - $$PWD/qquickparticleaffector.cpp \ - $$PWD/qquickparticleemitter.cpp \ - $$PWD/qquickparticleextruder.cpp \ - $$PWD/qquickparticlepainter.cpp \ - $$PWD/qquickparticlesmodule.cpp \ - $$PWD/qquickparticlesystem.cpp \ - $$PWD/qquickpointattractor.cpp \ - $$PWD/qquickpointdirection.cpp \ - $$PWD/qquickspritegoal.cpp \ - $$PWD/qquickdirection.cpp \ - $$PWD/qquicktargetdirection.cpp \ - $$PWD/qquickturbulence.cpp \ - $$PWD/qquickwander.cpp \ - $$PWD/qquickcumulativedirection.cpp \ - $$PWD/qquickv8particledata.cpp \ - $$PWD/qquickrectangleextruder.cpp \ - $$PWD/qquickparticlegroup.cpp \ - $$PWD/qquickgroupgoal.cpp - -RESOURCES += \ - $$PWD/particles.qrc - - - diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/particles.qrc qt5-declarative-0.1~git20120423/src/quick/particles/particles.qrc --- qt5-declarative-0.1~git20120402/src/quick/particles/particles.qrc 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/particles.qrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,5 +0,0 @@ - - - particleresources/noise.png - - diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquickage.cpp qt5-declarative-0.1~git20120423/src/quick/particles/qquickage.cpp --- qt5-declarative-0.1~git20120402/src/quick/particles/qquickage.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquickage.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,112 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qquickage_p.h" -#include "qquickparticleemitter_p.h" -QT_BEGIN_NAMESPACE -/*! - \qmlclass Age QQuickAgeAffector - \inqmlmodule QtQuick.Particles 2 - \inherits Affector - \brief The Age affector allows you to prematurely age particles - - The Age affector allows you to alter where the particle is in its lifecycle. Common uses - are to expire particles prematurely, possibly giving them time to animate out. - - The Age affector only applies to particles which are still alive. -*/ -/*! - \qmlproperty int QtQuick.Particles2::Age::lifeLeft - - The amount of life to set the particle to have. Affected particles - will advance to a point in their life where they will have this many - milliseconds left to live. -*/ - -/*! - \qmlproperty bool QtQuick.Particles2::Age::advancePosition - - advancePosition determines whether position, veclocity and acceleration are included in - the simulated aging done by the affector. If advancePosition is false, - then the position, velocity and acceleration will remain the same and only - other attributes (such as opacity) will advance in the simulation to where - it would normally be for that point in the particle's life. With advancePosition set to - true the position, velocity and acceleration will also advance to where it would - normally be by that point in the particle's life, making it advance its position - on screen. - - Default value is true. -*/ - -QQuickAgeAffector::QQuickAgeAffector(QQuickItem *parent) : - QQuickParticleAffector(parent), m_lifeLeft(0), m_advancePosition(true) -{ -} - - -bool QQuickAgeAffector::affectParticle(QQuickParticleData *d, qreal dt) -{ - Q_UNUSED(dt); - if (d->stillAlive()){ - qreal curT = (qreal)m_system->timeInt/1000.0; - qreal ttl = (qreal)m_lifeLeft/1000.0; - if (!m_advancePosition && ttl > 0){ - qreal x = d->curX(); - qreal vx = d->curVX(); - qreal ax = d->curAX(); - qreal y = d->curY(); - qreal vy = d->curVY(); - qreal ay = d->curAY(); - d->t = curT - (d->lifeSpan - ttl); - d->setInstantaneousX(x); - d->setInstantaneousVX(vx); - d->setInstantaneousAX(ax); - d->setInstantaneousY(y); - d->setInstantaneousVY(vy); - d->setInstantaneousAY(ay); - } else { - d->t = curT - (d->lifeSpan - ttl); - } - return true; - } - return false; -} -QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquickage_p.h qt5-declarative-0.1~git20120423/src/quick/particles/qquickage_p.h --- qt5-declarative-0.1~git20120402/src/quick/particles/qquickage_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquickage_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,99 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef KILLAFFECTOR_H -#define KILLAFFECTOR_H -#include "qquickparticleaffector_p.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -class QQuickAgeAffector : public QQuickParticleAffector -{ - Q_OBJECT - Q_PROPERTY(int lifeLeft READ lifeLeft WRITE setLifeLeft NOTIFY lifeLeftChanged) - Q_PROPERTY(bool advancePosition READ advancePosition WRITE setAdvancePosition NOTIFY advancePositionChanged) - -public: - explicit QQuickAgeAffector(QQuickItem *parent = 0); - - int lifeLeft() const - { - return m_lifeLeft; - } - - bool advancePosition() const - { - return m_advancePosition; - } - -protected: - virtual bool affectParticle(QQuickParticleData *d, qreal dt); -signals: - void lifeLeftChanged(int arg); - void advancePositionChanged(bool arg); - -public slots: - void setLifeLeft(int arg) - { - if (m_lifeLeft != arg) { - m_lifeLeft = arg; - emit lifeLeftChanged(arg); - } - } - - void setAdvancePosition(bool arg) - { - if (m_advancePosition != arg) { - m_advancePosition = arg; - emit advancePositionChanged(arg); - } - } - -private: - int m_lifeLeft; - bool m_advancePosition; -}; - -QT_END_NAMESPACE -QT_END_HEADER -#endif // KILLAFFECTOR_H diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquickangledirection.cpp qt5-declarative-0.1~git20120423/src/quick/particles/qquickangledirection.cpp --- qt5-declarative-0.1~git20120402/src/quick/particles/qquickangledirection.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquickangledirection.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,120 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qquickangledirection_p.h" -#include -#include -#ifdef Q_OS_QNX -#include -#endif -QT_BEGIN_NAMESPACE -const qreal CONV = 0.017453292519943295; -/*! - \qmlclass AngleDirection QQuickAngleDirection - \inqmlmodule QtQuick.Particles 2 - \inherits Direction - \brief The AngleDirection element allows you to specify a direction that varies in angle - - The AngledDirection element allows both the specification of a direction by angle and magnitude, - as well as varying the parameters by angle or magnitude. -*/ -/*! - \qmlproperty real QtQuick.Particles2::AngleDirection::angle - This property specifies the base angle for the direction. - The angle of this direction will vary by no more than angleVariation - from this angle. - - Angle is specified by degrees clockwise from straight right. - - The default value is zero. -*/ -/*! - \qmlproperty real QtQuick.Particles2::AngleDirection::magnitude - This property specifies the base magnitude for the direction. - The magnitude of this direction will vary by no more than magnitudeVariation - from this magnitude. - - Magnitude is specified in units of pixels per second. - - The default value is zero. -*/ -/*! - \qmlproperty real QtQuick.Particles2::AngleDirection::angleVariation - This property specifies the maximum angle variation for the direction. - The angle of the direction will vary by up to angleVariation clockwise - and anticlockwise from the value specified in angle. - - Angle is specified by degrees clockwise from straight right. - - The default value is zero. -*/ -/*! - \qmlproperty real QtQuick.Particles2::AngleDirection::magnitudeVariation - This property specifies the base magnitude for the direction. - The magnitude of this direction will vary by no more than magnitudeVariation - from the base magnitude. - - Magnitude is specified in units of pixels per second. - - The default value is zero. -*/ -QQuickAngleDirection::QQuickAngleDirection(QObject *parent) : - QQuickDirection(parent) - , m_angle(0) - , m_magnitude(0) - , m_angleVariation(0) - , m_magnitudeVariation(0) -{ - -} - -const QPointF QQuickAngleDirection::sample(const QPointF &from) -{ - Q_UNUSED(from); - QPointF ret; - qreal theta = m_angle*CONV - m_angleVariation*CONV + rand()/float(RAND_MAX) * m_angleVariation*CONV * 2; - qreal mag = m_magnitude- m_magnitudeVariation + rand()/float(RAND_MAX) * m_magnitudeVariation * 2; - ret.setX(mag * cos(theta)); - ret.setY(mag * sin(theta)); - return ret; -} - -QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquickangledirection_p.h qt5-declarative-0.1~git20120423/src/quick/particles/qquickangledirection_p.h --- qt5-declarative-0.1~git20120402/src/quick/particles/qquickangledirection_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquickangledirection_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,131 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QQuickANGLEDDIRECTION_H -#define QQuickANGLEDDIRECTION_H -#include "qquickdirection_p.h" -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -class QQuickAngleDirection : public QQuickDirection -{ - Q_OBJECT - Q_PROPERTY(qreal angle READ angle WRITE setAngle NOTIFY angleChanged) - Q_PROPERTY(qreal magnitude READ magnitude WRITE setMagnitude NOTIFY magnitudeChanged) - Q_PROPERTY(qreal angleVariation READ angleVariation WRITE setAngleVariation NOTIFY angleVariationChanged) - Q_PROPERTY(qreal magnitudeVariation READ magnitudeVariation WRITE setMagnitudeVariation NOTIFY magnitudeVariationChanged) -public: - explicit QQuickAngleDirection(QObject *parent = 0); - const QPointF sample(const QPointF &from); - qreal angle() const - { - return m_angle; - } - - qreal magnitude() const - { - return m_magnitude; - } - - qreal angleVariation() const - { - return m_angleVariation; - } - - qreal magnitudeVariation() const - { - return m_magnitudeVariation; - } - -signals: - - void angleChanged(qreal arg); - - void magnitudeChanged(qreal arg); - - void angleVariationChanged(qreal arg); - - void magnitudeVariationChanged(qreal arg); - -public slots: -void setAngle(qreal arg) -{ - if (m_angle != arg) { - m_angle = arg; - emit angleChanged(arg); - } -} - -void setMagnitude(qreal arg) -{ - if (m_magnitude != arg) { - m_magnitude = arg; - emit magnitudeChanged(arg); - } -} - -void setAngleVariation(qreal arg) -{ - if (m_angleVariation != arg) { - m_angleVariation = arg; - emit angleVariationChanged(arg); - } -} - -void setMagnitudeVariation(qreal arg) -{ - if (m_magnitudeVariation != arg) { - m_magnitudeVariation = arg; - emit magnitudeVariationChanged(arg); - } -} - -private: -qreal m_angle; -qreal m_magnitude; -qreal m_angleVariation; -qreal m_magnitudeVariation; -}; - -QT_END_NAMESPACE -QT_END_HEADER -#endif // QQuickANGLEDDIRECTION_H diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquickcumulativedirection.cpp qt5-declarative-0.1~git20120423/src/quick/particles/qquickcumulativedirection.cpp --- qt5-declarative-0.1~git20120402/src/quick/particles/qquickcumulativedirection.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquickcumulativedirection.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,70 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qquickcumulativedirection_p.h" -QT_BEGIN_NAMESPACE - -/*! - \qmlclass CumulativeDirection QQuickCumulativeDirection - \inqmlmodule QtQuick.Particles 2 - \inherits Direction - \brief The CumulativeDirection element allows you to specify a direction made of other directions - - The CumulativeDirection element will act as a direction that sums the directions within it. -*/ -QQuickCumulativeDirection::QQuickCumulativeDirection(QObject *parent):QQuickDirection(parent) -{ -} - -QQmlListProperty QQuickCumulativeDirection::directions() -{ - return QQmlListProperty(this, m_directions);//TODO: Proper list property -} - -const QPointF QQuickCumulativeDirection::sample(const QPointF &from) -{ - QPointF ret; - foreach (QQuickDirection* dir, m_directions) - ret += dir->sample(from); - return ret; -} - -QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquickcumulativedirection_p.h qt5-declarative-0.1~git20120423/src/quick/particles/qquickcumulativedirection_p.h --- qt5-declarative-0.1~git20120402/src/quick/particles/qquickcumulativedirection_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquickcumulativedirection_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,67 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QQuickCUMULATIVEDIRECTION_P_H -#define QQuickCUMULATIVEDIRECTION_P_H -#include "qquickdirection_p.h" -#include -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -class QQuickCumulativeDirection : public QQuickDirection -{ - Q_OBJECT - Q_PROPERTY(QQmlListProperty directions READ directions) - Q_CLASSINFO("DefaultProperty", "directions") -public: - explicit QQuickCumulativeDirection(QObject *parent = 0); - QQmlListProperty directions(); - const QPointF sample(const QPointF &from); -private: - QList m_directions; -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QQuickCUMULATIVEDIRECTION_P_H diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquickcustomaffector.cpp qt5-declarative-0.1~git20120423/src/quick/particles/qquickcustomaffector.cpp --- qt5-declarative-0.1~git20120402/src/quick/particles/qquickcustomaffector.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquickcustomaffector.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,211 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qquickcustomaffector_p.h" -#include -#include -#include -#include -QT_BEGIN_NAMESPACE - -//TODO: Move docs (and inheritence) to real base when docs can propagate. Currently this pretends to be the base class! -/*! - \qmlsignal QtQuick.Particles2::Affector::affectParticles(Array particles, real dt) - - This handler is called when particles are selected to be affected. particles contains - an array of particle objects which can be directly manipulated. - - dt is the time since the last time it was affected. Use dt to normalize - trajectory manipulations to real time. - - Note that JS is slower to execute, so it is not recommended to use this in - high-volume particle systems. -*/ - -/*! - \qmlproperty StochasticDirection QtQuick.Particles2::Affector::position - - Affected particles will have their position set to this direction, - relative to the ParticleSystem. When interpreting directions as points, - imagine it as an arrow with the base at the 0,0 of the ParticleSystem and the - tip at where the specified position will be. -*/ - -/*! - \qmlproperty StochasticDirection QtQuick.Particles2::Affector::speed - - Affected particles will have their speed set to this direction. -*/ - - -/*! - \qmlproperty StochasticDirection QtQuick.Particles2::Affector::acceleration - - Affected particles will have their acceleration set to this direction. -*/ - - -/*! - \qmlproperty bool QtQuick.Particles2::Affector::relative - - Whether the affected particles have their existing position/speed/acceleration added - to the new one. - - Default is true. -*/ -QQuickCustomAffector::QQuickCustomAffector(QQuickItem *parent) : - QQuickParticleAffector(parent) - , m_position(&m_nullVector) - , m_speed(&m_nullVector) - , m_acceleration(&m_nullVector) - , m_relative(true) -{ -} - -bool QQuickCustomAffector::isAffectConnected() -{ - static int idx = QObjectPrivate::get(this)->signalIndex("affectParticles(QQmlV8Handle,qreal)"); - return QObjectPrivate::get(this)->isSignalConnected(idx); -} - -void QQuickCustomAffector::affectSystem(qreal dt) -{ - if (!isAffectConnected()) { - QQuickParticleAffector::affectSystem(dt); - return; - } - if (!m_enabled) - return; - updateOffsets(); - - QList toAffect; - foreach (QQuickParticleGroupData* gd, m_system->groupData) - if (activeGroup(m_system->groupData.key(gd))) - foreach (QQuickParticleData* d, gd->data) - if (shouldAffect(d)) - toAffect << d; - - if (toAffect.isEmpty()) - return; - - if (m_onceOff) - dt = 1.0; - - v8::HandleScope handle_scope; - v8::Context::Scope scope(QQmlEnginePrivate::getV8Engine(qmlEngine(this))->context()); - v8::Handle array = v8::Array::New(toAffect.size()); - for (int i=0; iSet(i, toAffect[i]->v8Value().toHandle()); - - if (dt >= simulationCutoff || dt <= simulationDelta) { - affectProperties(toAffect, dt); - emit affectParticles(QQmlV8Handle::fromHandle(array), dt); - } else { - int realTime = m_system->timeInt; - m_system->timeInt -= dt * 1000.0; - while (dt > simulationDelta) { - m_system->timeInt += simulationDelta * 1000.0; - dt -= simulationDelta; - affectProperties(toAffect, simulationDelta); - emit affectParticles(QQmlV8Handle::fromHandle(array), simulationDelta); - } - m_system->timeInt = realTime; - if (dt > 0.0) { - affectProperties(toAffect, dt); - emit affectParticles(QQmlV8Handle::fromHandle(array), dt); - } - } - - foreach (QQuickParticleData* d, toAffect) - if (d->update == 1.0) - postAffect(d); -} - -bool QQuickCustomAffector::affectParticle(QQuickParticleData *d, qreal dt) -{ - //This does the property based affecting, called by superclass if signal isn't hooked up. - bool changed = false; - QPointF curPos(d->curX(), d->curY()); - - if (m_acceleration != &m_nullVector){ - QPointF pos = m_acceleration->sample(curPos); - if (m_relative) { - pos *= dt; - pos += QPointF(d->curAX(), d->curAY()); - } - d->setInstantaneousAX(pos.x()); - d->setInstantaneousAY(pos.y()); - changed = true; - } - - if (m_speed != &m_nullVector){ - QPointF pos = m_speed->sample(curPos); - if (m_relative) { - pos *= dt; - pos += QPointF(d->curVX(), d->curVY()); - } - d->setInstantaneousVX(pos.x()); - d->setInstantaneousVY(pos.y()); - changed = true; - } - - if (m_position != &m_nullVector){ - QPointF pos = m_position->sample(curPos); - if (m_relative) { - pos *= dt; - pos += curPos; - } - d->setInstantaneousX(pos.x()); - d->setInstantaneousY(pos.y()); - changed = true; - } - - return changed; -} - -void QQuickCustomAffector::affectProperties(const QList particles, qreal dt) -{ - foreach (QQuickParticleData* d, particles) - if ( affectParticle(d, dt) ) - d->update = 1.0; -} - -QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquickcustomaffector_p.h qt5-declarative-0.1~git20120423/src/quick/particles/qquickcustomaffector_p.h --- qt5-declarative-0.1~git20120402/src/quick/particles/qquickcustomaffector_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquickcustomaffector_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,162 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef CUSTOMAFFECTOR_H -#define CUSTOMAFFECTOR_H - -#include -#include "qquickparticlesystem_p.h" -#include "qquickparticleextruder_p.h" -#include "qquickparticleaffector_p.h" -#include "qquickdirection_p.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -class QQuickCustomAffector : public QQuickParticleAffector -{ - Q_OBJECT - Q_PROPERTY(bool relative READ relative WRITE setRelative NOTIFY relativeChanged) - Q_PROPERTY(QQuickDirection *position READ position WRITE setPosition NOTIFY positionChanged RESET positionReset) - Q_PROPERTY(QQuickDirection *speed READ speed WRITE setSpeed NOTIFY speedChanged RESET speedReset) - Q_PROPERTY(QQuickDirection *acceleration READ acceleration WRITE setAcceleration NOTIFY accelerationChanged RESET accelerationReset) - -public: - explicit QQuickCustomAffector(QQuickItem *parent = 0); - virtual void affectSystem(qreal dt); - - QQuickDirection * position() const - { - return m_position; - } - - QQuickDirection * speed() const - { - return m_speed; - } - - QQuickDirection * acceleration() const - { - return m_acceleration; - } - - void positionReset() - { - m_position = &m_nullVector; - } - - void speedReset() - { - m_speed = &m_nullVector; - } - - void accelerationReset() - { - m_acceleration = &m_nullVector; - } - - bool relative() const - { - return m_relative; - } - - -signals: - void affectParticles(QQmlV8Handle particles, qreal dt); - - void positionChanged(QQuickDirection * arg); - - void speedChanged(QQuickDirection * arg); - - void accelerationChanged(QQuickDirection * arg); - - void relativeChanged(bool arg); - -public slots: - void setPosition(QQuickDirection * arg) - { - if (m_position != arg) { - m_position = arg; - emit positionChanged(arg); - } - } - - void setSpeed(QQuickDirection * arg) - { - if (m_speed != arg) { - m_speed = arg; - emit speedChanged(arg); - } - } - - void setAcceleration(QQuickDirection * arg) - { - if (m_acceleration != arg) { - m_acceleration = arg; - emit accelerationChanged(arg); - } - } - - void setRelative(bool arg) - { - if (m_relative != arg) { - m_relative = arg; - emit relativeChanged(arg); - } - } - -protected: - bool isAffectConnected(); - virtual bool affectParticle(QQuickParticleData *d, qreal dt); -private: - void affectProperties(const QList particles, qreal dt); - QQuickDirection * m_position; - QQuickDirection * m_speed; - QQuickDirection * m_acceleration; - - QQuickDirection m_nullVector; - bool m_relative; -}; - -QT_END_NAMESPACE -QT_END_HEADER -#endif // CUSTOMAFFECTOR_H diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquickcustomparticle.cpp qt5-declarative-0.1~git20120423/src/quick/particles/qquickcustomparticle.cpp --- qt5-declarative-0.1~git20120402/src/quick/particles/qquickcustomparticle.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquickcustomparticle.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,602 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qquickcustomparticle_p.h" -#include -#include - -QT_BEGIN_NAMESPACE - -//Includes comments because the code isn't self explanatory -static const char qt_particles_template_vertex_code[] = - "attribute highp vec2 qt_ParticlePos;\n" - "attribute highp vec2 qt_ParticleTex;\n" - "attribute highp vec4 qt_ParticleData; // x = time, y = lifeSpan, z = size, w = endSize\n" - "attribute highp vec4 qt_ParticleVec; // x,y = constant speed, z,w = acceleration\n" - "attribute highp float qt_ParticleR;\n" - "uniform highp mat4 qt_Matrix;\n" - "uniform highp float qt_Timestamp;\n" - "varying highp vec2 qt_TexCoord0;\n" - "void defaultMain() {\n" - " qt_TexCoord0 = qt_ParticleTex;\n" - " highp float size = qt_ParticleData.z;\n" - " highp float endSize = qt_ParticleData.w;\n" - " highp float t = (qt_Timestamp - qt_ParticleData.x) / qt_ParticleData.y;\n" - " highp float currentSize = mix(size, endSize, t * t);\n" - " if (t < 0. || t > 1.)\n" - " currentSize = 0.;\n" - " highp vec2 pos = qt_ParticlePos\n" - " - currentSize / 2. + currentSize * qt_ParticleTex // adjust size\n" - " + qt_ParticleVec.xy * t * qt_ParticleData.y // apply speed vector..\n" - " + 0.5 * qt_ParticleVec.zw * pow(t * qt_ParticleData.y, 2.);\n" - " gl_Position = qt_Matrix * vec4(pos.x, pos.y, 0, 1);\n" - "}"; -static const char qt_particles_default_vertex_code[] = - "void main() { \n" - " defaultMain(); \n" - "}"; - -static const char qt_particles_default_fragment_code[] = - "uniform sampler2D source; \n" - "varying highp vec2 qt_TexCoord0; \n" - "uniform lowp float qt_Opacity; \n" - "void main() { \n" - " gl_FragColor = texture2D(source, qt_TexCoord0) * qt_Opacity; \n" - "}"; - -static QSGGeometry::Attribute PlainParticle_Attributes[] = { - QSGGeometry::Attribute::create(0, 2, GL_FLOAT, true), // Position - QSGGeometry::Attribute::create(1, 2, GL_FLOAT), // TexCoord - QSGGeometry::Attribute::create(2, 4, GL_FLOAT), // Data - QSGGeometry::Attribute::create(3, 4, GL_FLOAT), // Vectors - QSGGeometry::Attribute::create(4, 1, GL_FLOAT) // r -}; - -static QSGGeometry::AttributeSet PlainParticle_AttributeSet = -{ - 5, // Attribute Count - (2 + 2 + 4 + 4 + 1) * sizeof(float), - PlainParticle_Attributes -}; - -struct PlainVertex { - float x; - float y; - float tx; - float ty; - float t; - float lifeSpan; - float size; - float endSize; - float vx; - float vy; - float ax; - float ay; - float r; -}; - -struct PlainVertices { - PlainVertex v1; - PlainVertex v2; - PlainVertex v3; - PlainVertex v4; -}; - -/*! - \qmlclass CustomParticle QQuickCustomParticle - \inqmlmodule QtQuick.Particles 2 - \inherits ParticlePainter - \brief The CustomParticle element allows you to specify your own shader to paint particles. - -*/ - -QQuickCustomParticle::QQuickCustomParticle(QQuickItem* parent) - : QQuickParticlePainter(parent) - , m_dirtyData(true) - , m_material(0) - , m_rootNode(0) -{ - setFlag(QQuickItem::ItemHasContents); -} - -class QQuickShaderEffectMaterialObject : public QObject, public QQuickShaderEffectMaterial { }; - -void QQuickCustomParticle::sceneGraphInvalidated() -{ - m_nodes.clear(); - m_rootNode = 0; -} - -QQuickCustomParticle::~QQuickCustomParticle() -{ - if (m_material) - m_material->deleteLater(); -} - -void QQuickCustomParticle::componentComplete() -{ - reset(); - QQuickParticlePainter::componentComplete(); -} - - -//Trying to keep the shader conventions the same as in qsgshadereffectitem -/*! - \qmlproperty string QtQuick.Particles2::CustomParticle::fragmentShader - - This property holds the fragment shader's GLSL source code. - The default shader expects the texture coordinate to be passed from the - vertex shader as "varying highp vec2 qt_TexCoord0", and it samples from a - sampler2D named "source". -*/ - -void QQuickCustomParticle::setFragmentShader(const QByteArray &code) -{ - if (m_source.fragmentCode.constData() == code.constData()) - return; - m_source.fragmentCode = code; - if (isComponentComplete()) { - reset(); - } - emit fragmentShaderChanged(); -} - -/*! - \qmlproperty string QtQuick.Particles2::CustomParticle::vertexShader - - This property holds the vertex shader's GLSL source code. - - The default shader passes the texture coordinate along to the fragment - shader as "varying highp vec2 qt_TexCoord0". - - To aid writing a particle vertex shader, the following GLSL code is prepended - to your vertex shader: - \code - attribute highp vec2 qt_ParticlePos; - attribute highp vec2 qt_ParticleTex; - attribute highp vec4 qt_ParticleData; // x = time, y = lifeSpan, z = size, w = endSize - attribute highp vec4 qt_ParticleVec; // x,y = constant speed, z,w = acceleration - attribute highp float qt_ParticleR; - uniform highp mat4 qt_Matrix; - uniform highp float qt_Timestamp; - varying highp vec2 qt_TexCoord0; - void defaultMain() { - qt_TexCoord0 = qt_ParticleTex; - highp float size = qt_ParticleData.z; - highp float endSize = qt_ParticleData.w; - highp float t = (qt_Timestamp - qt_ParticleData.x) / qt_ParticleData.y; - highp float currentSize = mix(size, endSize, t * t); - if (t < 0. || t > 1.) - currentSize = 0.; - highp vec2 pos = qt_ParticlePos - - currentSize / 2. + currentSize * qt_ParticleTex // adjust size - + qt_ParticleVec.xy * t * qt_ParticleData.y // apply speed vector.. - + 0.5 * qt_ParticleVec.zw * pow(t * qt_ParticleData.y, 2.); - gl_Position = qt_Matrix * vec4(pos.x, pos.y, 0, 1); - } - \endcode - - defaultMain() is the same code as in the default shader, you can call this for basic - particle functions and then add additional variables for custom effects. Note that - the vertex shader for particles is responsible for simulating the movement of particles - over time, the particle data itself only has the starting position and spawn time. -*/ - -void QQuickCustomParticle::setVertexShader(const QByteArray &code) -{ - if (m_source.vertexCode.constData() == code.constData()) - return; - m_source.vertexCode = code; - if (isComponentComplete()) { - reset(); - } - emit vertexShaderChanged(); -} - -void QQuickCustomParticle::reset() -{ - disconnectPropertySignals(); - - m_source.attributeNames.clear(); - m_source.uniformNames.clear(); - m_source.respectsOpacity = false; - m_source.respectsMatrix = false; - m_source.className = metaObject()->className(); - - for (int i = 0; i < m_sources.size(); ++i) { - const SourceData &source = m_sources.at(i); - delete source.mapper; - if (source.item && source.item->parentItem() == this) - source.item->setParentItem(0); - } - m_sources.clear(); - - QQuickParticlePainter::reset(); - m_pleaseReset = true; - update(); -} - - -void QQuickCustomParticle::changeSource(int index) -{ - Q_ASSERT(index >= 0 && index < m_sources.size()); - QVariant v = property(m_sources.at(index).name.constData()); - setSource(v, index); -} - -void QQuickCustomParticle::updateData() -{ - m_dirtyData = true; - update(); -} - -void QQuickCustomParticle::setSource(const QVariant &var, int index) -{ - Q_ASSERT(index >= 0 && index < m_sources.size()); - - SourceData &source = m_sources[index]; - - source.item = 0; - if (var.isNull()) { - return; - } else if (!qVariantCanConvert(var)) { - qWarning("Could not assign source of type '%s' to property '%s'.", var.typeName(), source.name.constData()); - return; - } - - QObject *obj = qVariantValue(var); - source.item = qobject_cast(obj); - if (!source.item || !source.item->isTextureProvider()) { - qWarning("ShaderEffect: source uniform [%s] is not assigned a valid texture provider: %s [%s]", - source.name.constData(), qPrintable(obj->objectName()), obj->metaObject()->className()); - return; - } - - // TODO: Copy better solution in QQuickShaderEffect when they find it. - // 'source.item' needs a canvas to get a scenegraph node. - // The easiest way to make sure it gets a canvas is to - // make it a part of the same item tree as 'this'. - if (source.item && source.item->parentItem() == 0) { - source.item->setParentItem(this); - source.item->setVisible(false); - } -} - -void QQuickCustomParticle::disconnectPropertySignals() -{ - disconnect(this, 0, this, SLOT(updateData())); - for (int i = 0; i < m_sources.size(); ++i) { - SourceData &source = m_sources[i]; - disconnect(this, 0, source.mapper, 0); - disconnect(source.mapper, 0, this, 0); - } -} - -void QQuickCustomParticle::connectPropertySignals() -{ - QSet::const_iterator it; - for (it = m_source.uniformNames.begin(); it != m_source.uniformNames.end(); ++it) { - int pi = metaObject()->indexOfProperty(it->constData()); - if (pi >= 0) { - QMetaProperty mp = metaObject()->property(pi); - if (!mp.hasNotifySignal()) - qWarning("QQuickCustomParticle: property '%s' does not have notification method!", it->constData()); - QByteArray signalName("2"); - signalName.append(mp.notifySignal().signature()); - connect(this, signalName, this, SLOT(updateData())); - } else { - qWarning("QQuickCustomParticle: '%s' does not have a matching property!", it->constData()); - } - } - for (int i = 0; i < m_sources.size(); ++i) { - SourceData &source = m_sources[i]; - int pi = metaObject()->indexOfProperty(source.name.constData()); - if (pi >= 0) { - QMetaProperty mp = metaObject()->property(pi); - QByteArray signalName("2"); - signalName.append(mp.notifySignal().signature()); - connect(this, signalName, source.mapper, SLOT(map())); - source.mapper->setMapping(this, i); - connect(source.mapper, SIGNAL(mapped(int)), this, SLOT(changeSource(int))); - } else { - qWarning("QQuickCustomParticle: '%s' does not have a matching source!", source.name.constData()); - } - } -} - -void QQuickCustomParticle::updateProperties() -{ - QByteArray vertexCode = m_source.vertexCode; - QByteArray fragmentCode = m_source.fragmentCode; - if (vertexCode.isEmpty()) - vertexCode = qt_particles_default_vertex_code; - if (fragmentCode.isEmpty()) - fragmentCode = qt_particles_default_fragment_code; - vertexCode = qt_particles_template_vertex_code + vertexCode; - - m_source.attributeNames.clear(); - m_source.attributeNames << "qt_ParticlePos" - << "qt_ParticleTex" - << "qt_ParticleData" - << "qt_ParticleVec" - << "qt_ParticleR"; - - lookThroughShaderCode(vertexCode); - lookThroughShaderCode(fragmentCode); - - if (!m_source.respectsMatrix) - qWarning("QQuickCustomParticle: Missing reference to \'qt_Matrix\'."); - if (!m_source.respectsOpacity) - qWarning("QQuickCustomParticle: Missing reference to \'qt_Opacity\'."); - - for (int i = 0; i < m_sources.size(); ++i) { - QVariant v = property(m_sources.at(i).name); - setSource(v, i); - } - - connectPropertySignals(); -} - -void QQuickCustomParticle::lookThroughShaderCode(const QByteArray &code) -{ - // Regexp for matching attributes and uniforms. - // In human readable form: attribute|uniform [lowp|mediump|highp] - static QRegExp re(QLatin1String("\\b(attribute|uniform)\\b\\s*\\b(?:lowp|mediump|highp)?\\b\\s*\\b(\\w+)\\b\\s*\\b(\\w+)")); - Q_ASSERT(re.isValid()); - - int pos = -1; - - QString wideCode = QString::fromLatin1(code.constData(), code.size()); - - while ((pos = re.indexIn(wideCode, pos + 1)) != -1) { - QByteArray decl = re.cap(1).toLatin1(); // uniform or attribute - QByteArray type = re.cap(2).toLatin1(); // type - QByteArray name = re.cap(3).toLatin1(); // variable name - - if (decl == "attribute") { - if (!m_source.attributeNames.contains(name)) - qWarning() << "Custom Particle: Unknown attribute " << name; - } else { - Q_ASSERT(decl == "uniform");//TODO: Shouldn't assert - - if (name == "qt_Matrix") { - m_source.respectsMatrix = true; - } else if (name == "qt_Opacity") { - m_source.respectsOpacity = true; - } else if (name == "qt_Timestamp") { - //Not strictly necessary - } else { - m_source.uniformNames.insert(name); - if (type == "sampler2D") { - SourceData d; - d.mapper = new QSignalMapper; - d.name = name; - d.item = 0; - m_sources.append(d); - } - } - } - } -} - -QSGNode *QQuickCustomParticle::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) -{ - Q_UNUSED(oldNode); - if (m_pleaseReset){ - - //delete m_material;//Shader effect item doesn't regen material? - - delete m_rootNode;//Automatically deletes children - m_rootNode = 0; - m_nodes.clear(); - m_pleaseReset = false; - m_dirtyData = false; - } - - if (m_system && m_system->isRunning() && !m_system->isPaused()){ - prepareNextFrame(); - if (m_rootNode) { - update(); - foreach (QSGGeometryNode* node, m_nodes) - node->markDirty(QSGNode::DirtyGeometry);//done in buildData? - } - } - - return m_rootNode; -} - -void QQuickCustomParticle::prepareNextFrame(){ - if (!m_rootNode) - m_rootNode = buildCustomNodes(); - if (!m_rootNode) - return; - - m_lastTime = m_system->systemSync(this) / 1000.; - if (m_dirtyData || true)//Currently this is how we update timestamp... potentially over expensive. - buildData(); -} - -QQuickShaderEffectNode* QQuickCustomParticle::buildCustomNodes() -{ -#ifdef QT_OPENGL_ES_2 - if (m_count * 4 > 0xffff) { - printf("CustomParticle: Too many particles... \n"); - return 0; - } -#endif - - if (m_count <= 0) { - printf("CustomParticle: Too few particles... \n"); - return 0; - } - - updateProperties(); - - QQuickShaderEffectProgram s = m_source; - if (s.fragmentCode.isEmpty()) - s.fragmentCode = qt_particles_default_fragment_code; - if (s.vertexCode.isEmpty()) - s.vertexCode = qt_particles_default_vertex_code; - - if (!m_material) { - m_material = new QQuickShaderEffectMaterialObject; - } - - s.vertexCode = qt_particles_template_vertex_code + s.vertexCode; - m_material->setProgramSource(s); - foreach (const QString &str, m_groups){ - int gIdx = m_system->groupIds[str]; - int count = m_system->groupData[gIdx]->size(); - - QQuickShaderEffectNode* node = new QQuickShaderEffectNode(); - m_nodes.insert(gIdx, node); - - node->setMaterial(m_material); - node->markDirty(QSGNode::DirtyMaterial); - - //Create Particle Geometry - int vCount = count * 4; - int iCount = count * 6; - QSGGeometry *g = new QSGGeometry(PlainParticle_AttributeSet, vCount, iCount); - g->setDrawingMode(GL_TRIANGLES); - node->setGeometry(g); - PlainVertex *vertices = (PlainVertex *) g->vertexData(); - for (int p=0; p < count; ++p) { - commit(gIdx, p); - vertices[0].tx = 0; - vertices[0].ty = 0; - - vertices[1].tx = 1; - vertices[1].ty = 0; - - vertices[2].tx = 0; - vertices[2].ty = 1; - - vertices[3].tx = 1; - vertices[3].ty = 1; - vertices += 4; - } - quint16 *indices = g->indexDataAsUShort(); - for (int i=0; i < count; ++i) { - int o = i * 4; - indices[0] = o; - indices[1] = o + 1; - indices[2] = o + 2; - indices[3] = o + 1; - indices[4] = o + 3; - indices[5] = o + 2; - indices += 6; - } - } - foreach (QQuickShaderEffectNode* node, m_nodes){ - if (node == *(m_nodes.begin())) - continue; - (*(m_nodes.begin()))->appendChildNode(node); - } - - return *(m_nodes.begin()); -} - - -void QQuickCustomParticle::buildData() -{ - if (!m_rootNode) - return; - const QByteArray timestampName("qt_Timestamp"); - QVector > values; - QVector > textures; - const QVector > &oldTextures = m_material->textureProviders(); - for (int i = 0; i < oldTextures.size(); ++i) { - QSGTextureProvider *t = oldTextures.at(i).second; - if (t) - foreach (QQuickShaderEffectNode* node, m_nodes) - disconnect(t, SIGNAL(textureChanged()), node, SLOT(markDirtyTexture())); - } - for (int i = 0; i < m_sources.size(); ++i) { - const SourceData &source = m_sources.at(i); - QSGTextureProvider *t = source.item->textureProvider(); - textures.append(qMakePair(source.name, t)); - if (t) - foreach (QQuickShaderEffectNode* node, m_nodes) - connect(t, SIGNAL(textureChanged()), node, SLOT(markDirtyTexture()), Qt::DirectConnection); - } - for (QSet::const_iterator it = m_source.uniformNames.begin(); - it != m_source.uniformNames.end(); ++it) { - values.append(qMakePair(*it, property(*it))); - } - values.append(qMakePair(timestampName, QVariant(m_lastTime))); - m_material->setUniforms(values); - m_material->setTextureProviders(textures); - m_dirtyData = false; - foreach (QQuickShaderEffectNode* node, m_nodes) - node->markDirty(QSGNode::DirtyMaterial); -} - -void QQuickCustomParticle::initialize(int gIdx, int pIdx) -{ - QQuickParticleData* datum = m_system->groupData[gIdx]->data[pIdx]; - datum->r = rand()/(qreal)RAND_MAX; -} - -void QQuickCustomParticle::commit(int gIdx, int pIdx) -{ - if (m_nodes[gIdx] == 0) - return; - - QQuickParticleData* datum = m_system->groupData[gIdx]->data[pIdx]; - PlainVertices *particles = (PlainVertices *) m_nodes[gIdx]->geometry()->vertexData(); - PlainVertex *vertices = (PlainVertex *)&particles[pIdx]; - for (int i=0; i<4; ++i) { - vertices[i].x = datum->x - m_systemOffset.x(); - vertices[i].y = datum->y - m_systemOffset.y(); - vertices[i].t = datum->t; - vertices[i].lifeSpan = datum->lifeSpan; - vertices[i].size = datum->size; - vertices[i].endSize = datum->endSize; - vertices[i].vx = datum->vx; - vertices[i].vy = datum->vy; - vertices[i].ax = datum->ax; - vertices[i].ay = datum->ay; - vertices[i].r = datum->r; - } -} - -QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquickcustomparticle_p.h qt5-declarative-0.1~git20120423/src/quick/particles/qquickcustomparticle_p.h --- qt5-declarative-0.1~git20120402/src/quick/particles/qquickcustomparticle_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquickcustomparticle_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,121 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef CUSTOM_PARTICLE_H -#define CUSTOM_PARTICLE_H -#include "qquickparticlepainter_p.h" -#include -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -class QSGNode; -struct PlainVertices; - -class QQuickShaderEffectMaterialObject; - -//Genealogy: Hybrid of UltraParticle and ShaderEffect -class QQuickCustomParticle : public QQuickParticlePainter -{ - Q_OBJECT - Q_PROPERTY(QByteArray fragmentShader READ fragmentShader WRITE setFragmentShader NOTIFY fragmentShaderChanged) - Q_PROPERTY(QByteArray vertexShader READ vertexShader WRITE setVertexShader NOTIFY vertexShaderChanged) - -public: - explicit QQuickCustomParticle(QQuickItem* parent=0); - ~QQuickCustomParticle(); - - QByteArray fragmentShader() const { return m_source.fragmentCode; } - void setFragmentShader(const QByteArray &code); - - QByteArray vertexShader() const { return m_source.vertexCode; } - void setVertexShader(const QByteArray &code); -public Q_SLOTS: - void updateData(); - void changeSource(int); -Q_SIGNALS: - void fragmentShaderChanged(); - void vertexShaderChanged(); -protected: - virtual void initialize(int gIdx, int pIdx); - virtual void commit(int gIdx, int pIdx); - - QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *); - void prepareNextFrame(); - void setSource(const QVariant &var, int index); - void disconnectPropertySignals(); - void connectPropertySignals(); - void reset(); - void resize(int oldCount, int newCount); - void updateProperties(); - void lookThroughShaderCode(const QByteArray &code); - virtual void componentComplete(); - QQuickShaderEffectNode *buildCustomNodes(); - void performPendingResize(); - - void sceneGraphInvalidated(); - -private: - void buildData(); - - bool m_dirtyData; - QQuickShaderEffectProgram m_source; - struct SourceData - { - QSignalMapper *mapper; - QPointer item; - QByteArray name; - }; - QVector m_sources; - QQuickShaderEffectMaterialObject *m_material; - QQuickShaderEffectNode* m_rootNode; - QHash m_nodes; - qreal m_lastTime; - -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif //HEADER_GUARD diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquickdirection.cpp qt5-declarative-0.1~git20120423/src/quick/particles/qquickdirection.cpp --- qt5-declarative-0.1~git20120402/src/quick/particles/qquickdirection.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquickdirection.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,64 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qquickdirection_p.h" - -QT_BEGIN_NAMESPACE -/*! - \qmlclass Direction QQuickDirection - \inqmlmodule QtQuick.Particles 2 - \brief The Direction elements allow you to specify a vector space. - -*/ - - -QQuickDirection::QQuickDirection(QObject *parent) : - QObject(parent) -{ -} - -const QPointF QQuickDirection::sample(const QPointF &from) -{ - Q_UNUSED(from); - return QPointF(); -} - -QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquickdirection_p.h qt5-declarative-0.1~git20120423/src/quick/particles/qquickdirection_p.h --- qt5-declarative-0.1~git20120402/src/quick/particles/qquickdirection_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquickdirection_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,68 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef VARYINGVECTOR_H -#define VARYINGVECTOR_H - -#include -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -class QQuickDirection : public QObject -{ - Q_OBJECT -public: - explicit QQuickDirection(QObject *parent = 0); - - virtual const QPointF sample(const QPointF &from); -signals: - -public slots: - -protected: -}; - -QT_END_NAMESPACE -QT_END_HEADER -#endif // VARYINGVECTOR_H diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquickellipseextruder.cpp qt5-declarative-0.1~git20120423/src/quick/particles/qquickellipseextruder.cpp --- qt5-declarative-0.1~git20120402/src/quick/particles/qquickellipseextruder.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquickellipseextruder.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,86 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qquickellipseextruder_p.h" -#include -#include - -#ifdef Q_OS_QNX -#include -#endif - -QT_BEGIN_NAMESPACE -/*! - \qmlclass EllipseShape QQuickEllipseExtruder - \inqmlmodule QtQuick.Particles 2 - \inherits Shape - \brief The EllipseShape represents an ellipse to other particle system elements - - This shape can be used by Emitter subclasses and Affector subclasses to have - them act upon an ellipse shaped area. -*/ -QQuickEllipseExtruder::QQuickEllipseExtruder(QObject *parent) : - QQuickParticleExtruder(parent) - , m_fill(true) -{ -} - -/*! - \qmlproperty bool QtQuick.Particles2::EllipseShape::fill - If fill is true the ellipse is filled; otherwise it is just a border. - - Default is true. -*/ - -QPointF QQuickEllipseExtruder::extrude(const QRectF & r) -{ - qreal theta = ((qreal)rand()/RAND_MAX) * 6.2831853071795862; - qreal mag = m_fill ? ((qreal)rand()/RAND_MAX) : 1; - return QPointF(r.x() + r.width()/2 + mag * (r.width()/2) * cos(theta), - r.y() + r.height()/2 + mag * (r.height()/2) * sin(theta)); -} - -bool QQuickEllipseExtruder::contains(const QRectF &bounds, const QPointF &point) -{ - return bounds.contains(point);//TODO: Ellipse -} - -QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquickellipseextruder_p.h qt5-declarative-0.1~git20120423/src/quick/particles/qquickellipseextruder_p.h --- qt5-declarative-0.1~git20120402/src/quick/particles/qquickellipseextruder_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquickellipseextruder_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,83 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef ELLIPSEEXTRUDER_H -#define ELLIPSEEXTRUDER_H -#include "qquickparticleextruder_p.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -class QQuickEllipseExtruder : public QQuickParticleExtruder -{ - Q_OBJECT - Q_PROPERTY(bool fill READ fill WRITE setFill NOTIFY fillChanged)//###Use base class? If it's still box -public: - explicit QQuickEllipseExtruder(QObject *parent = 0); - virtual QPointF extrude(const QRectF &); - virtual bool contains(const QRectF &bounds, const QPointF &point); - - bool fill() const - { - return m_fill; - } - -signals: - - void fillChanged(bool arg); - -public slots: - - void setFill(bool arg) - { - if (m_fill != arg) { - m_fill = arg; - emit fillChanged(arg); - } - } -private: - bool m_fill; -}; - -QT_END_NAMESPACE -QT_END_HEADER -#endif // ELLIPSEEXTRUDER_H diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquickfriction.cpp qt5-declarative-0.1~git20120423/src/quick/particles/qquickfriction.cpp --- qt5-declarative-0.1~git20120402/src/quick/particles/qquickfriction.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquickfriction.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,111 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qquickfriction_p.h" -QT_BEGIN_NAMESPACE -/*! - \qmlclass Friction QQuickFrictionAffector - \inqmlmodule QtQuick.Particles 2 - \inherits Affector - \brief The Friction affector slows down movement proportional to the particle's current speed. - -*/ - -/*! - \qmlproperty real QtQuick.Particles2::Friction::factor - - A drag will be applied to moving objects which is this factor of their current velocity. -*/ -/*! - \qmlproperty real QtQuick.Particles2::Friction::threshold - - The drag will only be applied to objects with a velocity above the threshold velocity. The - drag applied will bring objects down to the threshold velocity, but no further. - - The default threshold is 0 -*/ -static qreal sign(qreal a) -{ - return a >= 0 ? 1 : -1; -} - -static const qreal epsilon = 0.00001; - -QQuickFrictionAffector::QQuickFrictionAffector(QQuickItem *parent) : - QQuickParticleAffector(parent), m_factor(0.0), m_threshold(0.0) -{ -} - -bool QQuickFrictionAffector::affectParticle(QQuickParticleData *d, qreal dt) -{ - if (!m_factor) - return false; - qreal curVX = d->curVX(); - qreal curVY = d->curVY(); - if (!curVX && !curVY) - return false; - qreal newVX = curVX + (curVX * m_factor * -1 * dt); - qreal newVY = curVY + (curVY * m_factor * -1 * dt); - - if (!m_threshold) { - if (sign(curVX) != sign(newVX)) - newVX = 0; - if (sign(curVY) != sign(newVY)) - newVY = 0; - } else { - qreal curMag = sqrt(curVX*curVX + curVY*curVY); - if (curMag <= m_threshold + epsilon) - return false; - qreal newMag = sqrt(newVX*newVX + newVY*newVY); - if (newMag <= m_threshold + epsilon || //went past the threshold, stop there instead - sign(curVX) != sign(newVX) || //went so far past maybe it came out the other side! - sign(curVY) != sign(newVY)) { - qreal theta = atan2(curVY, curVX); - newVX = m_threshold * cos(theta); - newVY = m_threshold * sin(theta); - } - } - - d->setInstantaneousVX(newVX); - d->setInstantaneousVY(newVY); - return true; -} -QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquickfriction_p.h qt5-declarative-0.1~git20120423/src/quick/particles/qquickfriction_p.h --- qt5-declarative-0.1~git20120402/src/quick/particles/qquickfriction_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquickfriction_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef FRICTIONAFFECTOR_H -#define FRICTIONAFFECTOR_H -#include "qquickparticleaffector_p.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -class QQuickFrictionAffector : public QQuickParticleAffector -{ - Q_OBJECT - Q_PROPERTY(qreal factor READ factor WRITE setFactor NOTIFY factorChanged) - Q_PROPERTY(qreal threshold READ threshold WRITE setThreshold NOTIFY thresholdChanged) -public: - explicit QQuickFrictionAffector(QQuickItem *parent = 0); - - qreal factor() const - { - return m_factor; - } - - qreal threshold() const - { - return m_threshold; - } - -protected: - virtual bool affectParticle(QQuickParticleData *d, qreal dt); - -signals: - - void factorChanged(qreal arg); - void thresholdChanged(qreal arg); - -public slots: - - void setFactor(qreal arg) - { - if (m_factor != arg) { - m_factor = arg; - emit factorChanged(arg); - } - } - - void setThreshold(qreal arg) - { - if (m_threshold != arg) { - m_threshold = arg; - emit thresholdChanged(arg); - } - } - -private: - qreal m_factor; - qreal m_threshold; -}; - -QT_END_NAMESPACE -QT_END_HEADER -#endif // FRICTIONAFFECTOR_H diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquickgravity.cpp qt5-declarative-0.1~git20120423/src/quick/particles/qquickgravity.cpp --- qt5-declarative-0.1~git20120402/src/quick/particles/qquickgravity.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquickgravity.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,97 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qquickgravity_p.h" -#include -QT_BEGIN_NAMESPACE -const qreal CONV = 0.017453292520444443; -/*! - \qmlclass Gravity QQuickGravityAffector - \inqmlmodule QtQuick.Particles 2 - \inherits Affector - \brief The Gravity element allows you to set an accleration in an angle - - This element will accelerate all affected particles to a vector of - the specified magnitude in the specified angle. If the angle and acceleration do - not vary, it is more efficient to set the specified acceleration on the Emitter. - - This element models the gravity of a massive object whose center of - gravity is far away (and thus the gravitational pull is effectively constant - across the scene). To model the gravity of an object near or inside the scene, - use PointAttractor. -*/ - -/*! - \qmlproperty real QtQuick.Particles2::Gravity::magnitude - - Pixels per second that objects will be accelerated by. -*/ -/*! - \qmlproperty real QtQuick.Particles2::Gravity::acceleration - - Name changed to magnitude, will be removed soon. -*/ -/*! - \qmlproperty real QtQuick.Particles2::Gravity::angle - - Angle of acceleration. -*/ - -QQuickGravityAffector::QQuickGravityAffector(QQuickItem *parent) : - QQuickParticleAffector(parent), m_magnitude(-10), m_angle(90), m_needRecalc(true) -{ -} - -bool QQuickGravityAffector::affectParticle(QQuickParticleData *d, qreal dt) -{ - if (!m_magnitude) - return false; - if (m_needRecalc) { - m_needRecalc = false; - m_dx = m_magnitude * cos(m_angle * CONV); - m_dy = m_magnitude * sin(m_angle * CONV); - } - - d->setInstantaneousVX(d->curVX() + m_dx*dt); - d->setInstantaneousVY(d->curVY() + m_dy*dt); - return true; -} -QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquickgravity_p.h qt5-declarative-0.1~git20120423/src/quick/particles/qquickgravity_p.h --- qt5-declarative-0.1~git20120402/src/quick/particles/qquickgravity_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquickgravity_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,115 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef GRAVITYAFFECTOR_H -#define GRAVITYAFFECTOR_H -#include "qquickparticleaffector_p.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -class QQuickGravityAffector : public QQuickParticleAffector -{ - Q_OBJECT - Q_PROPERTY(qreal magnitude READ magnitude WRITE setMagnitude NOTIFY magnitudeChanged) - Q_PROPERTY(qreal acceleration READ magnitude WRITE setAcceleration NOTIFY magnitudeChanged) - Q_PROPERTY(qreal angle READ angle WRITE setAngle NOTIFY angleChanged) -public: - explicit QQuickGravityAffector(QQuickItem *parent = 0); - qreal magnitude() const - { - return m_magnitude; - } - - qreal angle() const - { - return m_angle; - } -protected: - virtual bool affectParticle(QQuickParticleData *d, qreal dt); -signals: - - void magnitudeChanged(qreal arg); - - void angleChanged(qreal arg); - -public slots: -void setAcceleration(qreal arg) -{ - qWarning() << "Gravity::acceleration has been renamed Gravity::magnitude"; - if (m_magnitude != arg) { - m_magnitude = arg; - m_needRecalc = true; - emit magnitudeChanged(arg); - } -} - -void setMagnitude(qreal arg) -{ - if (m_magnitude != arg) { - m_magnitude = arg; - m_needRecalc = true; - emit magnitudeChanged(arg); - } -} - -void setAngle(qreal arg) -{ - if (m_angle != arg) { - m_angle = arg; - m_needRecalc = true; - emit angleChanged(arg); - } -} - -private: - qreal m_magnitude; - qreal m_angle; - - bool m_needRecalc; - qreal m_dx; - qreal m_dy; -}; - -QT_END_NAMESPACE -QT_END_HEADER -#endif // GRAVITYAFFECTOR_H diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquickgroupgoal.cpp qt5-declarative-0.1~git20120423/src/quick/particles/qquickgroupgoal.cpp --- qt5-declarative-0.1~git20120402/src/quick/particles/qquickgroupgoal.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquickgroupgoal.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,112 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qquickgroupgoal_p.h" -#include -#include -#include "qquickimageparticle_p.h" -#include - -QT_BEGIN_NAMESPACE - -/*! - \qmlclass GroupGoal QQuickGroupGoalAffector - \inqmlmodule QtQuick.Particles 2 - \inherits Affector - \brief The GroupGoal Affector allows you to change the state of a group of a particle. - -*/ -/*! - \qmlproperty string QtQuick.Particles2::GroupGoal::goalState - - The name of the group which the affected particles should move to. - - Groups can have defined durations and transitions between them, setting goalState - will cause it to disregard any path weightings (including 0) and head down the path - which will reach the goalState quickest. It will pass through intermediate groups - on that path for their respective durations. -*/ -/*! - \qmlproperty bool QtQuick.Particles2::GroupGoal::jump - - If true, affected particles will jump directly to the target group instead of taking the - the shortest valid path to get there. They will also not finish their current state, - but immediately move to the beginning of the goal state. - - Default is false. -*/ - -QQuickGroupGoalAffector::QQuickGroupGoalAffector(QQuickItem *parent) : - QQuickParticleAffector(parent), m_jump(false) -{ - m_ignoresTime = true; -} - -void QQuickGroupGoalAffector::setGoalState(QString arg) -{ - if (m_goalState != arg) { - m_goalState = arg; - emit goalStateChanged(arg); - } -} - -bool QQuickGroupGoalAffector::affectParticle(QQuickParticleData *d, qreal dt) -{ - Q_UNUSED(dt); - QQuickStochasticEngine *engine = m_system->stateEngine; - bool notUsingEngine = false; - if (!engine) - notUsingEngine = true; - - int index = d->systemIndex; - int goalIdx = m_system->groupIds[m_goalState]; - if (notUsingEngine){//no stochastic states defined. So cut out the engine - //TODO: It's possible to move to a group that is intermediate and not used by painters or emitters - but right now that will redirect to the default group - m_system->moveGroups(d, goalIdx); - return true; - }else if (engine->curState(index) != goalIdx){ - engine->setGoal(goalIdx, index, m_jump); - return true; - } - return false; -} - -QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquickgroupgoal_p.h qt5-declarative-0.1~git20120423/src/quick/particles/qquickgroupgoal_p.h --- qt5-declarative-0.1~git20120402/src/quick/particles/qquickgroupgoal_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquickgroupgoal_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,100 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef GROUPGOALAFFECTOR_H -#define GROUPGOALAFFECTOR_H -#include "qquickparticleaffector_p.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -class QQuickStochasticEngine; - -class QQuickGroupGoalAffector : public QQuickParticleAffector -{ - Q_OBJECT - Q_PROPERTY(QString goalState READ goalState WRITE setGoalState NOTIFY goalStateChanged) - Q_PROPERTY(bool jump READ jump WRITE setJump NOTIFY jumpChanged) -public: - explicit QQuickGroupGoalAffector(QQuickItem *parent = 0); - - QString goalState() const - { - return m_goalState; - } - - bool jump() const - { - return m_jump; - } - -protected: - virtual bool affectParticle(QQuickParticleData *d, qreal dt); - -signals: - - void goalStateChanged(QString arg); - - void jumpChanged(bool arg); - -public slots: - - void setGoalState(QString arg); - - void setJump(bool arg) - { - if (m_jump != arg) { - m_jump = arg; - emit jumpChanged(arg); - } - } - -private: - QString m_goalState; - bool m_jump; -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // GROUPGOALAFFECTOR_H diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquickimageparticle.cpp qt5-declarative-0.1~git20120423/src/quick/particles/qquickimageparticle.cpp --- qt5-declarative-0.1~git20120402/src/quick/particles/qquickimageparticle.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquickimageparticle.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,1978 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include "qquickimageparticle_p.h" -#include "qquickparticleemitter_p.h" -#include -#include -#include -#include -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - -#ifndef QT_OPENGL_ES_2 -#define SHADER_DEFINES "#version 120\n" -#else -#define SHADER_DEFINES "" -#endif - -//TODO: Make it larger on desktop? Requires fixing up shader code with the same define -#define UNIFORM_ARRAY_SIZE 64 - -static const char vertexShaderCode[] = - "#if defined(DEFORM)\n" - "attribute highp vec4 vPosTex;\n" - "#else\n" - "attribute highp vec2 vPos;\n" - "#endif\n" - "attribute highp vec4 vData; // x = time, y = lifeSpan, z = size, w = endSize\n" - "attribute highp vec4 vVec; // x,y = constant speed, z,w = acceleration\n" - "uniform highp float entry;\n" - "#if defined(COLOR)\n" - "attribute highp vec4 vColor;\n" - "#endif\n" - "#if defined(DEFORM)\n" - "attribute highp vec4 vDeformVec; //x,y x unit vector; z,w = y unit vector\n" - "attribute highp vec3 vRotation; //x = radians of rotation, y=rotation speed, z= bool autoRotate\n" - "#endif\n" - "#if defined(SPRITE)\n" - "attribute highp vec3 vAnimData;// w,h(premultiplied of anim), interpolation progress\n" - "attribute highp vec4 vAnimPos;//x,y, x,y (two frames for interpolation)\n" - "#endif\n" - "\n" - "uniform highp mat4 qt_Matrix;\n" - "uniform highp float timestamp;\n" - "#if defined(TABLE)\n" - "varying lowp vec2 tt;//y is progress if Sprite mode\n" - "uniform highp float sizetable[64];\n" - "uniform highp float opacitytable[64];\n" - "#endif\n" - "#if defined(SPRITE)\n" - "varying highp vec4 fTexS;\n" - "#elif defined(DEFORM)\n" - "varying highp vec2 fTex;\n" - "#endif\n" - "#if defined(COLOR)\n" - "varying lowp vec4 fColor;\n" - "#else\n" - "varying lowp float fFade;\n" - "#endif\n" - "\n" - "\n" - "void main() {\n" - "\n" - " highp float t = (timestamp - vData.x) / vData.y;\n" - " if (t < 0. || t > 1.) {\n" - "#if defined(DEFORM)\n" - " gl_Position = qt_Matrix * vec4(vPosTex.x, vPosTex.y, 0., 1.);\n" - "#else\n" - " gl_PointSize = 0.;\n" - "#endif\n" - " } else {\n" - "#if defined(SPRITE)\n" - " tt.y = vAnimData.z;\n" - " //Calculate frame location in texture\n" - " fTexS.xy = vAnimPos.xy + vPosTex.zw * vAnimData.xy;\n" - " //Next frame is also passed, for interpolation\n" - " fTexS.zw = vAnimPos.zw + vPosTex.zw * vAnimData.xy;\n" - "\n" - "#elif defined(DEFORM)\n" - " fTex = vPosTex.zw;\n" - "#endif\n" - " highp float currentSize = mix(vData.z, vData.w, t * t);\n" - " lowp float fade = 1.;\n" - " highp float fadeIn = min(t * 10., 1.);\n" - " highp float fadeOut = 1. - clamp((t - 0.75) * 4.,0., 1.);\n" - "\n" - "#if defined(TABLE)\n" - " currentSize = currentSize * sizetable[int(floor(t*64.))];\n" - " fade = fade * opacitytable[int(floor(t*64.))];\n" - "#endif\n" - "\n" - " if (entry == 1.)\n" - " fade = fade * fadeIn * fadeOut;\n" - " else if (entry == 2.)\n" - " currentSize = currentSize * fadeIn * fadeOut;\n" - "\n" - " if (currentSize <= 0.) {\n" - "#if defined(DEFORM)\n" - " gl_Position = qt_Matrix * vec4(vPosTex.x, vPosTex.y, 0., 1.);\n" - "#else\n" - " gl_PointSize = 0.;\n" - "#endif\n" - " } else {\n" - " if (currentSize < 3.)//Sizes too small look jittery as they move\n" - " currentSize = 3.;\n" - "\n" - " highp vec2 pos;\n" - "#if defined(DEFORM)\n" - " highp float rotation = vRotation.x + vRotation.y * t * vData.y;\n" - " if (vRotation.z == 1.0){\n" - " highp vec2 curVel = vVec.zw * t * vData.y + vVec.xy;\n" - " rotation += atan(curVel.y, curVel.x);\n" - " }\n" - " highp vec2 trigCalcs = vec2(cos(rotation), sin(rotation));\n" - " highp vec4 deform = vDeformVec * currentSize * (vPosTex.zzww - 0.5);\n" - " highp vec4 rotatedDeform = deform.xxzz * trigCalcs.xyxy;\n" - " rotatedDeform = rotatedDeform + (deform.yyww * trigCalcs.yxyx * vec4(-1.,1.,-1.,1.));\n" - " /* The readable version:\n" - " highp vec2 xDeform = vDeformVec.xy * currentSize * (vTex.x-0.5);\n" - " highp vec2 yDeform = vDeformVec.zw * currentSize * (vTex.y-0.5);\n" - " highp vec2 xRotatedDeform;\n" - " xRotatedDeform.x = trigCalcs.x*xDeform.x - trigCalcs.y*xDeform.y;\n" - " xRotatedDeform.y = trigCalcs.y*xDeform.x + trigCalcs.x*xDeform.y;\n" - " highp vec2 yRotatedDeform;\n" - " yRotatedDeform.x = trigCalcs.x*yDeform.x - trigCalcs.y*yDeform.y;\n" - " yRotatedDeform.y = trigCalcs.y*yDeform.x + trigCalcs.x*yDeform.y;\n" - " */\n" - " pos = vPosTex.xy\n" - " + rotatedDeform.xy\n" - " + rotatedDeform.zw\n" - " + vVec.xy * t * vData.y // apply speed\n" - " + 0.5 * vVec.zw * pow(t * vData.y, 2.); // apply acceleration\n" - "#else\n" - " pos = vPos\n" - " + vVec.xy * t * vData.y // apply speed vector..\n" - " + 0.5 * vVec.zw * pow(t * vData.y, 2.);\n" - " gl_PointSize = currentSize;\n" - "#endif\n" - " gl_Position = qt_Matrix * vec4(pos.x, pos.y, 0, 1);\n" - "\n" - "#if defined(COLOR)\n" - " fColor = vColor * fade;\n" - "#else\n" - " fFade = fade;\n" - "#endif\n" - "#if defined(TABLE)\n" - " tt.x = t;\n" - "#endif\n" - " }\n" - " }\n" - "}\n"; - -static const char fragmentShaderCode[] = - "uniform sampler2D texture;\n" - "uniform lowp float qt_Opacity;\n" - "\n" - "#if defined(SPRITE)\n" - "varying highp vec4 fTexS;\n" - "#elif defined(DEFORM)\n" - "varying highp vec2 fTex;\n" - "#endif\n" - "#if defined(COLOR)\n" - "varying lowp vec4 fColor;\n" - "#else\n" - "varying lowp float fFade;\n" - "#endif\n" - "#if defined(TABLE)\n" - "varying lowp vec2 tt;\n" - "uniform sampler2D colortable;\n" - "#endif\n" - "\n" - "void main() {\n" - "#if defined(SPRITE)\n" - " gl_FragColor = mix(texture2D(texture, fTexS.xy), texture2D(texture, fTexS.zw), tt.y)\n" - " * fColor\n" - " * texture2D(colortable, tt)\n" - " * qt_Opacity;\n" - "#elif defined(TABLE)\n" - " gl_FragColor = texture2D(texture, fTex)\n" - " * fColor\n" - " * texture2D(colortable, tt)\n" - " * qt_Opacity;\n" - "#elif defined(DEFORM)\n" - " gl_FragColor = (texture2D(texture, fTex)) * fColor * qt_Opacity;\n" - "#elif defined(COLOR)\n" - " gl_FragColor = (texture2D(texture, gl_PointCoord)) * fColor * qt_Opacity;\n" - "#else\n" - " gl_FragColor = texture2D(texture, gl_PointCoord) * (fFade * qt_Opacity);\n" - "#endif\n" - "}\n"; - -const qreal CONV = 0.017453292519943295; -class ImageMaterialData -{ - public: - ImageMaterialData() - : texture(0), colorTable(0) - {} - - ~ImageMaterialData(){ - delete texture; - delete colorTable; - } - - QSGTexture *texture; - QSGTexture *colorTable; - float sizeTable[UNIFORM_ARRAY_SIZE]; - float opacityTable[UNIFORM_ARRAY_SIZE]; - - qreal timestamp; - qreal entry; - QSizeF animSheetSize; -}; - -class TabledMaterialData : public ImageMaterialData {}; -class TabledMaterial : public QSGSimpleMaterialShader -{ - QSG_DECLARE_SIMPLE_SHADER(TabledMaterial, TabledMaterialData) - -public: - TabledMaterial() - { - m_vertex_code = QByteArray(SHADER_DEFINES) - + QByteArray("#define TABLE\n#define DEFORM\n#define COLOR\n") - + vertexShaderCode; - - m_fragment_code = QByteArray(SHADER_DEFINES) - + QByteArray("#define TABLE\n#define DEFORM\n#define COLOR\n") - + fragmentShaderCode; - - Q_ASSERT(!m_vertex_code.isNull()); - Q_ASSERT(!m_fragment_code.isNull()); - } - - const char *vertexShader() const { return m_vertex_code.constData(); } - const char *fragmentShader() const { return m_fragment_code.constData(); } - - QList attributes() const { - return QList() << "vPosTex" << "vData" << "vVec" - << "vColor" << "vDeformVec" << "vRotation"; - }; - - void initialize() { - QSGSimpleMaterialShader::initialize(); - program()->bind(); - program()->setUniformValue("texture", 0); - program()->setUniformValue("colortable", 1); - glFuncs = QOpenGLContext::currentContext()->functions(); - m_timestamp_id = program()->uniformLocation("timestamp"); - m_entry_id = program()->uniformLocation("entry"); - m_sizetable_id = program()->uniformLocation("sizetable"); - m_opacitytable_id = program()->uniformLocation("opacitytable"); - } - - void updateState(const TabledMaterialData* d, const TabledMaterialData*) { - glFuncs->glActiveTexture(GL_TEXTURE1); - d->colorTable->bind(); - - glFuncs->glActiveTexture(GL_TEXTURE0); - d->texture->bind(); - - program()->setUniformValue(m_timestamp_id, (float) d->timestamp); - program()->setUniformValue(m_entry_id, (float) d->entry); - program()->setUniformValueArray(m_sizetable_id, (float*) d->sizeTable, UNIFORM_ARRAY_SIZE, 1); - program()->setUniformValueArray(m_opacitytable_id, (float*) d->opacityTable, UNIFORM_ARRAY_SIZE, 1); - } - - int m_entry_id; - int m_timestamp_id; - int m_sizetable_id; - int m_opacitytable_id; - QByteArray m_vertex_code; - QByteArray m_fragment_code; - QOpenGLFunctions* glFuncs; -}; - -class DeformableMaterialData : public ImageMaterialData {}; -class DeformableMaterial : public QSGSimpleMaterialShader -{ - QSG_DECLARE_SIMPLE_SHADER(DeformableMaterial, DeformableMaterialData) - -public: - DeformableMaterial() - { - m_vertex_code = QByteArray(SHADER_DEFINES) - + QByteArray("#define DEFORM\n#define COLOR\n") - + vertexShaderCode; - - m_fragment_code = QByteArray(SHADER_DEFINES) - + QByteArray("#define DEFORM\n#define COLOR\n") - + fragmentShaderCode; - - Q_ASSERT(!m_vertex_code.isNull()); - Q_ASSERT(!m_fragment_code.isNull()); - } - - const char *vertexShader() const { return m_vertex_code.constData(); } - const char *fragmentShader() const { return m_fragment_code.constData(); } - - QList attributes() const { - return QList() << "vPosTex" << "vData" << "vVec" - << "vColor" << "vDeformVec" << "vRotation"; - }; - - void initialize() { - QSGSimpleMaterialShader::initialize(); - program()->bind(); - program()->setUniformValue("texture", 0); - glFuncs = QOpenGLContext::currentContext()->functions(); - m_timestamp_id = program()->uniformLocation("timestamp"); - m_entry_id = program()->uniformLocation("entry"); - } - - void updateState(const DeformableMaterialData* d, const DeformableMaterialData*) { - glFuncs->glActiveTexture(GL_TEXTURE0); - d->texture->bind(); - - program()->setUniformValue(m_timestamp_id, (float) d->timestamp); - program()->setUniformValue(m_entry_id, (float) d->entry); - } - - int m_entry_id; - int m_timestamp_id; - QByteArray m_vertex_code; - QByteArray m_fragment_code; - QOpenGLFunctions* glFuncs; -}; - -class SpriteMaterialData : public ImageMaterialData {}; -class SpriteMaterial : public QSGSimpleMaterialShader -{ - QSG_DECLARE_SIMPLE_SHADER(SpriteMaterial, SpriteMaterialData) - -public: - SpriteMaterial() - { - m_vertex_code = QByteArray(SHADER_DEFINES) - + QByteArray("#define SPRITE\n#define TABLE\n#define DEFORM\n#define COLOR\n") - + vertexShaderCode; - - m_fragment_code = QByteArray(SHADER_DEFINES) - + QByteArray("#define SPRITE\n#define TABLE\n#define DEFORM\n#define COLOR\n") - + fragmentShaderCode; - - Q_ASSERT(!m_vertex_code.isNull()); - Q_ASSERT(!m_fragment_code.isNull()); - } - - const char *vertexShader() const { return m_vertex_code.constData(); } - const char *fragmentShader() const { return m_fragment_code.constData(); } - - QList attributes() const { - return QList() << "vPosTex" << "vData" << "vVec" - << "vColor" << "vDeformVec" << "vRotation" << "vAnimData" << "vAnimPos"; - }; - - void initialize() { - QSGSimpleMaterialShader::initialize(); - program()->bind(); - program()->setUniformValue("texture", 0); - program()->setUniformValue("colortable", 1); - glFuncs = QOpenGLContext::currentContext()->functions(); - //Don't actually expose the animSheetSize in the shader, it's currently only used for CPU calculations. - m_timestamp_id = program()->uniformLocation("timestamp"); - m_entry_id = program()->uniformLocation("entry"); - m_sizetable_id = program()->uniformLocation("sizetable"); - m_opacitytable_id = program()->uniformLocation("opacitytable"); - } - - void updateState(const SpriteMaterialData* d, const SpriteMaterialData*) { - glFuncs->glActiveTexture(GL_TEXTURE1); - d->colorTable->bind(); - - // make sure we end by setting GL_TEXTURE0 as active texture - glFuncs->glActiveTexture(GL_TEXTURE0); - d->texture->bind(); - - program()->setUniformValue(m_timestamp_id, (float) d->timestamp); - program()->setUniformValue(m_entry_id, (float) d->entry); - program()->setUniformValueArray(m_sizetable_id, (float*) d->sizeTable, 64, 1); - program()->setUniformValueArray(m_opacitytable_id, (float*) d->opacityTable, UNIFORM_ARRAY_SIZE, 1); - } - - int m_timestamp_id; - int m_entry_id; - int m_sizetable_id; - int m_opacitytable_id; - QByteArray m_vertex_code; - QByteArray m_fragment_code; - QOpenGLFunctions* glFuncs; -}; - -class ColoredMaterialData : public ImageMaterialData {}; -class ColoredMaterial : public QSGSimpleMaterialShader -{ - QSG_DECLARE_SIMPLE_SHADER(ColoredMaterial, ColoredMaterialData) - -public: - ColoredMaterial() - { - m_vertex_code = QByteArray(SHADER_DEFINES) - + QByteArray("#define COLOR\n") - + vertexShaderCode; - - m_fragment_code = QByteArray(SHADER_DEFINES) - + QByteArray("#define COLOR\n") - + fragmentShaderCode; - - Q_ASSERT(!m_vertex_code.isNull()); - Q_ASSERT(!m_fragment_code.isNull()); - } - - const char *vertexShader() const { return m_vertex_code.constData(); } - const char *fragmentShader() const { return m_fragment_code.constData(); } - - void activate() { - QSGSimpleMaterialShader::activate(); -#if !defined(QT_OPENGL_ES_2) && !defined(Q_OS_WIN) - glEnable(GL_POINT_SPRITE); - glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); -#endif - } - - void deactivate() { - QSGSimpleMaterialShader::deactivate(); -#if !defined(QT_OPENGL_ES_2) && !defined(Q_OS_WIN) - glDisable(GL_POINT_SPRITE); - glDisable(GL_VERTEX_PROGRAM_POINT_SIZE); -#endif - } - - QList attributes() const { - return QList() << "vPos" << "vData" << "vVec" << "vColor"; - } - - void initialize() { - QSGSimpleMaterialShader::initialize(); - program()->bind(); - program()->setUniformValue("texture", 0); - glFuncs = QOpenGLContext::currentContext()->functions(); - m_timestamp_id = program()->uniformLocation("timestamp"); - m_entry_id = program()->uniformLocation("entry"); - } - - void updateState(const ColoredMaterialData* d, const ColoredMaterialData*) { - glFuncs->glActiveTexture(GL_TEXTURE0); - d->texture->bind(); - - program()->setUniformValue(m_timestamp_id, (float) d->timestamp); - program()->setUniformValue(m_entry_id, (float) d->entry); - } - - int m_timestamp_id; - int m_entry_id; - QByteArray m_vertex_code; - QByteArray m_fragment_code; - QOpenGLFunctions* glFuncs; -}; - -class SimpleMaterialData : public ImageMaterialData {}; -class SimpleMaterial : public QSGSimpleMaterialShader -{ - QSG_DECLARE_SIMPLE_SHADER(SimpleMaterial, SimpleMaterialData) - -public: - SimpleMaterial() - { - m_vertex_code = QByteArray(SHADER_DEFINES) - + vertexShaderCode; - - m_fragment_code = QByteArray(SHADER_DEFINES) - + fragmentShaderCode; - - Q_ASSERT(!m_vertex_code.isNull()); - Q_ASSERT(!m_fragment_code.isNull()); - } - - const char *vertexShader() const { return m_vertex_code.constData(); } - const char *fragmentShader() const { return m_fragment_code.constData(); } - - void activate() { - QSGSimpleMaterialShader::activate(); -#if !defined(QT_OPENGL_ES_2) && !defined(Q_OS_WIN) - glEnable(GL_POINT_SPRITE); - glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); -#endif - } - - void deactivate() { - QSGSimpleMaterialShader::deactivate(); -#if !defined(QT_OPENGL_ES_2) && !defined(Q_OS_WIN) - glDisable(GL_POINT_SPRITE); - glDisable(GL_VERTEX_PROGRAM_POINT_SIZE); -#endif - } - - QList attributes() const { - return QList() << "vPos" << "vData" << "vVec"; - } - - void initialize() { - QSGSimpleMaterialShader::initialize(); - program()->bind(); - program()->setUniformValue("texture", 0); - glFuncs = QOpenGLContext::currentContext()->functions(); - m_timestamp_id = program()->uniformLocation("timestamp"); - m_entry_id = program()->uniformLocation("entry"); - } - - void updateState(const SimpleMaterialData* d, const SimpleMaterialData*) { - glFuncs->glActiveTexture(GL_TEXTURE0); - d->texture->bind(); - - program()->setUniformValue(m_timestamp_id, (float) d->timestamp); - program()->setUniformValue(m_entry_id, (float) d->entry); - } - - int m_timestamp_id; - int m_entry_id; - QByteArray m_vertex_code; - QByteArray m_fragment_code; - QOpenGLFunctions* glFuncs; -}; - -void fillUniformArrayFromImage(float* array, const QImage& img, int size) -{ - if (img.isNull()){ - for (int i=0; i QtQuick.Particles2::ImageParticle::sprites - - The sprite or sprites used to draw this particle. - - Note that the sprite image will be scaled to a square based on the size of - the particle being rendered. -*/ -/*! - \qmlproperty url QtQuick.Particles2::ImageParticle::colorTable - - An image whose color will be used as a 1D texture to determine color over life. E.g. when - the particle is halfway through its lifetime, it will have the color specified halfway - across the image. - - This color is blended with the color property and the color of the source image. -*/ -/*! - \qmlproperty url QtQuick.Particles2::ImageParticle::sizeTable - - An image whose opacity will be used as a 1D texture to determine size over life. - - This property is expected to be removed shortly, in favor of custom easing curves to determine size over life. -*/ -/*! - \qmlproperty url QtQuick.Particles2::ImageParticle::opacityTable - - An image whose opacity will be used as a 1D texture to determine size over life. - - This property is expected to be removed shortly, in favor of custom easing curves to determine opacity over life. -*/ -/*! - \qmlproperty color QtQuick.Particles2::ImageParticle::color - - If a color is specified, the provided image will be colorized with it. - - Default is white (no change). -*/ -/*! - \qmlproperty real QtQuick.Particles2::ImageParticle::colorVariation - - This number represents the color variation applied to individual particles. - Setting colorVariation is the same as setting redVariation, greenVariation, - and blueVariation to the same number. - - Each channel can vary between particle by up to colorVariation from its usual color. - - Color is measured, per channel, from 0.0 to 1.0. - - Default is 0.0 -*/ -/*! - \qmlproperty real QtQuick.Particles2::ImageParticle::redVariation - The variation in the red color channel between particles. - - Color is measured, per channel, from 0.0 to 1.0. - - Default is 0.0 -*/ -/*! - \qmlproperty real QtQuick.Particles2::ImageParticle::greenVariation - The variation in the green color channel between particles. - - Color is measured, per channel, from 0.0 to 1.0. - - Default is 0.0 -*/ -/*! - \qmlproperty real QtQuick.Particles2::ImageParticle::blueVariation - The variation in the blue color channel between particles. - - Color is measured, per channel, from 0.0 to 1.0. - - Default is 0.0 -*/ -/*! - \qmlproperty real QtQuick.Particles2::ImageParticle::alpha - An alpha to be applied to the image. This value is multiplied by the value in - the image, and the value in the color property. - - Particles have additive blending, so lower alpha on single particles leads - to stronger effects when multiple particles overlap. - - Alpha is measured from 0.0 to 1.0. - - Default is 1.0 -*/ -/*! - \qmlproperty real QtQuick.Particles2::ImageParticle::alphaVariation - The variation in the alpha channel between particles. - - Alpha is measured from 0.0 to 1.0. - - Default is 0.0 -*/ -/*! - \qmlproperty real QtQuick.Particles2::ImageParticle::rotation - - If set the image will be rotated by this many degrees before it is drawn. - - The particle coordinates are not transformed. -*/ -/*! - \qmlproperty real QtQuick.Particles2::ImageParticle::rotationVariation - - If set the rotation of individual particles will vary by up to this much - between particles. - -*/ -/*! - \qmlproperty real QtQuick.Particles2::ImageParticle::rotationSpeed - - If set particles will rotate at this speed in degrees/second. -*/ -/*! - \qmlproperty real QtQuick.Particles2::ImageParticle::rotationSpeedVariation - - If set the rotationSpeed of individual particles will vary by up to this much - between particles. - -*/ -/*! - \qmlproperty bool QtQuick.Particles2::ImageParticle::autoRotation - - If set to true then a rotation will be applied on top of the particles rotation, so - that it faces the direction of travel. So to face away from the direction of travel, - set autoRotation to true and rotation to 180. - - Default is false -*/ -/*! - \qmlproperty StochasticDirection QtQuick.Particles2::ImageParticle::xVector - - Allows you to deform the particle image when drawn. The rectangular image will - be deformed so that the horizontal sides are in the shape of this vector instead - of (1,0). -*/ -/*! - \qmlproperty StochasticDirection QtQuick.Particles2::ImageParticle::yVector - - Allows you to deform the particle image when drawn. The rectangular image will - be deformed so that the vertical sides are in the shape of this vector instead - of (0,1). -*/ -/*! - \qmlproperty EntryEffect QtQuick.Particles2::ImageParticle::entryEffect - - This property provides basic and cheap entrance and exit effects for the particles. - For fine-grained control, see sizeTable and opacityTable. - - Acceptable values are - \list - \li ImageParticle.None: Particles just appear and disappear. - \li ImageParticle.Fade: Particles fade in from 0 opacity at the start of their life, and fade out to 0 at the end. - \li ImageParticle.Scale: Particles scale in from 0 size at the start of their life, and scale back to 0 at the end. - \endlist - - Default value is Fade. -*/ -/*! - \qmlproperty bool QtQuick.Particles2::ImageParticle::spritesInterpolate - - If set to true, sprite particles will interpolate between sprite frames each rendered frame, making - the sprites look smoother. - - Default is true. -*/ - -/*! - \qmlproperty Status QtQuick.Particles2::ImageParticle::status - - The status of loading the image. -*/ - - -QQuickImageParticle::QQuickImageParticle(QQuickItem* parent) - : QQuickParticlePainter(parent) - , m_image(0) - , m_colorTable(0) - , m_sizeTable(0) - , m_opacityTable(0) - , m_color_variation(0.0) - , m_rootNode(0) - , m_material(0) - , m_alphaVariation(0.0) - , m_alpha(1.0) - , m_redVariation(0.0) - , m_greenVariation(0.0) - , m_blueVariation(0.0) - , m_rotation(0) - , m_rotationVariation(0) - , m_rotationSpeed(0) - , m_rotationSpeedVariation(0) - , m_autoRotation(false) - , m_xVector(0) - , m_yVector(0) - , m_spriteEngine(0) - , m_spritesInterpolate(true) - , m_explicitColor(false) - , m_explicitRotation(false) - , m_explicitDeformation(false) - , m_explicitAnimation(false) - , m_bypassOptimizations(false) - , perfLevel(Unknown) - , m_lastLevel(Unknown) - , m_debugMode(false) - , m_entryEffect(Fade) - , m_buildingNodes(false) -{ - setFlag(ItemHasContents); -} - -QQuickImageParticle::~QQuickImageParticle() -{ -} - -QQmlListProperty QQuickImageParticle::sprites() -{ - return QQmlListProperty(this, &m_sprites, spriteAppend, spriteCount, spriteAt, spriteClear); -} - -void QQuickImageParticle::sceneGraphInvalidated() -{ - m_nodes.clear(); - m_rootNode = 0; - m_material = 0; -} - -void QQuickImageParticle::setImage(const QUrl &image) -{ - if (image.isEmpty()){ - if (m_image) { - delete m_image; - emit imageChanged(); - } - return; - } - - if (!m_image) - m_image = new ImageData; - if (image == m_image->source) - return; - m_image->source = image; - emit imageChanged(); - reset(); -} - - -void QQuickImageParticle::setColortable(const QUrl &table) -{ - if (table.isEmpty()){ - if (m_colorTable) { - delete m_colorTable; - emit colortableChanged(); - } - return; - } - - if (!m_colorTable) - m_colorTable = new ImageData; - if (table == m_colorTable->source) - return; - m_colorTable->source = table; - emit colortableChanged(); - reset(); -} - -void QQuickImageParticle::setSizetable(const QUrl &table) -{ - if (table.isEmpty()){ - if (m_sizeTable) { - delete m_sizeTable; - emit sizetableChanged(); - } - return; - } - - if (!m_sizeTable) - m_sizeTable = new ImageData; - if (table == m_sizeTable->source) - return; - m_sizeTable->source = table; - emit sizetableChanged(); - reset(); -} - -void QQuickImageParticle::setOpacitytable(const QUrl &table) -{ - if (table.isEmpty()){ - if (m_opacityTable) { - delete m_opacityTable; - emit opacitytableChanged(); - } - return; - } - - if (!m_opacityTable) - m_opacityTable = new ImageData; - if (table == m_opacityTable->source) - return; - m_opacityTable->source = table; - emit opacitytableChanged(); - reset(); -} - -void QQuickImageParticle::setColor(const QColor &color) -{ - if (color == m_color) - return; - m_color = color; - emit colorChanged(); - m_explicitColor = true; - if (perfLevel < Colored) - reset(); -} - -void QQuickImageParticle::setColorVariation(qreal var) -{ - if (var == m_color_variation) - return; - m_color_variation = var; - emit colorVariationChanged(); - m_explicitColor = true; - if (perfLevel < Colored) - reset(); -} - -void QQuickImageParticle::setAlphaVariation(qreal arg) -{ - if (m_alphaVariation != arg) { - m_alphaVariation = arg; - emit alphaVariationChanged(arg); - } - m_explicitColor = true; - if (perfLevel < Colored) - reset(); -} - -void QQuickImageParticle::setAlpha(qreal arg) -{ - if (m_alpha != arg) { - m_alpha = arg; - emit alphaChanged(arg); - } - m_explicitColor = true; - if (perfLevel < Colored) - reset(); -} - -void QQuickImageParticle::setRedVariation(qreal arg) -{ - if (m_redVariation != arg) { - m_redVariation = arg; - emit redVariationChanged(arg); - } - m_explicitColor = true; - if (perfLevel < Colored) - reset(); -} - -void QQuickImageParticle::setGreenVariation(qreal arg) -{ - if (m_greenVariation != arg) { - m_greenVariation = arg; - emit greenVariationChanged(arg); - } - m_explicitColor = true; - if (perfLevel < Colored) - reset(); -} - -void QQuickImageParticle::setBlueVariation(qreal arg) -{ - if (m_blueVariation != arg) { - m_blueVariation = arg; - emit blueVariationChanged(arg); - } - m_explicitColor = true; - if (perfLevel < Colored) - reset(); -} - -void QQuickImageParticle::setRotation(qreal arg) -{ - if (m_rotation != arg) { - m_rotation = arg; - emit rotationChanged(arg); - } - m_explicitRotation = true; - if (perfLevel < Deformable) - reset(); -} - -void QQuickImageParticle::setRotationVariation(qreal arg) -{ - if (m_rotationVariation != arg) { - m_rotationVariation = arg; - emit rotationVariationChanged(arg); - } - m_explicitRotation = true; - if (perfLevel < Deformable) - reset(); -} - -void QQuickImageParticle::setRotationSpeed(qreal arg) -{ - if (m_rotationSpeed != arg) { - m_rotationSpeed = arg; - emit rotationSpeedChanged(arg); - } - m_explicitRotation = true; - if (perfLevel < Deformable) - reset(); -} - -void QQuickImageParticle::setRotationSpeedVariation(qreal arg) -{ - if (m_rotationSpeedVariation != arg) { - m_rotationSpeedVariation = arg; - emit rotationSpeedVariationChanged(arg); - } - m_explicitRotation = true; - if (perfLevel < Deformable) - reset(); -} - -void QQuickImageParticle::setAutoRotation(bool arg) -{ - if (m_autoRotation != arg) { - m_autoRotation = arg; - emit autoRotationChanged(arg); - } - m_explicitRotation = true; - if (perfLevel < Deformable) - reset(); -} - -void QQuickImageParticle::setXVector(QQuickDirection* arg) -{ - if (m_xVector != arg) { - m_xVector = arg; - emit xVectorChanged(arg); - } - m_explicitDeformation = true; - if (perfLevel < Deformable) - reset(); -} - -void QQuickImageParticle::setYVector(QQuickDirection* arg) -{ - if (m_yVector != arg) { - m_yVector = arg; - emit yVectorChanged(arg); - } - m_explicitDeformation = true; - if (perfLevel < Deformable) - reset(); -} - -void QQuickImageParticle::setSpritesInterpolate(bool arg) -{ - if (m_spritesInterpolate != arg) { - m_spritesInterpolate = arg; - emit spritesInterpolateChanged(arg); - } -} - -void QQuickImageParticle::setBypassOptimizations(bool arg) -{ - if (m_bypassOptimizations != arg) { - m_bypassOptimizations = arg; - emit bypassOptimizationsChanged(arg); - } - if (perfLevel < 9999) - reset(); -} - -void QQuickImageParticle::setEntryEffect(EntryEffect arg) -{ - if (m_entryEffect != arg) { - m_entryEffect = arg; - if (m_material) - getState(m_material)->entry = (qreal) m_entryEffect; - emit entryEffectChanged(arg); - } -} - -void QQuickImageParticle::resetColor() -{ - m_explicitColor = false; - foreach (const QString &str, m_groups) - foreach (QQuickParticleData* d, m_system->groupData[m_system->groupIds[str]]->data) - if (d->colorOwner == this) - d->colorOwner = 0; - m_color = QColor(); - m_color_variation = 0.0f; - m_redVariation = 0.0f; - m_blueVariation = 0.0f; - m_greenVariation = 0.0f; - m_alpha = 1.0f; - m_alphaVariation = 0.0f; -} - -void QQuickImageParticle::resetRotation() -{ - m_explicitRotation = false; - foreach (const QString &str, m_groups) - foreach (QQuickParticleData* d, m_system->groupData[m_system->groupIds[str]]->data) - if (d->rotationOwner == this) - d->rotationOwner = 0; - m_rotation = 0; - m_rotationVariation = 0; - m_rotationSpeed = 0; - m_rotationSpeedVariation = 0; - m_autoRotation = false; -} - -void QQuickImageParticle::resetDeformation() -{ - m_explicitDeformation = false; - foreach (const QString &str, m_groups) - foreach (QQuickParticleData* d, m_system->groupData[m_system->groupIds[str]]->data) - if (d->deformationOwner == this) - d->deformationOwner = 0; - if (m_xVector) - delete m_xVector; - if (m_yVector) - delete m_yVector; - m_xVector = 0; - m_yVector = 0; -} - -void QQuickImageParticle::reset() -{ - QQuickParticlePainter::reset(); - m_pleaseReset = true; - update(); -} - -void QQuickImageParticle::createEngine() -{ - if (m_spriteEngine) - delete m_spriteEngine; - if (m_sprites.count()) { - m_spriteEngine = new QQuickSpriteEngine(m_sprites, this); - connect(m_spriteEngine, SIGNAL(stateChanged(int)), - this, SLOT(spriteAdvance(int)), Qt::DirectConnection); - m_explicitAnimation = true; - } else { - m_spriteEngine = 0; - m_explicitAnimation = false; - } - reset(); -} - -static QSGGeometry::Attribute SimpleParticle_Attributes[] = { - QSGGeometry::Attribute::create(0, 2, GL_FLOAT, true), // Position - QSGGeometry::Attribute::create(1, 4, GL_FLOAT), // Data - QSGGeometry::Attribute::create(2, 4, GL_FLOAT) // Vectors -}; - -static QSGGeometry::AttributeSet SimpleParticle_AttributeSet = -{ - 3, // Attribute Count - ( 2 + 4 + 4 ) * sizeof(float), - SimpleParticle_Attributes -}; - -static QSGGeometry::Attribute ColoredParticle_Attributes[] = { - QSGGeometry::Attribute::create(0, 2, GL_FLOAT, true), // Position - QSGGeometry::Attribute::create(1, 4, GL_FLOAT), // Data - QSGGeometry::Attribute::create(2, 4, GL_FLOAT), // Vectors - QSGGeometry::Attribute::create(3, 4, GL_UNSIGNED_BYTE), // Colors -}; - -static QSGGeometry::AttributeSet ColoredParticle_AttributeSet = -{ - 4, // Attribute Count - ( 2 + 4 + 4 ) * sizeof(float) + 4 * sizeof(uchar), - ColoredParticle_Attributes -}; - -static QSGGeometry::Attribute DeformableParticle_Attributes[] = { - QSGGeometry::Attribute::create(0, 4, GL_FLOAT), // Position & TexCoord - QSGGeometry::Attribute::create(1, 4, GL_FLOAT), // Data - QSGGeometry::Attribute::create(2, 4, GL_FLOAT), // Vectors - QSGGeometry::Attribute::create(3, 4, GL_UNSIGNED_BYTE), // Colors - QSGGeometry::Attribute::create(4, 4, GL_FLOAT), // DeformationVectors - QSGGeometry::Attribute::create(5, 3, GL_FLOAT), // Rotation -}; - -static QSGGeometry::AttributeSet DeformableParticle_AttributeSet = -{ - 6, // Attribute Count - (4 + 4 + 4 + 4 + 3) * sizeof(float) + 4 * sizeof(uchar), - DeformableParticle_Attributes -}; - -static QSGGeometry::Attribute SpriteParticle_Attributes[] = { - QSGGeometry::Attribute::create(0, 4, GL_FLOAT), // Position & TexCoord - QSGGeometry::Attribute::create(1, 4, GL_FLOAT), // Data - QSGGeometry::Attribute::create(2, 4, GL_FLOAT), // Vectors - QSGGeometry::Attribute::create(3, 4, GL_UNSIGNED_BYTE), // Colors - QSGGeometry::Attribute::create(4, 4, GL_FLOAT), // DeformationVectors - QSGGeometry::Attribute::create(5, 3, GL_FLOAT), // Rotation - QSGGeometry::Attribute::create(6, 3, GL_FLOAT), // Anim Data - QSGGeometry::Attribute::create(7, 4, GL_FLOAT) // Anim Pos -}; - -static QSGGeometry::AttributeSet SpriteParticle_AttributeSet = -{ - 8, // Attribute Count - (4 + 4 + 4 + 4 + 3 + 3 + 4) * sizeof(float) + 4 * sizeof(uchar), - SpriteParticle_Attributes -}; - -void QQuickImageParticle::clearShadows() -{ - foreach (const QVector data, m_shadowData) - qDeleteAll(data); - m_shadowData.clear(); -} - -//Only call if you need to, may initialize the whole array first time -QQuickParticleData* QQuickImageParticle::getShadowDatum(QQuickParticleData* datum) -{ - //Will return datum if the datum is a sentinel or uninitialized, to centralize that one check - if (datum->systemIndex == -1) - return datum; - QQuickParticleGroupData* gd = m_system->groupData[datum->group]; - if (!m_shadowData.contains(datum->group)) { - QVector data; - for (int i=0; isize(); i++){ - QQuickParticleData* datum = new QQuickParticleData(m_system); - *datum = *(gd->data[i]); - data << datum; - } - m_shadowData.insert(datum->group, data); - } - //### If dynamic resize is added, remember to potentially resize the shadow data on out-of-bounds access request - - return m_shadowData[datum->group][datum->index]; -} - -bool QQuickImageParticle::loadingSomething() -{ - return (m_image && m_image->pix.isLoading()) - || (m_colorTable && m_colorTable->pix.isLoading()) - || (m_sizeTable && m_sizeTable->pix.isLoading()) - || (m_opacityTable && m_opacityTable->pix.isLoading()) - || (m_spriteEngine && m_spriteEngine->isLoading()); -} - -void QQuickImageParticle::buildParticleNodes()//Starts async parts, like loading images. -{ - if (m_rootNode || loadingSomething()) - return; - - if (!m_buildingNodes) { - if (m_image) {//ImageData created on setSource - m_image->pix.clear(this); - m_image->pix.load(qmlEngine(this), m_image->source); - } - - if (m_spriteEngine) - m_spriteEngine->startAssemblingImage(); - - if (m_colorTable) - m_colorTable->pix.load(qmlEngine(this), m_colorTable->source); - - if (m_sizeTable) - m_sizeTable->pix.load(qmlEngine(this), m_sizeTable->source); - - if (m_opacityTable) - m_opacityTable->pix.load(qmlEngine(this), m_opacityTable->source); - - m_buildingNodes = true; - if (loadingSomething()) - return; - } - finishBuildParticleNodes(); -} - -void QQuickImageParticle::finishBuildParticleNodes() -{ - m_buildingNodes = false; -#ifdef QT_OPENGL_ES_2 - if (m_count * 4 > 0xffff) { - printf("ImageParticle: Too many particles - maximum 16,000 per ImageParticle.\n");//ES 2 vertex count limit is ushort - return; - } -#endif - - if (count() <= 0) - return; - - m_debugMode = m_system->m_debugMode; - - if (m_sprites.count() || m_bypassOptimizations) { - perfLevel = Sprites; - } else if (m_colorTable || m_sizeTable || m_opacityTable) { - perfLevel = Tabled; - } else if (m_autoRotation || m_rotation || m_rotationVariation - || m_rotationSpeed || m_rotationSpeedVariation - || m_xVector || m_yVector) { - perfLevel = Deformable; - } else if (m_alphaVariation || m_alpha != 1.0 || m_color.isValid() || m_color_variation - || m_redVariation || m_blueVariation || m_greenVariation) { - perfLevel = Colored; - } else { - perfLevel = Simple; - } - - foreach (const QString &str, m_groups){//For sharing higher levels, need to have highest used so it renders - int gIdx = m_system->groupIds[str]; - foreach (QQuickParticlePainter* p, m_system->groupData[gIdx]->painters){ - QQuickImageParticle* other = qobject_cast(p); - if (other){ - if (other->perfLevel > perfLevel) { - if (other->perfLevel >= Tabled){//Deformable is the highest level needed for this, anything higher isn't shared (or requires your own sprite) - if (perfLevel < Deformable) - perfLevel = Deformable; - } else { - perfLevel = other->perfLevel; - } - } else if (other->perfLevel < perfLevel) { - other->reset(); - } - } - } - } -#ifdef Q_OS_WIN - if (perfLevel < Deformable) //QTBUG-24540 , point sprite 'extension' isn't working on windows. - perfLevel = Deformable; -#endif - - if (perfLevel >= Colored && !m_color.isValid()) - m_color = QColor(Qt::white);//Hidden default, but different from unset - - clearShadows(); - if (m_material) - m_material = 0; - - //Setup material - QImage colortable; - QImage sizetable; - QImage opacitytable; - QImage image; - bool imageLoaded = false; - switch (perfLevel) {//Fallthrough intended - case Sprites: - if (!m_spriteEngine) { - qWarning() << "ImageParticle: No sprite engine..."; - //Sprite performance mode with static image is supported, but not advised - //Note that in this case it always uses shadow data - } else { - image = m_spriteEngine->assembledImage(); - if (image.isNull())//Warning is printed in engine - return; - imageLoaded = true; - } - m_material = SpriteMaterial::createMaterial(); - if (imageLoaded) - getState(m_material)->texture = QSGPlainTexture::fromImage(image); - getState(m_material)->animSheetSize = QSizeF(image.size()); - if (m_spriteEngine) - m_spriteEngine->setCount(m_count); - case Tabled: - if (!m_material) - m_material = TabledMaterial::createMaterial(); - - if (m_colorTable) { - if (m_colorTable->pix.isReady()) - colortable = m_colorTable->pix.image(); - else - qmlInfo(this) << "Error loading color table: " << m_colorTable->pix.error(); - } - - if (m_sizeTable) { - if (m_sizeTable->pix.isReady()) - sizetable = m_sizeTable->pix.image(); - else - qmlInfo(this) << "Error loading size table: " << m_sizeTable->pix.error(); - } - - if (m_opacityTable) { - if (m_opacityTable->pix.isReady()) - opacitytable = m_opacityTable->pix.image(); - else - qmlInfo(this) << "Error loading opacity table: " << m_opacityTable->pix.error(); - } - - if (colortable.isNull()){//###Goes through image just for this - colortable = QImage(1,1,QImage::Format_ARGB32_Premultiplied); - colortable.fill(Qt::white); - } - getState(m_material)->colorTable = QSGPlainTexture::fromImage(colortable); - fillUniformArrayFromImage(getState(m_material)->sizeTable, sizetable, UNIFORM_ARRAY_SIZE); - fillUniformArrayFromImage(getState(m_material)->opacityTable, opacitytable, UNIFORM_ARRAY_SIZE); - case Deformable: - if (!m_material) - m_material = DeformableMaterial::createMaterial(); - case Colored: - if (!m_material) - m_material = ColoredMaterial::createMaterial(); - default://Also Simple - if (!m_material) - m_material = SimpleMaterial::createMaterial(); - if (!imageLoaded) { - if (!m_image->pix.isReady()) { - qmlInfo(this) << m_image->pix.error(); - delete m_material; - return; - } - //getState(m_material)->texture //TODO: Shouldn't this be better? But not crash? - // = QQuickItemPrivate::get(this)->sceneGraphContext()->textureForFactory(m_imagePix.textureFactory()); - getState(m_material)->texture = QSGPlainTexture::fromImage(m_image->pix.image()); - } - getState(m_material)->texture->setFiltering(QSGTexture::Linear); - getState(m_material)->entry = (qreal) m_entryEffect; - m_material->setFlag(QSGMaterial::Blending); - } - - m_nodes.clear(); - foreach (const QString &str, m_groups){ - int gIdx = m_system->groupIds[str]; - int count = m_system->groupData[gIdx]->size(); - QSGGeometryNode* node = new QSGGeometryNode(); - node->setMaterial(m_material); - node->markDirty(QSGNode::DirtyMaterial); - - m_nodes.insert(gIdx, node); - m_idxStarts.insert(gIdx, m_lastIdxStart); - m_startsIdx.append(qMakePair(m_lastIdxStart, gIdx)); - m_lastIdxStart += count; - - //Create Particle Geometry - int vCount = count * 4; - int iCount = count * 6; - - QSGGeometry *g; - if (perfLevel == Sprites) - g = new QSGGeometry(SpriteParticle_AttributeSet, vCount, iCount); - else if (perfLevel == Tabled) - g = new QSGGeometry(DeformableParticle_AttributeSet, vCount, iCount); - else if (perfLevel == Deformable) - g = new QSGGeometry(DeformableParticle_AttributeSet, vCount, iCount); - else if (perfLevel == Colored) - g = new QSGGeometry(ColoredParticle_AttributeSet, count, 0); - else //Simple - g = new QSGGeometry(SimpleParticle_AttributeSet, count, 0); - - node->setGeometry(g); - if (perfLevel <= Colored){ - g->setDrawingMode(GL_POINTS); - if (m_debugMode){ - GLfloat pointSizeRange[2]; - glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, pointSizeRange); - qDebug() << "Using point sprites, GL_ALIASED_POINT_SIZE_RANGE " <setDrawingMode(GL_TRIANGLES); - - for (int p=0; p < count; ++p) - commit(gIdx, p);//commit sets geometry for the node, has its own perfLevel switch - - if (perfLevel == Sprites) - initTexCoords((SpriteVertex*)g->vertexData(), vCount); - else if (perfLevel == Tabled) - initTexCoords((DeformableVertex*)g->vertexData(), vCount); - else if (perfLevel == Deformable) - initTexCoords((DeformableVertex*)g->vertexData(), vCount); - - if (perfLevel > Colored){ - quint16 *indices = g->indexDataAsUShort(); - for (int i=0; i < count; ++i) { - int o = i * 4; - indices[0] = o; - indices[1] = o + 1; - indices[2] = o + 2; - indices[3] = o + 1; - indices[4] = o + 3; - indices[5] = o + 2; - indices += 6; - } - } - } - - if (perfLevel == Sprites) - spritesUpdate();//Gives all vertexes the initial sprite data, then maintained per frame - - foreach (QSGGeometryNode* node, m_nodes){ - if (node == *(m_nodes.begin())) - node->setFlag(QSGGeometryNode::OwnsMaterial);//Root node owns the material for memory management purposes - else - (*(m_nodes.begin()))->appendChildNode(node); - } - - m_rootNode = *(m_nodes.begin()); - update(); -} - -QSGNode *QQuickImageParticle::updatePaintNode(QSGNode *, UpdatePaintNodeData *) -{ - if (m_pleaseReset){ - m_lastLevel = perfLevel; - - delete m_rootNode;//Automatically deletes children, and SG manages material lifetime - m_rootNode = 0; - m_nodes.clear(); - - m_idxStarts.clear(); - m_startsIdx.clear(); - m_lastIdxStart = 0; - - m_material = 0; - - m_pleaseReset = false; - m_buildingNodes = false;//Cancel a part-way build - } - - if (m_system && m_system->isRunning() && !m_system->isPaused()){ - prepareNextFrame(); - if (m_rootNode) { - update(); - foreach (QSGGeometryNode* node, m_nodes) - node->markDirty(QSGNode::DirtyGeometry); - } else if (m_buildingNodes) { - update();//To call prepareNextFrame() again from the renderThread - } - } - - return m_rootNode; -} - -void QQuickImageParticle::prepareNextFrame() -{ - if (m_rootNode == 0){//TODO: Staggered loading (as emitted) - buildParticleNodes(); - if (m_debugMode) { - qDebug() << "QQuickImageParticle Feature level: " << perfLevel; - qDebug() << "QQuickImageParticle Nodes: "; - int count = 0; - foreach (int i, m_nodes.keys()) { - qDebug() << "Group " << i << " (" << m_system->groupData[i]->size() << " particles)"; - count += m_system->groupData[i]->size(); - } - qDebug() << "Total count: " << count; - } - if (m_rootNode == 0) - return; - } - qint64 timeStamp = m_system->systemSync(this); - - qreal time = timeStamp / 1000.; - - switch (perfLevel){//Fall-through intended - case Sprites: - //Advance State - if (m_spriteEngine) - m_spriteEngine->updateSprites(timeStamp);//fires signals if anim changed - spritesUpdate(time); - case Tabled: - case Deformable: - case Colored: - case Simple: - default: //Also Simple - getState(m_material)->timestamp = time; - break; - } - foreach (QSGGeometryNode* node, m_nodes) - node->markDirty(QSGNode::DirtyMaterial); -} - -void QQuickImageParticle::spritesUpdate(qreal time) -{ - // Sprite progression handled CPU side, so as to have per-frame control. - foreach (const QString &str, m_groups) { - int gIdx = m_system->groupIds[str]; - foreach (QQuickParticleData* mainDatum, m_system->groupData[gIdx]->data) { - QSGGeometryNode *node = m_nodes[gIdx]; - if (!node) - continue; - //TODO: Interpolate between two different animations if it's going to transition next frame - // This is particularly important for cut-up sprites. - QQuickParticleData* datum = (mainDatum->animationOwner == this ? mainDatum : getShadowDatum(mainDatum)); - int spriteIdx = 0; - for (int i = 0; iindex; - break; - } - } - - double frameAt; - qreal progress = 0; - - if (datum->frameDuration > 0) { - qreal frame = (time - datum->animT)/(datum->frameDuration / 1000.0); - frame = qBound((qreal)0.0, frame, (qreal)((qreal)datum->frameCount - 1.0));//Stop at count-1 frames until we have between anim interpolation - if (m_spritesInterpolate) - progress = modf(frame,&frameAt); - else - modf(frame,&frameAt); - } else { - datum->frameAt++; - if (datum->frameAt >= datum->frameCount){ - datum->frameAt = 0; - m_spriteEngine->advance(spriteIdx); - } - frameAt = datum->frameAt; - } - if (m_spriteEngine->sprite(spriteIdx)->reverse())//### Store this in datum too? - frameAt = (datum->frameCount - 1) - frameAt; - QSizeF sheetSize = getState(m_material)->animSheetSize; - qreal y = datum->animY / sheetSize.height(); - qreal w = datum->animWidth / sheetSize.width(); - qreal h = datum->animHeight / sheetSize.height(); - qreal x1 = datum->animX / sheetSize.width(); - x1 += frameAt * w; - qreal x2 = x1; - if (frameAt < (datum->frameCount-1)) - x2 += w; - - node->setFlag(QSGNode::OwnsGeometry, false); - SpriteVertex *spriteVertices = (SpriteVertex *) node->geometry()->vertexData(); - spriteVertices += datum->index*4; - for (int i=0; i<4; i++) { - spriteVertices[i].animX1 = x1; - spriteVertices[i].animY1 = y; - spriteVertices[i].animX2 = x2; - spriteVertices[i].animY2 = y; - spriteVertices[i].animW = w; - spriteVertices[i].animH = h; - spriteVertices[i].animProgress = progress; - } - node->setFlag(QSGNode::OwnsGeometry, true); - } - } -} - -void QQuickImageParticle::spriteAdvance(int spriteIdx) -{ - if (!m_startsIdx.count())//Probably overly defensive - return; - - int gIdx = -1; - int i; - for (i = 0; igroupData[gIdx]->data[pIdx]; - QQuickParticleData* datum = (mainDatum->animationOwner == this ? mainDatum : getShadowDatum(mainDatum)); - - datum->animIdx = m_spriteEngine->spriteState(spriteIdx); - datum->animT = m_spriteEngine->spriteStart(spriteIdx)/1000.0; - datum->frameCount = m_spriteEngine->spriteFrames(spriteIdx); - datum->frameDuration = m_spriteEngine->spriteDuration(spriteIdx) / datum->frameCount; - datum->animX = m_spriteEngine->spriteX(spriteIdx); - datum->animY = m_spriteEngine->spriteY(spriteIdx); - datum->animWidth = m_spriteEngine->spriteWidth(spriteIdx); - datum->animHeight = m_spriteEngine->spriteHeight(spriteIdx); -} - -void QQuickImageParticle::reloadColor(const Color4ub &c, QQuickParticleData* d) -{ - d->color = c; - //TODO: get index for reload - or make function take an index -} - -void QQuickImageParticle::initialize(int gIdx, int pIdx) -{ - Color4ub color; - QQuickParticleData* datum = m_system->groupData[gIdx]->data[pIdx]; - qreal redVariation = m_color_variation + m_redVariation; - qreal greenVariation = m_color_variation + m_greenVariation; - qreal blueVariation = m_color_variation + m_blueVariation; - int spriteIdx = 0; - if (m_spriteEngine) { - spriteIdx = m_idxStarts[gIdx] + datum->index; - if (spriteIdx >= m_spriteEngine->count()) - m_spriteEngine->setCount(spriteIdx+1); - } - - float rotation; - float rotationSpeed; - float autoRotate; - switch (perfLevel){//Fall-through is intended on all of them - case Sprites: - // Initial Sprite State - if (m_explicitAnimation && m_spriteEngine){ - if (!datum->animationOwner) - datum->animationOwner = this; - QQuickParticleData* writeTo = (datum->animationOwner == this ? datum : getShadowDatum(datum)); - writeTo->animT = writeTo->t; - //writeTo->animInterpolate = m_spritesInterpolate; - if (m_spriteEngine){ - m_spriteEngine->start(spriteIdx); - writeTo->frameCount = m_spriteEngine->spriteFrames(spriteIdx); - writeTo->frameDuration = m_spriteEngine->spriteDuration(spriteIdx) / writeTo->frameCount; - writeTo->animIdx = 0;//Always starts at 0 - writeTo->frameAt = -1; - writeTo->animX = m_spriteEngine->spriteX(spriteIdx); - writeTo->animY = m_spriteEngine->spriteY(spriteIdx); - writeTo->animWidth = m_spriteEngine->spriteWidth(spriteIdx); - writeTo->animHeight = m_spriteEngine->spriteHeight(spriteIdx); - } - } else { - QQuickParticleData* writeTo = getShadowDatum(datum); - writeTo->animT = datum->t; - writeTo->frameCount = 1; - writeTo->frameDuration = 60000000.0; - writeTo->frameAt = -1; - writeTo->animIdx = 0; - writeTo->animT = 0; - writeTo->animX = writeTo->animY = 0; - writeTo->animWidth = getState(m_material)->animSheetSize.width(); - writeTo->animHeight = getState(m_material)->animSheetSize.height(); - } - case Tabled: - case Deformable: - //Initial Rotation - if (m_explicitDeformation){ - if (!datum->deformationOwner) - datum->deformationOwner = this; - if (m_xVector){ - const QPointF &ret = m_xVector->sample(QPointF(datum->x, datum->y)); - if (datum->deformationOwner == this) { - datum->xx = ret.x(); - datum->xy = ret.y(); - } else { - getShadowDatum(datum)->xx = ret.x(); - getShadowDatum(datum)->xy = ret.y(); - } - } - if (m_yVector){ - const QPointF &ret = m_yVector->sample(QPointF(datum->x, datum->y)); - if (datum->deformationOwner == this) { - datum->yx = ret.x(); - datum->yy = ret.y(); - } else { - getShadowDatum(datum)->yx = ret.x(); - getShadowDatum(datum)->yy = ret.y(); - } - } - } - - if (m_explicitRotation){ - if (!datum->rotationOwner) - datum->rotationOwner = this; - rotation = - (m_rotation + (m_rotationVariation - 2*((qreal)rand()/RAND_MAX)*m_rotationVariation) ) * CONV; - rotationSpeed = - (m_rotationSpeed + (m_rotationSpeedVariation - 2*((qreal)rand()/RAND_MAX)*m_rotationSpeedVariation) ) * CONV; - autoRotate = m_autoRotation?1.0:0.0; - if (datum->rotationOwner == this) { - datum->rotation = rotation; - datum->rotationSpeed = rotationSpeed; - datum->autoRotate = autoRotate; - } else { - getShadowDatum(datum)->rotation = rotation; - getShadowDatum(datum)->rotationSpeed = rotationSpeed; - getShadowDatum(datum)->autoRotate = autoRotate; - } - } - case Colored: - //Color initialization - // Particle color - if (m_explicitColor) { - if (!datum->colorOwner) - datum->colorOwner = this; - color.r = m_color.red() * (1 - redVariation) + rand() % 256 * redVariation; - color.g = m_color.green() * (1 - greenVariation) + rand() % 256 * greenVariation; - color.b = m_color.blue() * (1 - blueVariation) + rand() % 256 * blueVariation; - color.a = m_alpha * m_color.alpha() * (1 - m_alphaVariation) + rand() % 256 * m_alphaVariation; - if (datum->colorOwner == this) - datum->color = color; - else - getShadowDatum(datum)->color = color; - } - default: - break; - } -} - -void QQuickImageParticle::commit(int gIdx, int pIdx) -{ - if (m_pleaseReset) - return; - QSGGeometryNode *node = m_nodes[gIdx]; - if (!node) - return; - QQuickParticleData* datum = m_system->groupData[gIdx]->data[pIdx]; - node->setFlag(QSGNode::OwnsGeometry, false); - SpriteVertex *spriteVertices = (SpriteVertex *) node->geometry()->vertexData(); - DeformableVertex *deformableVertices = (DeformableVertex *) node->geometry()->vertexData(); - ColoredVertex *coloredVertices = (ColoredVertex *) node->geometry()->vertexData(); - SimpleVertex *simpleVertices = (SimpleVertex *) node->geometry()->vertexData(); - switch (perfLevel){//No automatic fall through intended on this one - case Sprites: - spriteVertices += pIdx*4; - for (int i=0; i<4; i++){ - spriteVertices[i].x = datum->x - m_systemOffset.x(); - spriteVertices[i].y = datum->y - m_systemOffset.y(); - spriteVertices[i].t = datum->t; - spriteVertices[i].lifeSpan = datum->lifeSpan; - spriteVertices[i].size = datum->size; - spriteVertices[i].endSize = datum->endSize; - spriteVertices[i].vx = datum->vx; - spriteVertices[i].vy = datum->vy; - spriteVertices[i].ax = datum->ax; - spriteVertices[i].ay = datum->ay; - if (m_explicitDeformation && datum->deformationOwner != this) { - QQuickParticleData* shadow = getShadowDatum(datum); - spriteVertices[i].xx = shadow->xx; - spriteVertices[i].xy = shadow->xy; - spriteVertices[i].yx = shadow->yx; - spriteVertices[i].yy = shadow->yy; - } else { - spriteVertices[i].xx = datum->xx; - spriteVertices[i].xy = datum->xy; - spriteVertices[i].yx = datum->yx; - spriteVertices[i].yy = datum->yy; - } - if (m_explicitRotation && datum->rotationOwner != this) { - QQuickParticleData* shadow = getShadowDatum(datum); - spriteVertices[i].rotation = shadow->rotation; - spriteVertices[i].rotationSpeed = shadow->rotationSpeed; - spriteVertices[i].autoRotate = shadow->autoRotate; - } else { - spriteVertices[i].rotation = datum->rotation; - spriteVertices[i].rotationSpeed = datum->rotationSpeed; - spriteVertices[i].autoRotate = datum->autoRotate; - } - //Sprite-related vertices updated per-frame in spritesUpdate(), not on demand - if (m_explicitColor && datum->colorOwner != this) { - QQuickParticleData* shadow = getShadowDatum(datum); - spriteVertices[i].color.r = shadow->color.r; - spriteVertices[i].color.g = shadow->color.g; - spriteVertices[i].color.b = shadow->color.b; - spriteVertices[i].color.a = shadow->color.a; - } else { - spriteVertices[i].color.r = datum->color.r; - spriteVertices[i].color.g = datum->color.g; - spriteVertices[i].color.b = datum->color.b; - spriteVertices[i].color.a = datum->color.a; - } - } - break; - case Tabled: //Fall through until it has its own vertex class - case Deformable: - deformableVertices += pIdx*4; - for (int i=0; i<4; i++){ - deformableVertices[i].x = datum->x - m_systemOffset.x(); - deformableVertices[i].y = datum->y - m_systemOffset.y(); - deformableVertices[i].t = datum->t; - deformableVertices[i].lifeSpan = datum->lifeSpan; - deformableVertices[i].size = datum->size; - deformableVertices[i].endSize = datum->endSize; - deformableVertices[i].vx = datum->vx; - deformableVertices[i].vy = datum->vy; - deformableVertices[i].ax = datum->ax; - deformableVertices[i].ay = datum->ay; - if (m_explicitDeformation && datum->deformationOwner != this) { - QQuickParticleData* shadow = getShadowDatum(datum); - deformableVertices[i].xx = shadow->xx; - deformableVertices[i].xy = shadow->xy; - deformableVertices[i].yx = shadow->yx; - deformableVertices[i].yy = shadow->yy; - } else { - deformableVertices[i].xx = datum->xx; - deformableVertices[i].xy = datum->xy; - deformableVertices[i].yx = datum->yx; - deformableVertices[i].yy = datum->yy; - } - if (m_explicitRotation && datum->rotationOwner != this) { - QQuickParticleData* shadow = getShadowDatum(datum); - deformableVertices[i].rotation = shadow->rotation; - deformableVertices[i].rotationSpeed = shadow->rotationSpeed; - deformableVertices[i].autoRotate = shadow->autoRotate; - } else { - deformableVertices[i].rotation = datum->rotation; - deformableVertices[i].rotationSpeed = datum->rotationSpeed; - deformableVertices[i].autoRotate = datum->autoRotate; - } - if (m_explicitColor && datum->colorOwner != this) { - QQuickParticleData* shadow = getShadowDatum(datum); - deformableVertices[i].color.r = shadow->color.r; - deformableVertices[i].color.g = shadow->color.g; - deformableVertices[i].color.b = shadow->color.b; - deformableVertices[i].color.a = shadow->color.a; - } else { - deformableVertices[i].color.r = datum->color.r; - deformableVertices[i].color.g = datum->color.g; - deformableVertices[i].color.b = datum->color.b; - deformableVertices[i].color.a = datum->color.a; - } - } - break; - case Colored: - coloredVertices += pIdx*1; - for (int i=0; i<1; i++){ - coloredVertices[i].x = datum->x - m_systemOffset.x(); - coloredVertices[i].y = datum->y - m_systemOffset.y(); - coloredVertices[i].t = datum->t; - coloredVertices[i].lifeSpan = datum->lifeSpan; - coloredVertices[i].size = datum->size; - coloredVertices[i].endSize = datum->endSize; - coloredVertices[i].vx = datum->vx; - coloredVertices[i].vy = datum->vy; - coloredVertices[i].ax = datum->ax; - coloredVertices[i].ay = datum->ay; - if (m_explicitColor && datum->colorOwner != this) { - QQuickParticleData* shadow = getShadowDatum(datum); - coloredVertices[i].color.r = shadow->color.r; - coloredVertices[i].color.g = shadow->color.g; - coloredVertices[i].color.b = shadow->color.b; - coloredVertices[i].color.a = shadow->color.a; - } else { - coloredVertices[i].color.r = datum->color.r; - coloredVertices[i].color.g = datum->color.g; - coloredVertices[i].color.b = datum->color.b; - coloredVertices[i].color.a = datum->color.a; - } - } - break; - case Simple: - simpleVertices += pIdx*1; - for (int i=0; i<1; i++){ - simpleVertices[i].x = datum->x - m_systemOffset.x(); - simpleVertices[i].y = datum->y - m_systemOffset.y(); - simpleVertices[i].t = datum->t; - simpleVertices[i].lifeSpan = datum->lifeSpan; - simpleVertices[i].size = datum->size; - simpleVertices[i].endSize = datum->endSize; - simpleVertices[i].vx = datum->vx; - simpleVertices[i].vy = datum->vy; - simpleVertices[i].ax = datum->ax; - simpleVertices[i].ay = datum->ay; - } - break; - default: - break; - } - - node->setFlag(QSGNode::OwnsGeometry, true); -} - - - -QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquickimageparticle_p.h qt5-declarative-0.1~git20120423/src/quick/particles/qquickimageparticle_p.h --- qt5-declarative-0.1~git20120402/src/quick/particles/qquickimageparticle_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquickimageparticle_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,446 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef ULTRAPARTICLE_H -#define ULTRAPARTICLE_H -#include "qquickparticlepainter_p.h" -#include "qquickdirection_p.h" -#include -#include -#include -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -class ImageMaterialData; -class QSGGeometryNode; - -class QQuickSprite; -class QQuickStochasticEngine; - -struct SimpleVertex { - float x; - float y; - float t; - float lifeSpan; - float size; - float endSize; - float vx; - float vy; - float ax; - float ay; -}; - -struct ColoredVertex { - float x; - float y; - float t; - float lifeSpan; - float size; - float endSize; - float vx; - float vy; - float ax; - float ay; - Color4ub color; -}; - -struct DeformableVertex { - float x; - float y; - float tx; - float ty; - float t; - float lifeSpan; - float size; - float endSize; - float vx; - float vy; - float ax; - float ay; - Color4ub color; - float xx; - float xy; - float yx; - float yy; - float rotation; - float rotationSpeed; - float autoRotate;//Assumed that GPUs prefer floats to bools -}; - -struct SpriteVertex { - float x; - float y; - float tx; - float ty; - float t; - float lifeSpan; - float size; - float endSize; - float vx; - float vy; - float ax; - float ay; - Color4ub color; - float xx; - float xy; - float yx; - float yy; - float rotation; - float rotationSpeed; - float autoRotate;//Assumed that GPUs prefer floats to bools - float animW; - float animH; - float animProgress; - float animX1; - float animY1; - float animX2; - float animY2; -}; - -template -struct Vertices { - Vertex v1; - Vertex v2; - Vertex v3; - Vertex v4; -}; - -class QQuickImageParticle : public QQuickParticlePainter -{ - Q_OBJECT - Q_PROPERTY(QUrl source READ image WRITE setImage NOTIFY imageChanged) - Q_PROPERTY(QQmlListProperty sprites READ sprites) - Q_PROPERTY(Status status READ status NOTIFY statusChanged) - //### Is it worth having progress like Image has? - //Q_PROPERTY(qreal progress READ progress NOTIFY progressChanged) - - Q_PROPERTY(QUrl colorTable READ colortable WRITE setColortable NOTIFY colortableChanged) - Q_PROPERTY(QUrl sizeTable READ sizetable WRITE setSizetable NOTIFY sizetableChanged) - Q_PROPERTY(QUrl opacityTable READ opacitytable WRITE setOpacitytable NOTIFY opacitytableChanged) - - //###Now just colorize - add a flag for 'solid' color particles(where the img is just a mask?)? - Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged RESET resetColor) - //Stacks (added) with individual colorVariations - Q_PROPERTY(qreal colorVariation READ colorVariation WRITE setColorVariation NOTIFY colorVariationChanged RESET resetColor) - Q_PROPERTY(qreal redVariation READ redVariation WRITE setRedVariation NOTIFY redVariationChanged RESET resetColor) - Q_PROPERTY(qreal greenVariation READ greenVariation WRITE setGreenVariation NOTIFY greenVariationChanged RESET resetColor) - Q_PROPERTY(qreal blueVariation READ blueVariation WRITE setBlueVariation NOTIFY blueVariationChanged RESET resetColor) - //Stacks (multiplies) with the Alpha in the color, mostly here so you can use svg color names (which have full alpha) - Q_PROPERTY(qreal alpha READ alpha WRITE setAlpha NOTIFY alphaChanged RESET resetColor) - Q_PROPERTY(qreal alphaVariation READ alphaVariation WRITE setAlphaVariation NOTIFY alphaVariationChanged RESET resetColor) - - Q_PROPERTY(qreal rotation READ rotation WRITE setRotation NOTIFY rotationChanged RESET resetRotation) - Q_PROPERTY(qreal rotationVariation READ rotationVariation WRITE setRotationVariation NOTIFY rotationVariationChanged RESET resetRotation) - Q_PROPERTY(qreal rotationSpeed READ rotationSpeed WRITE setRotationSpeed NOTIFY rotationSpeedChanged RESET resetRotation) - Q_PROPERTY(qreal rotationSpeedVariation READ rotationSpeedVariation WRITE setRotationSpeedVariation NOTIFY rotationSpeedVariationChanged RESET resetRotation) - //If true, then will face the direction of motion. Stacks with rotation, e.g. setting rotation - //to 180 will lead to facing away from the direction of motion - Q_PROPERTY(bool autoRotation READ autoRotation WRITE setAutoRotation NOTIFY autoRotationChanged RESET resetRotation) - - //xVector is the vector from the top-left point to the top-right point, and is multiplied by current size - Q_PROPERTY(QQuickDirection* xVector READ xVector WRITE setXVector NOTIFY xVectorChanged RESET resetDeformation) - //yVector is the same, but top-left to bottom-left. The particle is always a parallelogram. - Q_PROPERTY(QQuickDirection* yVector READ yVector WRITE setYVector NOTIFY yVectorChanged RESET resetDeformation) - Q_PROPERTY(bool spritesInterpolate READ spritesInterpolate WRITE setSpritesInterpolate NOTIFY spritesInterpolateChanged) - - Q_PROPERTY(EntryEffect entryEffect READ entryEffect WRITE setEntryEffect NOTIFY entryEffectChanged) - Q_ENUMS(EntryEffect) - Q_ENUMS(Status) -public: - explicit QQuickImageParticle(QQuickItem *parent = 0); - virtual ~QQuickImageParticle(); - - enum Status { Null, Ready, Loading, Error }; - - QQmlListProperty sprites(); - QQuickStochasticEngine* spriteEngine() {return m_spriteEngine;} - - enum EntryEffect { - None = 0, - Fade = 1, - Scale = 2 - }; - - enum PerformanceLevel{//TODO: Expose? - Unknown = 0, - Simple, - Colored, - Deformable, - Tabled, - Sprites - }; - - QUrl image() const { return m_image ? m_image->source : QUrl(); } - void setImage(const QUrl &image); - - QUrl colortable() const { return m_colorTable ? m_colorTable->source : QUrl(); } - void setColortable(const QUrl &table); - - QUrl sizetable() const { return m_sizeTable ? m_sizeTable->source : QUrl(); } - void setSizetable (const QUrl &table); - - QUrl opacitytable() const { return m_opacityTable ? m_opacityTable->source : QUrl(); } - void setOpacitytable(const QUrl &table); - - QColor color() const { return m_color; } - void setColor(const QColor &color); - - qreal colorVariation() const { return m_color_variation; } - void setColorVariation(qreal var); - - qreal alphaVariation() const { return m_alphaVariation; } - - qreal alpha() const { return m_alpha; } - - qreal redVariation() const { return m_redVariation; } - - qreal greenVariation() const { return m_greenVariation; } - - qreal blueVariation() const { return m_blueVariation; } - - qreal rotation() const { return m_rotation; } - - qreal rotationVariation() const { return m_rotationVariation; } - - qreal rotationSpeed() const { return m_rotationSpeed; } - - qreal rotationSpeedVariation() const { return m_rotationSpeedVariation; } - - bool autoRotation() const { return m_autoRotation; } - - QQuickDirection* xVector() const { return m_xVector; } - - QQuickDirection* yVector() const { return m_yVector; } - - bool spritesInterpolate() const { return m_spritesInterpolate; } - - bool bypassOptimizations() const { return m_bypassOptimizations; } - - EntryEffect entryEffect() const { return m_entryEffect; } - - Status status() const { return m_status; } - - void resetColor(); - void resetRotation(); - void resetDeformation(); - -signals: - - void imageChanged(); - void colortableChanged(); - void sizetableChanged(); - void opacitytableChanged(); - - void colorChanged(); - void colorVariationChanged(); - - void alphaVariationChanged(qreal arg); - - void alphaChanged(qreal arg); - - void redVariationChanged(qreal arg); - - void greenVariationChanged(qreal arg); - - void blueVariationChanged(qreal arg); - - void rotationChanged(qreal arg); - - void rotationVariationChanged(qreal arg); - - void rotationSpeedChanged(qreal arg); - - void rotationSpeedVariationChanged(qreal arg); - - void autoRotationChanged(bool arg); - - void xVectorChanged(QQuickDirection* arg); - - void yVectorChanged(QQuickDirection* arg); - - void spritesInterpolateChanged(bool arg); - - void bypassOptimizationsChanged(bool arg); - - void entryEffectChanged(EntryEffect arg); - - void statusChanged(Status arg); - -public slots: - void reloadColor(const Color4ub &c, QQuickParticleData* d); - void setAlphaVariation(qreal arg); - - void setAlpha(qreal arg); - - void setRedVariation(qreal arg); - - void setGreenVariation(qreal arg); - - void setBlueVariation(qreal arg); - - void setRotation(qreal arg); - - void setRotationVariation(qreal arg); - - void setRotationSpeed(qreal arg); - - void setRotationSpeedVariation(qreal arg); - - void setAutoRotation(bool arg); - - void setXVector(QQuickDirection* arg); - - void setYVector(QQuickDirection* arg); - - void setSpritesInterpolate(bool arg); - - void setBypassOptimizations(bool arg); - - void setEntryEffect(EntryEffect arg); - -protected: - void reset(); - virtual void initialize(int gIdx, int pIdx); - virtual void commit(int gIdx, int pIdx); - - QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *); - void prepareNextFrame(); - void buildParticleNodes(); - - void sceneGraphInvalidated(); - -private slots: - void createEngine(); //### method invoked by sprite list changing (in engine.h) - pretty nasty - - void spriteAdvance(int spriteIndex); - void spritesUpdate(qreal time = 0 ); - void finishBuildParticleNodes(); -private: - struct ImageData { - QUrl source; - QQuickPixmap pix; - }; - ImageData *m_image; - ImageData *m_colorTable; - ImageData *m_sizeTable; - ImageData *m_opacityTable; - bool loadingSomething(); - - - QColor m_color; - qreal m_color_variation; - - QSGGeometryNode *m_rootNode; - QHash m_nodes; - QHash m_idxStarts;//TODO: Proper resizing will lead to needing a spriteEngine per particle - do this after sprite engine gains transparent sharing? - QList > m_startsIdx;//Same data, optimized for alternate retrieval - - int m_lastIdxStart; - QSGMaterial *m_material; - - // derived values... - - qreal m_alphaVariation; - qreal m_alpha; - qreal m_redVariation; - qreal m_greenVariation; - qreal m_blueVariation; - qreal m_rotation; - qreal m_rotationVariation; - qreal m_rotationSpeed; - qreal m_rotationSpeedVariation; - bool m_autoRotation; - QQuickDirection* m_xVector; - QQuickDirection* m_yVector; - - QList m_sprites; - QQuickSpriteEngine* m_spriteEngine; - bool m_spritesInterpolate; - - bool m_explicitColor; - bool m_explicitRotation; - bool m_explicitDeformation; - bool m_explicitAnimation; - QHash > m_shadowData; - void clearShadows(); - QQuickParticleData* getShadowDatum(QQuickParticleData* datum); - - bool m_bypassOptimizations; - PerformanceLevel perfLevel; - - PerformanceLevel m_lastLevel; - bool m_debugMode; - - template - void initTexCoords(Vertex* v, int count){ - Vertex* end = v + count; - while (v < end){ - v[0].tx = 0; - v[0].ty = 0; - - v[1].tx = 1; - v[1].ty = 0; - - v[2].tx = 0; - v[2].ty = 1; - - v[3].tx = 1; - v[3].ty = 1; - - v += 4; - } - } - - template - MaterialData* getState(QSGMaterial* m){ - return static_cast *>(m)->state(); - } - EntryEffect m_entryEffect; - Status m_status; - bool m_buildingNodes; -}; - -QT_END_NAMESPACE -QT_END_HEADER -#endif // ULTRAPARTICLE_H diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquickitemparticle.cpp qt5-declarative-0.1~git20120423/src/quick/particles/qquickitemparticle.cpp --- qt5-declarative-0.1~git20120402/src/quick/particles/qquickitemparticle.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquickitemparticle.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,277 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qquickitemparticle_p.h" -#include -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - -/*! - \qmlclass ItemParticle QQuickItemParticle - \inqmlmodule QtQuick.Particles 2 - \inherits ParticlePainter - \brief The ItemParticle element allows you to specify your own delegate to paint particles. - -*/ - - -/*! - \qmlmethod void QtQuick.Particles2::ItemParticle::freeze(Item item) - - Suspends the flow of time for the logical particle which item represents, allowing you to control its movement. -*/ - -/*! - \qmlmethod void QtQuick.Particles2::ItemParticle::unfreeze(Item item) - - Restarts the flow of time for the logical particle which item represents, allowing it to be moved by the particle system again. -*/ - -/*! - \qmlmethod void QtQuick.Particles2::ItemParticle::take(Item item, bool prioritize) - - Asks the ItemParticle to take over control of item. It will be emitted when there is a logical particle available. - - By default items form a queue when waiting for a logical particle, but if prioritize is true then it will go immediately to the - head of the queue. -*/ -/*! - \qmlmethod void QtQuick.Particles2::ItemParticle::give(Item item) - - Orders the ItemParticle to give you control of the item. It will cease controlling it and the item will lose its association to the logical particle. -*/ - -/*! - \qmlproperty bool QtQuick.Particles2::ItemParticle::fade - - If true, the item will automatically be faded in and out - at the ends of its lifetime. If false, you will have to - implement any entry effect yourself. - - Default is true. -*/ -/*! - \qmlproperty Component QtQuick.Particles2::ItemParticle::delegate - - An instance of the delegate will be created for every logical - particle, and moved along with it. -*/ - -QQuickItemParticle::QQuickItemParticle(QQuickItem *parent) : - QQuickParticlePainter(parent), m_fade(true), m_delegate(0) -{ - setFlag(QQuickItem::ItemHasContents); - clock = new Clock(this); - clock->start(); -} - -QQuickItemParticle::~QQuickItemParticle() -{ - delete clock; -} - -void QQuickItemParticle::freeze(QQuickItem* item) -{ - m_stasis << item; -} - - -void QQuickItemParticle::unfreeze(QQuickItem* item) -{ - m_stasis.remove(item); -} - -void QQuickItemParticle::take(QQuickItem *item, bool prioritize) -{ - if (prioritize) - m_pendingItems.push_front(item); - else - m_pendingItems.push_back(item); -} - -void QQuickItemParticle::give(QQuickItem *item) -{ - //TODO: This - Q_UNUSED(item); -} - -void QQuickItemParticle::initialize(int gIdx, int pIdx) -{ - m_loadables << m_system->groupData[gIdx]->data[pIdx];//defer to other thread -} - -void QQuickItemParticle::commit(int, int) -{ -} - -void QQuickItemParticle::tick(int time) -{ - Q_UNUSED(time);//only needed because QTickAnimationProxy expects one - foreach (QQuickItem* item, m_deletables){ - if (m_fade) - item->setOpacity(0.); - item->setVisible(false); - QQuickItemParticleAttached* mpa; - if ((mpa = qobject_cast(qmlAttachedPropertiesObject(item)))) - mpa->detach();//reparent as well? - //TODO: Delete iff we created it - m_activeCount--; - } - m_deletables.clear(); - - foreach (QQuickParticleData* d, m_loadables){ - if (m_stasis.contains(d->delegate)) - qWarning() << "Current model particles prefers overwrite:false"; - //remove old item from the particle that is dying to make room for this one - if (d->delegate) - m_deletables << d->delegate; - d->delegate = 0; - if (!m_pendingItems.isEmpty()){ - d->delegate = m_pendingItems.front(); - m_pendingItems.pop_front(); - }else if (m_delegate){ - d->delegate = qobject_cast(m_delegate->create(qmlContext(this))); - } - if (d->delegate && d){//###Data can be zero if creating an item leads to a reset - this screws things up. - d->delegate->setX(d->curX() - d->delegate->width()/2);//TODO: adjust for system? - d->delegate->setY(d->curY() - d->delegate->height()/2); - QQuickItemParticleAttached* mpa = qobject_cast(qmlAttachedPropertiesObject(d->delegate)); - if (mpa){ - mpa->m_mp = this; - mpa->attach(); - } - d->delegate->setParentItem(this); - if (m_fade) - d->delegate->setOpacity(0.); - d->delegate->setVisible(false);//Will be set to true when we prepare the next frame - m_activeCount++; - } - } - m_loadables.clear(); -} - -void QQuickItemParticle::reset() -{ - QQuickParticlePainter::reset(); - m_loadables.clear(); - //TODO: Cleanup items? - //deletables? -} - - -QSGNode* QQuickItemParticle::updatePaintNode(QSGNode* n, UpdatePaintNodeData* d) -{ - //Dummy update just to get painting tick - if (m_pleaseReset){ - m_pleaseReset = false; - //Refill loadables, delayed here so as to only happen once per frame max - //### Constant resetting might lead to m_loadables never being populated when tick() occurs - foreach (const QString group, m_groups){ - int gIdx = m_system->groupIds[group]; - foreach (QQuickParticleData* d, m_system->groupData[gIdx]->data) - if (!d->delegate && d->t != -1 && d->stillAlive()) - m_loadables << d; - } - } - prepareNextFrame(); - - update();//Get called again - if (n) - n->markDirty(QSGNode::DirtyMaterial); - return QQuickItem::updatePaintNode(n,d); -} - -void QQuickItemParticle::prepareNextFrame() -{ - if (!m_system) - return; - qint64 timeStamp = m_system->systemSync(this); - qreal curT = timeStamp/1000.0; - qreal dt = curT - m_lastT; - m_lastT = curT; - if (!m_activeCount) - return; - - //TODO: Size, better fade? - foreach (const QString &str, m_groups){ - int gIdx = m_system->groupIds[str]; - int count = m_system->groupData[gIdx]->size(); - - for (int i=0; igroupData[gIdx]->data[i]; - QQuickItem* item = data->delegate; - if (!item) - continue; - qreal t = ((timeStamp/1000.0) - data->t) / data->lifeSpan; - if (m_stasis.contains(item)) { - data->t += dt;//Stasis effect - continue; - } - if (t >= 1.0){//Usually happens from load - m_deletables << item; - data->delegate = 0; - }else{//Fade - data->delegate->setVisible(true); - if (m_fade){ - qreal o = 1.; - if (t<0.2) - o = t*5; - if (t>0.8) - o = (1-t)*5; - item->setOpacity(o); - } - } - item->setX(data->curX() - item->width()/2 - m_systemOffset.x()); - item->setY(data->curY() - item->height()/2 - m_systemOffset.y()); - } - } -} - -QQuickItemParticleAttached *QQuickItemParticle::qmlAttachedProperties(QObject *object) -{ - return new QQuickItemParticleAttached(object); -} - -QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquickitemparticle_p.h qt5-declarative-0.1~git20120423/src/quick/particles/qquickitemparticle_p.h --- qt5-declarative-0.1~git20120402/src/quick/particles/qquickitemparticle_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquickitemparticle_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,141 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef ITEMPARTICLE_H -#define ITEMPARTICLE_H -#include "qquickparticlepainter_p.h" -#include -#include -#include -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -class QQuickVisualDataModel; -class QQuickItemParticleAttached; - -class QQuickItemParticle : public QQuickParticlePainter -{ - Q_OBJECT - Q_PROPERTY(bool fade READ fade WRITE setFade NOTIFY fadeChanged) - Q_PROPERTY(QQmlComponent* delegate READ delegate WRITE setDelegate NOTIFY delegateChanged) -public: - explicit QQuickItemParticle(QQuickItem *parent = 0); - ~QQuickItemParticle(); - - bool fade() const { return m_fade; } - - virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *); - - static QQuickItemParticleAttached *qmlAttachedProperties(QObject *object); - QQmlComponent* delegate() const - { - return m_delegate; - } - -signals: - void fadeChanged(); - - void delegateChanged(QQmlComponent* arg); - -public slots: - //TODO: Add a follow mode, where moving the delegate causes the logical particle to go with it? - void freeze(QQuickItem* item); - void unfreeze(QQuickItem* item); - void take(QQuickItem* item,bool prioritize=false);//take by modelparticle - void give(QQuickItem* item);//give from modelparticle - - void setFade(bool arg){if (arg == m_fade) return; m_fade = arg; emit fadeChanged();} - void setDelegate(QQmlComponent* arg) - { - if (m_delegate != arg) { - m_delegate = arg; - emit delegateChanged(arg); - } - } - -protected: - virtual void reset(); - virtual void commit(int gIdx, int pIdx); - virtual void initialize(int gIdx, int pIdx); - void prepareNextFrame(); -private: - void tick(int time = 0); - QList m_deletables; - QList< QQuickParticleData* > m_loadables; - bool m_fade; - - QList m_pendingItems; - QList m_available; - QSet m_stasis; - qreal m_lastT; - int m_activeCount; - QQmlComponent* m_delegate; - - typedef QTickAnimationProxy Clock; - Clock *clock; -}; - -class QQuickItemParticleAttached : public QObject -{ - Q_OBJECT - Q_PROPERTY(QQuickItemParticle* particle READ particle CONSTANT); -public: - QQuickItemParticleAttached(QObject* parent) - : QObject(parent), m_mp(0) - {;} - QQuickItemParticle* particle() {return m_mp;} - void detach(){emit detached();} - void attach(){emit attached();} -private: - QQuickItemParticle* m_mp; - friend class QQuickItemParticle; -Q_SIGNALS: - void detached(); - void attached(); -}; - -QT_END_NAMESPACE - -QML_DECLARE_TYPEINFO(QQuickItemParticle, QML_HAS_ATTACHED_PROPERTIES) - -QT_END_HEADER -#endif // ITEMPARTICLE_H diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquicklineextruder.cpp qt5-declarative-0.1~git20120423/src/quick/particles/qquicklineextruder.cpp --- qt5-declarative-0.1~git20120402/src/quick/particles/qquicklineextruder.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquicklineextruder.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,85 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "qquicklineextruder_p.h" -#include -#include - -/*! - \qmlclass LineShape QQuickLineExtruder - \inqmlmodule QtQuick.Particles 2 - \inherits Shape - \brief The LineShape represents a line to Affectors and Emitter - -*/ - -/*! - \qmlproperty bool QtQuick.Particles2::LineShape::mirrored - - By default, the line goes from (0,0) to (width, height) of the item that - this shape is being applied to. - - If mirrored is set to true, this will be mirrored along the y axis. - The line will then go from (0,height) to (width, 0). -*/ - -QQuickLineExtruder::QQuickLineExtruder(QObject *parent) : - QQuickParticleExtruder(parent), m_mirrored(false) -{ -} - -QPointF QQuickLineExtruder::extrude(const QRectF &r) -{ - qreal x,y; - if (!r.height()){ - x = r.width() * ((qreal)rand())/RAND_MAX; - y = 0; - }else{ - y = r.height() * ((qreal)rand())/RAND_MAX; - if (!r.width()){ - x = 0; - }else{ - x = r.width()/r.height() * y; - if (m_mirrored) - x = r.width() - x; - } - } - return QPointF(x,y); -} diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquicklineextruder_p.h qt5-declarative-0.1~git20120423/src/quick/particles/qquicklineextruder_p.h --- qt5-declarative-0.1~git20120402/src/quick/particles/qquicklineextruder_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquicklineextruder_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,77 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef LINEEXTRUDER_H -#define LINEEXTRUDER_H -#include "qquickparticleextruder_p.h" - -class QQuickLineExtruder : public QQuickParticleExtruder -{ - Q_OBJECT - //Default is topleft to bottom right. Flipped makes it topright to bottom left - Q_PROPERTY(bool mirrored READ mirrored WRITE setmirrored NOTIFY mirroredChanged) - -public: - explicit QQuickLineExtruder(QObject *parent = 0); - virtual QPointF extrude(const QRectF &); - bool mirrored() const - { - return m_mirrored; - } - -signals: - - void mirroredChanged(bool arg); - -public slots: - - void setmirrored(bool arg) - { - if (m_mirrored != arg) { - m_mirrored = arg; - emit mirroredChanged(arg); - } - } -private: - bool m_mirrored; -}; - -#endif // LINEEXTRUDER_H diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquickmaskextruder.cpp qt5-declarative-0.1~git20120423/src/quick/particles/qquickmaskextruder.cpp --- qt5-declarative-0.1~git20120402/src/quick/particles/qquickmaskextruder.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquickmaskextruder.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,141 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qquickmaskextruder_p.h" -#include -#include -#include -#include -QT_BEGIN_NAMESPACE -/*! - \qmlclass MaskShape QQuickMaskExtruder - \inqmlmodule QtQuick.Particles 2 - \inherits Shape - \brief The MaskShape element allows you to represent an image as a shape to affectors and emitters. - -*/ -/*! - \qmlproperty url QtQuick.Particles2::MaskShape::source - - The image to use as the mask. Areas with non-zero opacity - will be considered inside the shape. -*/ - - -QQuickMaskExtruder::QQuickMaskExtruder(QObject *parent) : - QQuickParticleExtruder(parent) - , m_lastWidth(-1) - , m_lastHeight(-1) -{ -} - -void QQuickMaskExtruder::setSource(QUrl arg) -{ - if (m_source != arg) { - m_source = arg; - - m_lastHeight = -1;//Trigger reset - m_lastWidth = -1; - emit sourceChanged(arg); - startMaskLoading(); - } -} - -void QQuickMaskExtruder::startMaskLoading() -{ - m_pix.clear(this); - if (m_source.isEmpty()) - return; - m_pix.load(qmlEngine(this), m_source); - if (m_pix.isLoading()) - m_pix.connectFinished(this, SLOT(finishMaskLoading())); - else - finishMaskLoading(); -} - -void QQuickMaskExtruder::finishMaskLoading() -{ - if (m_pix.isError()) - qmlInfo(this) << m_pix.error(); -} - -QPointF QQuickMaskExtruder::extrude(const QRectF &r) -{ - ensureInitialized(r); - if (!m_mask.count() || m_img.isNull()) - return r.topLeft(); - const QPointF p = m_mask[rand() % m_mask.count()]; - //### Should random sub-pixel positioning be added? - return p + r.topLeft(); -} - -bool QQuickMaskExtruder::contains(const QRectF &bounds, const QPointF &point) -{ - ensureInitialized(bounds);//###Current usage patterns WILL lead to different bounds/r calls. Separate list? - if (m_img.isNull()) - return false; - QPoint p = point.toPoint() - bounds.topLeft().toPoint(); - return m_img.rect().contains(p) && (bool)m_img.pixelIndex(p); -} - -void QQuickMaskExtruder::ensureInitialized(const QRectF &r) -{ - if (m_lastWidth == r.width() && m_lastHeight == r.height()) - return;//Same as before - if (!m_pix.isReady()) - return; - m_lastWidth = r.width(); - m_lastHeight = r.height(); - - m_mask.clear(); - - m_img = m_pix.image().createAlphaMask(); - m_pix.clear(); - m_img = m_img.convertToFormat(QImage::Format_Mono);//Else LSB, but I think that's easier - m_img = m_img.scaled(r.size().toSize());//TODO: Do they need aspect ratio stuff? Or tiling? - for (int i=0; i -#include -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -class QQuickMaskExtruder : public QQuickParticleExtruder -{ - Q_OBJECT - Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged) -public: - explicit QQuickMaskExtruder(QObject *parent = 0); - virtual QPointF extrude(const QRectF &); - virtual bool contains(const QRectF &bounds, const QPointF &point); - - QUrl source() const - { - return m_source; - } - -signals: - - void sourceChanged(QUrl arg); - -public slots: - void setSource(QUrl arg); - -private slots: - void startMaskLoading(); - void finishMaskLoading(); - -private: - QUrl m_source; - - void ensureInitialized(const QRectF &r); - int m_lastWidth; - int m_lastHeight; - QQuickPixmap m_pix; - QImage m_img; - QList m_mask;//TODO: More memory efficient datastructures - //Perhaps just the mask for the largest bounds is stored, and interpolate up -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // MASKEXTRUDER_H diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquickparticleaffector.cpp qt5-declarative-0.1~git20120423/src/quick/particles/qquickparticleaffector.cpp --- qt5-declarative-0.1~git20120402/src/quick/particles/qquickparticleaffector.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquickparticleaffector.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,279 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qquickparticleaffector_p.h" -#include -QT_BEGIN_NAMESPACE - -/*! - \qmlclass Affector QQuickParticleAffector - \inqmlmodule QtQuick.Particles 2 - \brief Affector elements can alter the attributes of logical particles at any point in their lifetime. - - The base Affector does not alter any attributes, but can be used to emit a signal - when a particle meets certain conditions. - - If an affector has a defined size, then it will only affect particles within its size and position on screen. - - Affectors have different performance characteristics to the other particle system elements. In particular, - they have some simplifications to try to maintain a simulation at real-time or faster. When running a system - with Affectors, irregular frame timings that grow too large ( > one second per frame) will cause the Affectors - to try and cut corners with a faster but less accurate simulation. If the system has multiple affectors the order - in which they are applied is not guaranteed, and when simulating larger time shifts they will simulate the whole - shift each, which can lead to different results compared to smaller time shifts. - - Accurate simulation for large numbers of particles (hundreds) with multiple affectors may be possible on some hardware, - but on less capable hardware you should expect small irregularties in the simulation as simulates with worse granularity. -*/ -/*! - \qmlproperty ParticleSystem QtQuick.Particles2::Affector::system - This is the system which will be affected by the element. - If the Affector is a direct child of a ParticleSystem, it will automatically be associated with it. -*/ -/*! - \qmlproperty list QtQuick.Particles2::Affector::groups - Which logical particle groups will be affected. - - If empty, it will affect all particles. -*/ -/*! - \qmlproperty list QtQuick.Particles2::Affector::whenCollidingWith - If any logical particle groups are specified here, then the affector - will only be triggered if the particle being examined intersects with - a particle of one of these groups. - - This is different from the groups property. The groups property selects which - particles might be examined, and if they meet other criteria (including being - within the bounds of the Affector, modified by shape) then they will be tested - again to see if they intersect with a particles from one of the particle groups - in whenCollidingWith. - - By default, no groups are specified. -*/ -/*! - \qmlproperty bool QtQuick.Particles2::Affector::enabled - If enabled is set to false, this affector will not affect any particles. - - Usually this is used to conditionally turn an affector on or off. - - Default value is true. -*/ -/*! - \qmlproperty bool QtQuick.Particles2::Affector::once - If once is set to true, this affector will only affect each particle - once in their lifetimes. If the affector normally simulates a continuous - effect over time, then it will simulate the effect of one second of time - the one instant it affects the particle. - - Default value is false. -*/ -/*! - \qmlproperty Shape QtQuick.Particles2::Affector::shape - If a size has been defined, the shape property can be used to affect a - non-rectangular area. -*/ -/*! - \qmlsignal QtQuick.Particles2::Affector::onAffected(x, y) - - This signal is emitted each time the affector actually affects a particle. - - x,y are the coordinates of the affected particle, relative to the ParticleSystem. - -*/ - -/*! - \qmlsignal QtQuick.Particles2::Affector::affectParticle(particle particle, real dt) - - This handler is called when particles are selected to be affected. - - dt is the time since the last time it was affected. Use dt to normalize - trajectory manipulations to real time. - - Note that JS is slower to execute, so it is not recommended to use this in - high-volume particle systems. -*/ -/*! - \qmlsignal QtQuick.Particles2::Affector::affected(real x, real y) - - This handler is called when a particle is selected to be affected. It will - only be called if signal is set to true. - - x,y is the particles current position. -*/ -QQuickParticleAffector::QQuickParticleAffector(QQuickItem *parent) : - QQuickItem(parent), m_needsReset(false), m_ignoresTime(false), m_onceOff(false), m_enabled(true) - , m_system(0), m_updateIntSet(false), m_shape(new QQuickParticleExtruder(this)) -{ -} - -bool QQuickParticleAffector::isAffectedConnected() -{ - static int idx = QObjectPrivate::get(this)->signalIndex("affected(qreal,qreal)"); - return QObjectPrivate::get(this)->isSignalConnected(idx); -} - - -void QQuickParticleAffector::componentComplete() -{ - if (!m_system && qobject_cast(parentItem())) - setSystem(qobject_cast(parentItem())); - QQuickItem::componentComplete(); -} - -bool QQuickParticleAffector::activeGroup(int g) { - if (m_updateIntSet){ //This can occur before group ids are properly assigned, but that resets the flag - m_groupIds.clear(); - foreach (const QString &p, m_groups) - m_groupIds << m_system->groupIds[p]; - m_updateIntSet = false; - } - return m_groupIds.isEmpty() || m_groupIds.contains(g); -} - -bool QQuickParticleAffector::shouldAffect(QQuickParticleData* d) -{ - if (!d) - return false; - if (activeGroup(d->group)){ - if ((m_onceOff && m_onceOffed.contains(qMakePair(d->group, d->index))) - || !d->stillAlive()) - return false; - //Need to have previous location for affected anyways - if (width() == 0 || height() == 0 - || m_shape->contains(QRectF(m_offset.x(), m_offset.y(), width(), height()), QPointF(d->curX(), d->curY()))){ - if (m_whenCollidingWith.isEmpty() || isColliding(d)){ - return true; - } - } - } - return false; - -} - -void QQuickParticleAffector::postAffect(QQuickParticleData* d) -{ - m_system->needsReset << d; - if (m_onceOff) - m_onceOffed << qMakePair(d->group, d->index); - if (isAffectedConnected()) - emit affected(d->curX(), d->curY()); -} - -const qreal QQuickParticleAffector::simulationDelta = 0.020; -const qreal QQuickParticleAffector::simulationCutoff = 1.000;//If this goes above 1.0, then m_once behaviour needs special codepath - -void QQuickParticleAffector::affectSystem(qreal dt) -{ - if (!m_enabled) - return; - //If not reimplemented, calls affectParticle per particle - //But only on particles in targeted system/area - updateOffsets();//### Needed if an ancestor is transformed. - if (m_onceOff) - dt = 1.0; - foreach (QQuickParticleGroupData* gd, m_system->groupData) { - if (activeGroup(m_system->groupData.key(gd))) { - foreach (QQuickParticleData* d, gd->data) { - if (shouldAffect(d)) { - bool affected = false; - qreal myDt = dt; - if (!m_ignoresTime && myDt < simulationCutoff) { - int realTime = m_system->timeInt; - m_system->timeInt -= myDt * 1000.0; - while (myDt > simulationDelta) { - m_system->timeInt += simulationDelta * 1000.0; - if (d->alive())//Only affect during the parts it was alive for - affected = affectParticle(d, simulationDelta) || affected; - myDt -= simulationDelta; - } - m_system->timeInt = realTime; - } - if (myDt > 0.0) - affected = affectParticle(d, myDt) || affected; - if (affected) - postAffect(d); - } - } - } - } -} - -bool QQuickParticleAffector::affectParticle(QQuickParticleData *, qreal ) -{ - return true; -} - -void QQuickParticleAffector::reset(QQuickParticleData* pd) -{//TODO: This, among other ones, should be restructured so they don't all need to remember to call the superclass - if (m_onceOff) - if (activeGroup(pd->group)) - m_onceOffed.remove(qMakePair(pd->group, pd->index)); -} - -void QQuickParticleAffector::updateOffsets() -{ - if (m_system) - m_offset = m_system->mapFromItem(this, QPointF(0, 0)); -} - -bool QQuickParticleAffector::isColliding(QQuickParticleData *d) -{ - qreal myCurX = d->curX(); - qreal myCurY = d->curY(); - qreal myCurSize = d->curSize()/2; - foreach (const QString &group, m_whenCollidingWith){ - foreach (QQuickParticleData* other, m_system->groupData[m_system->groupIds[group]]->data){ - if (!other->stillAlive()) - continue; - qreal otherCurX = other->curX(); - qreal otherCurY = other->curY(); - qreal otherCurSize = other->curSize()/2; - if ((myCurX + myCurSize > otherCurX - otherCurSize - && myCurX - myCurSize < otherCurX + otherCurSize) - && (myCurY + myCurSize > otherCurY - otherCurSize - && myCurY - myCurSize < otherCurY + otherCurSize)) - return true; - } - } - return false; -} - -QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquickparticleaffector_p.h qt5-declarative-0.1~git20120423/src/quick/particles/qquickparticleaffector_p.h --- qt5-declarative-0.1~git20120402/src/quick/particles/qquickparticleaffector_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquickparticleaffector_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,199 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef PARTICLEAFFECTOR_H -#define PARTICLEAFFECTOR_H - -#include -#include "qquickparticlesystem_p.h" -#include "qquickparticleextruder_p.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -class QQuickParticleAffector : public QQuickItem -{ - Q_OBJECT - Q_PROPERTY(QQuickParticleSystem* system READ system WRITE setSystem NOTIFY systemChanged) - Q_PROPERTY(QStringList groups READ groups WRITE setGroups NOTIFY groupsChanged) - Q_PROPERTY(QStringList whenCollidingWith READ whenCollidingWith WRITE setWhenCollidingWith NOTIFY whenCollidingWithChanged) - Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged) - Q_PROPERTY(bool once READ onceOff WRITE setOnceOff NOTIFY onceChanged) - Q_PROPERTY(QQuickParticleExtruder* shape READ shape WRITE setShape NOTIFY shapeChanged) - -public: - explicit QQuickParticleAffector(QQuickItem *parent = 0); - virtual void affectSystem(qreal dt); - virtual void reset(QQuickParticleData*);//As some store their own data per particle? - QQuickParticleSystem* system() const - { - return m_system; - } - - QStringList groups() const - { - return m_groups; - } - - bool enabled() const - { - return m_enabled; - } - - bool onceOff() const - { - return m_onceOff; - } - - QQuickParticleExtruder* shape() const - { - return m_shape; - } - - QStringList whenCollidingWith() const - { - return m_whenCollidingWith; - } - -signals: - - void systemChanged(QQuickParticleSystem* arg); - - void groupsChanged(QStringList arg); - - void enabledChanged(bool arg); - - void onceChanged(bool arg); - - void shapeChanged(QQuickParticleExtruder* arg); - - void affected(qreal x, qreal y); - - void whenCollidingWithChanged(QStringList arg); - -public slots: -void setSystem(QQuickParticleSystem* arg) -{ - if (m_system != arg) { - m_system = arg; - m_system->registerParticleAffector(this); - emit systemChanged(arg); - } -} - -void setGroups(QStringList arg) -{ - if (m_groups != arg) { - m_groups = arg; - m_updateIntSet = true; - emit groupsChanged(arg); - } -} - -void setEnabled(bool arg) -{ - if (m_enabled != arg) { - m_enabled = arg; - emit enabledChanged(arg); - } -} - -void setOnceOff(bool arg) -{ - if (m_onceOff != arg) { - m_onceOff = arg; - m_needsReset = true; - emit onceChanged(arg); - } -} - -void setShape(QQuickParticleExtruder* arg) -{ - if (m_shape != arg) { - m_shape = arg; - emit shapeChanged(arg); - } -} - -void setWhenCollidingWith(QStringList arg) -{ - if (m_whenCollidingWith != arg) { - m_whenCollidingWith = arg; - emit whenCollidingWithChanged(arg); - } -} -public slots: - void updateOffsets(); - -protected: - friend class QQuickParticleSystem; - virtual bool affectParticle(QQuickParticleData *d, qreal dt); - bool m_needsReset:1;//### What is this really saving? - bool m_ignoresTime:1; - bool m_onceOff:1; - bool m_enabled:1; - - QQuickParticleSystem* m_system; - QStringList m_groups; - bool activeGroup(int g); - bool shouldAffect(QQuickParticleData* datum);//Call to do the logic on whether it is affecting that datum - void postAffect(QQuickParticleData* datum);//Call to do the post-affect logic on particles which WERE affected(once off, needs reset, affected signal) - virtual void componentComplete(); - QPointF m_offset; - bool isAffectedConnected(); - static const qreal simulationDelta; - static const qreal simulationCutoff; -private: - QSet m_groupIds; - QSet > m_onceOffed; - bool m_updateIntSet; - - QQuickParticleExtruder* m_shape; - - QStringList m_whenCollidingWith; - - bool isColliding(QQuickParticleData* d); -}; - -QT_END_NAMESPACE -QT_END_HEADER -#endif // PARTICLEAFFECTOR_H diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquickparticleemitter.cpp qt5-declarative-0.1~git20120423/src/quick/particles/qquickparticleemitter.cpp --- qt5-declarative-0.1~git20120402/src/quick/particles/qquickparticleemitter.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquickparticleemitter.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,495 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qquickparticleemitter_p.h" -#include -QT_BEGIN_NAMESPACE - - -/*! - \qmlclass Emitter QQuickParticleEmitter - \inqmlmodule QtQuick.Particles 2 - \brief The Emitter element allows you to emit logical particles. - - This element emits logical particles into the ParticleSystem, with the - given starting attributes. - - Note that logical particles are not - automatically rendered, you will need to have one or more - ParticlePainter elements visualizing them. - - Note that the given starting attributes can be modified at any point - in the particle's lifetime by any Affector element in the same - ParticleSystem. This includes attributes like lifespan. -*/ - - -/*! - \qmlproperty ParticleSystem QtQuick.Particles2::Emitter::system - - This is the Particle system that the Emitter will emit into. - This can be omitted if the Emitter is a direct child of the ParticleSystem -*/ -/*! - \qmlproperty string QtQuick.Particles2::Emitter::group - - This is the logical particle group which it will emit into. - - Default value is "" (empty string). -*/ -/*! - \qmlproperty Shape QtQuick.Particles2::Emitter::shape - - This shape is applied with the size of the Emitter. Particles will be emitted - randomly from any area covered by the shape. - - The default shape is a filled in rectangle, which corresponds to the full bounding - box of the Emitter. -*/ -/*! - \qmlproperty bool QtQuick.Particles2::Emitter::emitting - - If set to false, the emitter will cease emissions until it is set to true. - - Default value is true. -*/ -/*! - \qmlproperty real QtQuick.Particles2::Emitter::emitRate - - Number of particles emitted per second. - - Default value is 10 particles per second. -*/ -/*! - \qmlproperty int QtQuick.Particles2::Emitter::lifeSpan - - The time in milliseconds each emitted particle should last for. - - If you do not want particles to automatically die after a time, for example if - you wish to dispose of them manually, set lifeSpan to Emitter.InfiniteLife. - - lifeSpans greater than or equal to 600000 (10 minutes) will be treated as infinite. - Particles with lifeSpans less than or equal to 0 will start out dead. - - Default value is 1000 (one second). -*/ -/*! - \qmlproperty int QtQuick.Particles2::Emitter::lifeSpanVariation - - Particle lifespans will vary by up to this much in either direction. - - Default value is 0. -*/ - -/*! - \qmlproperty int QtQuick.Particles2::Emitter::maximumEmitted - - The maximum number of particles at a time that this emitter will have alive. - - This can be set as a performance optimization (when using burst and pulse) or - to stagger emissions. - - If this is set to a number below zero, then there is no maximum limit on the number - of particles this emitter can have alive. - - The default value is -1. -*/ -/*! - \qmlproperty int QtQuick.Particles2::Emitter::startTime - - If this value is set when the emitter is loaded, then it will emit particles from the - past, up to startTime milliseconds ago. These will simulate as if they were emitted then, - but will not have any affectors applied to them. Affectors will take effect from the present time. -*/ -/*! - \qmlproperty real QtQuick.Particles2::Emitter::size - - The size in pixels of the particles at the start of their life. - - Default value is 16. -*/ -/*! - \qmlproperty real QtQuick.Particles2::Emitter::endSize - - The size in pixels of the particles at the end of their life. Size will - be linearly interpolated during the life of the particle from this value and - size. If endSize is -1, then the size of the particle will remain constant at - the starting size. - - Default value is -1. -*/ -/*! - \qmlproperty real QtQuick.Particles2::Emitter::sizeVariation - - The size of a particle can vary by this much up or down from size/endSize. The same - random addition is made to both size and endSize for a single particle. - - Default value is 0. -*/ -/*! - \qmlproperty StochasticDirection QtQuick.Particles2::Emitter::speed - - The starting speed of the particles emitted. -*/ -/*! - \qmlproperty StochasticDirection QtQuick.Particles2::Emitter::acceleration - - The starting acceleraton of the particles emitted. -*/ -/*! - \qmlproperty qreal QtQuick.Particles2::Emitter::speedFromMovement - - If this value is non-zero, then any movement of the emitter will provide additional - starting velocity to the particles based on the movement. The additional vector will be the - same angle as the emitter's movement, with a magnitude that is the magnitude of the emitters - movement multiplied by speedFromMovement. - - Default value is 0. -*/ - -/*! - \qmlsignal QtQuick.Particles2::Emitter::onEmitParticles(Array particles) - - This handler is called when particles are emitted. particles is a javascript - array of Particle objects. You can modify particle attributes directly within the handler. - - Note that JS is slower to execute, so it is not recommended to use this in - high-volume particle systems. -*/ - -/*! \qmlmethod QtQuick.Particles2::Emitter::burst(int count) - - Emits count particles from this emitter immediately. -*/ - -/*! \qmlmethod QtQuick.Particles2::Emitter::burst(int x, int y, int count) - - Emits count particles from this emitter immediately. The particles are emitted - as if the Emitter was positioned at x,y but all other properties are the same. -*/ - -/*! \qmlmethod QtQuick.Particles2::Emitter::pulse(int duration) - - If the emitter is not enabled, enables it for duration milliseconds and then switches - it back off. -*/ - -QQuickParticleEmitter::QQuickParticleEmitter(QQuickItem *parent) : - QQuickItem(parent) - , m_particlesPerSecond(10) - , m_particleDuration(1000) - , m_particleDurationVariation(0) - , m_enabled(true) - , m_system(0) - , m_extruder(0) - , m_defaultExtruder(0) - , m_speed(&m_nullVector) - , m_acceleration(&m_nullVector) - , m_particleSize(16) - , m_particleEndSize(-1) - , m_particleSizeVariation(0) - , m_startTime(0) - , m_overwrite(true) - , m_pulseLeft(0) - , m_maxParticleCount(-1) - , m_speed_from_movement(0) - , m_reset_last(true) - , m_last_timestamp(-1) - , m_last_emission(0) - -{ - //TODO: Reset speed/acc back to null vector? Or allow null pointer? - connect(this, SIGNAL(maximumEmittedChanged(int)), - this, SIGNAL(particleCountChanged())); - connect(this, SIGNAL(particlesPerSecondChanged(qreal)), - this, SIGNAL(particleCountChanged())); - connect(this, SIGNAL(particleDurationChanged(int)), - this, SIGNAL(particleCountChanged())); -} - -QQuickParticleEmitter::~QQuickParticleEmitter() -{ - if (m_defaultExtruder) - delete m_defaultExtruder; -} - -bool QQuickParticleEmitter::isEmitConnected() -{ - static int idx = QObjectPrivate::get(this)->signalIndex("emitParticles(QQmlV8Handle)"); - return QObjectPrivate::get(this)->isSignalConnected(idx); -} - -void QQuickParticleEmitter::componentComplete() -{ - if (!m_system && qobject_cast(parentItem())) - setSystem(qobject_cast(parentItem())); - QQuickItem::componentComplete(); -} - -void QQuickParticleEmitter::setEnabled(bool arg) -{ - if (m_enabled != arg) { - m_enabled = arg; - emit enabledChanged(arg); - } -} - - -QQuickParticleExtruder* QQuickParticleEmitter::effectiveExtruder() -{ - if (m_extruder) - return m_extruder; - if (!m_defaultExtruder) - m_defaultExtruder = new QQuickParticleExtruder; - return m_defaultExtruder; -} - -void QQuickParticleEmitter::pulse(int milliseconds) -{ - if (!m_enabled) - m_pulseLeft = milliseconds; -} - -void QQuickParticleEmitter::burst(int num) -{ - m_burstQueue << qMakePair(num, QPointF(x(), y())); -} - -void QQuickParticleEmitter::burst(int num, qreal x, qreal y) -{ - m_burstQueue << qMakePair(num, QPointF(x, y)); -} - -void QQuickParticleEmitter::setMaxParticleCount(int arg) -{ - if (m_maxParticleCount != arg) { - if (arg < 0 && m_maxParticleCount >= 0){ - connect(this, SIGNAL(particlesPerSecondChanged(qreal)), - this, SIGNAL(particleCountChanged())); - connect(this, SIGNAL(particleDurationChanged(int)), - this, SIGNAL(particleCountChanged())); - }else if (arg >= 0 && m_maxParticleCount < 0){ - disconnect(this, SIGNAL(particlesPerSecondChanged(qreal)), - this, SIGNAL(particleCountChanged())); - disconnect(this, SIGNAL(particleDurationChanged(int)), - this, SIGNAL(particleCountChanged())); - } - m_overwrite = arg < 0; - m_maxParticleCount = arg; - emit maximumEmittedChanged(arg); - } -} - -int QQuickParticleEmitter::particleCount() const -{ - if (m_maxParticleCount >= 0) - return m_maxParticleCount; - return m_particlesPerSecond*((m_particleDuration+m_particleDurationVariation)/1000.0); -} - -void QQuickParticleEmitter::setSpeedFromMovement(qreal t) -{ - if (t == m_speed_from_movement) - return; - m_speed_from_movement = t; - emit speedFromMovementChanged(); -} - -void QQuickParticleEmitter::reset() -{ - m_reset_last = true; -} - -void QQuickParticleEmitter::emitWindow(int timeStamp) -{ - if (m_system == 0) - return; - if ((!m_enabled || !m_particlesPerSecond)&& !m_pulseLeft && m_burstQueue.isEmpty()){ - m_reset_last = true; - return; - } - - if (m_reset_last) { - m_last_emitter = m_last_last_emitter = QPointF(x(), y()); - if (m_last_timestamp == -1) - m_last_timestamp = (timeStamp - m_startTime)/1000.; - else - m_last_timestamp = timeStamp/1000.; - m_last_emission = m_last_timestamp; - m_reset_last = false; - m_emitCap = particleCount(); - } - - if (m_pulseLeft){ - m_pulseLeft -= timeStamp - m_last_timestamp * 1000.; - if (m_pulseLeft < 0){ - if (!m_enabled) - timeStamp += m_pulseLeft; - m_pulseLeft = 0; - } - } - qreal time = timeStamp / 1000.; - qreal particleRatio = 1. / m_particlesPerSecond; - qreal pt = m_last_emission; - qreal maxLife = (m_particleDuration + m_particleDurationVariation)/1000.0; - if (pt + maxLife < time)//We missed so much, that we should skip emiting particles that are dead by now - pt = time - maxLife; - - qreal opt = pt; // original particle time - qreal dt = time - m_last_timestamp; // timestamp delta... - if (!dt) - dt = 0.000001; - - // emitter difference since last... - qreal dex = (x() - m_last_emitter.x()); - qreal dey = (y() - m_last_emitter.y()); - - qreal ax = (m_last_last_emitter.x() + m_last_emitter.x()) / 2; - qreal bx = m_last_emitter.x(); - qreal cx = (x() + m_last_emitter.x()) / 2; - qreal ay = (m_last_last_emitter.y() + m_last_emitter.y()) / 2; - qreal by = m_last_emitter.y(); - qreal cy = (y() + m_last_emitter.y()) / 2; - - qreal sizeAtEnd = m_particleEndSize >= 0 ? m_particleEndSize : m_particleSize; - qreal emitter_x_offset = m_last_emitter.x() - x(); - qreal emitter_y_offset = m_last_emitter.y() - y(); - if (!m_burstQueue.isEmpty() && !m_pulseLeft && !m_enabled)//'outside time' emissions only - pt = time; - - QList toEmit; - - while ((pt < time && m_emitCap) || !m_burstQueue.isEmpty()) { - //int pos = m_last_particle % m_particle_count; - QQuickParticleData* datum = m_system->newDatum(m_system->groupIds[m_group], !m_overwrite); - if (datum){//actually emit(otherwise we've been asked to skip this one) - datum->e = this;//###useful? - qreal t = 1 - (pt - opt) / dt; - qreal vx = - - 2 * ax * (1 - t) - + 2 * bx * (1 - 2 * t) - + 2 * cx * t; - qreal vy = - - 2 * ay * (1 - t) - + 2 * by * (1 - 2 * t) - + 2 * cy * t; - - - // Particle timestamp - datum->t = pt; - datum->lifeSpan = - (m_particleDuration - + ((rand() % ((m_particleDurationVariation*2) + 1)) - m_particleDurationVariation)) - / 1000.0; - - if (datum->lifeSpan >= m_system->maxLife){ - datum->lifeSpan = m_system->maxLife; - m_emitCap--;//emitCap keeps us from reemitting 'infinite' particles after their life. Unless you reset the emitter. - } - - // Particle position - QRectF boundsRect; - if (!m_burstQueue.isEmpty()){ - boundsRect = QRectF(m_burstQueue.first().second.x() - x(), m_burstQueue.first().second.y() - y(), - width(), height()); - } else { - boundsRect = QRectF(emitter_x_offset + dex * (pt - opt) / dt, emitter_y_offset + dey * (pt - opt) / dt - , width(), height()); - } - QPointF newPos = effectiveExtruder()->extrude(boundsRect); - datum->x = newPos.x(); - datum->y = newPos.y(); - - // Particle speed - const QPointF &speed = m_speed->sample(newPos); - datum->vx = speed.x() - + m_speed_from_movement * vx; - datum->vy = speed.y() - + m_speed_from_movement * vy; - - // Particle acceleration - const QPointF &accel = m_acceleration->sample(newPos); - datum->ax = accel.x(); - datum->ay = accel.y(); - - // Particle size - float sizeVariation = -m_particleSizeVariation - + rand() / float(RAND_MAX) * m_particleSizeVariation * 2; - - float size = qMax((qreal)0.0 , m_particleSize + sizeVariation); - float endSize = qMax((qreal)0.0 , sizeAtEnd + sizeVariation); - - datum->size = size;// * float(m_emitting); - datum->endSize = endSize;// * float(m_emitting); - - toEmit << datum; - } - if (m_burstQueue.isEmpty()){ - pt += particleRatio; - }else{ - m_burstQueue.first().first--; - if (m_burstQueue.first().first <= 0) - m_burstQueue.pop_front(); - } - } - - if (isEmitConnected()) { - v8::HandleScope handle_scope; - v8::Context::Scope scope(QQmlEnginePrivate::getV8Engine(qmlEngine(this))->context()); - v8::Handle array = v8::Array::New(toEmit.size()); - for (int i=0; iSet(i, toEmit[i]->v8Value().toHandle()); - - emitParticles(QQmlV8Handle::fromHandle(array));//A chance for arbitrary JS changes - } - foreach (QQuickParticleData* d, toEmit) - m_system->emitParticle(d); - - m_last_emission = pt; - - m_last_last_last_emitter = m_last_last_emitter; - m_last_last_emitter = m_last_emitter; - m_last_emitter = QPointF(x(), y()); - m_last_timestamp = time; -} - - -QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquickparticleemitter_p.h qt5-declarative-0.1~git20120423/src/quick/particles/qquickparticleemitter_p.h --- qt5-declarative-0.1~git20120402/src/quick/particles/qquickparticleemitter_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquickparticleemitter_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,350 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef PARTICLEEMITTER_H -#define PARTICLEEMITTER_H - -#include -#include -#include "qquickparticlesystem_p.h" -#include "qquickparticleextruder_p.h" -#include "qquickdirection_p.h" - -#include -#include -#include -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -class QQuickParticleEmitter : public QQuickItem -{ - Q_OBJECT - Q_PROPERTY(QQuickParticleSystem* system READ system WRITE setSystem NOTIFY systemChanged) - Q_PROPERTY(QString group READ group WRITE setGroup NOTIFY groupChanged) - Q_PROPERTY(QQuickParticleExtruder* shape READ extruder WRITE setExtruder NOTIFY extruderChanged) - Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged) - Q_PROPERTY(int startTime READ startTime WRITE setStartTime NOTIFY startTimeChanged) - - Q_PROPERTY(qreal emitRate READ particlesPerSecond WRITE setParticlesPerSecond NOTIFY particlesPerSecondChanged) - Q_PROPERTY(int lifeSpan READ particleDuration WRITE setParticleDuration NOTIFY particleDurationChanged) - Q_PROPERTY(int lifeSpanVariation READ particleDurationVariation WRITE setParticleDurationVariation NOTIFY particleDurationVariationChanged) - Q_PROPERTY(int maximumEmitted READ maxParticleCount WRITE setMaxParticleCount NOTIFY maximumEmittedChanged) - - Q_PROPERTY(qreal size READ particleSize WRITE setParticleSize NOTIFY particleSizeChanged) - Q_PROPERTY(qreal endSize READ particleEndSize WRITE setParticleEndSize NOTIFY particleEndSizeChanged) - Q_PROPERTY(qreal sizeVariation READ particleSizeVariation WRITE setParticleSizeVariation NOTIFY particleSizeVariationChanged) - - Q_PROPERTY(QQuickDirection *speed READ speed WRITE setSpeed NOTIFY speedChanged) - Q_PROPERTY(QQuickDirection *acceleration READ acceleration WRITE setAcceleration NOTIFY accelerationChanged) - Q_PROPERTY(qreal speedFromMovement READ speedFromMovement WRITE setSpeedFromMovement NOTIFY speedFromMovementChanged) - - Q_ENUMS(Lifetime) -public: - explicit QQuickParticleEmitter(QQuickItem *parent = 0); - virtual ~QQuickParticleEmitter(); - virtual void emitWindow(int timeStamp); - - enum Lifetime { - InfiniteLife = QQuickParticleSystem::maxLife - }; - - bool enabled() const - { - return m_enabled; - } - - qreal particlesPerSecond() const - { - return m_particlesPerSecond; - } - - int particleDuration() const - { - return m_particleDuration; - } - - QQuickParticleSystem* system() const - { - return m_system; - } - - QString group() const - { - return m_group; - } - - int particleDurationVariation() const - { - return m_particleDurationVariation; - } - - qreal speedFromMovement() const { return m_speed_from_movement; } - void setSpeedFromMovement(qreal s); - virtual void componentComplete(); -signals: - void emitParticles(QQmlV8Handle particles); - void particlesPerSecondChanged(qreal); - void particleDurationChanged(int); - void enabledChanged(bool); - - void systemChanged(QQuickParticleSystem* arg); - - void groupChanged(QString arg); - - void particleDurationVariationChanged(int arg); - - void extruderChanged(QQuickParticleExtruder* arg); - - void particleSizeChanged(qreal arg); - - void particleEndSizeChanged(qreal arg); - - void particleSizeVariationChanged(qreal arg); - - void speedChanged(QQuickDirection * arg); - - void accelerationChanged(QQuickDirection * arg); - - void maximumEmittedChanged(int arg); - void particleCountChanged(); - - void speedFromMovementChanged(); - - void startTimeChanged(int arg); - -public slots: - void pulse(int milliseconds); - void burst(int num); - void burst(int num, qreal x, qreal y); - - void setEnabled(bool arg); - - void setParticlesPerSecond(qreal arg) - { - if (m_particlesPerSecond != arg) { - m_particlesPerSecond = arg; - emit particlesPerSecondChanged(arg); - } - } - - void setParticleDuration(int arg) - { - if (m_particleDuration != arg) { - m_particleDuration = arg; - emit particleDurationChanged(arg); - } - } - - void setSystem(QQuickParticleSystem* arg) - { - if (m_system != arg) { - m_system = arg; - if (m_system) - m_system->registerParticleEmitter(this); - emit systemChanged(arg); - } - } - - void setGroup(QString arg) - { - if (m_group != arg) { - m_group = arg; - emit groupChanged(arg); - } - } - - void setParticleDurationVariation(int arg) - { - if (m_particleDurationVariation != arg) { - m_particleDurationVariation = arg; - emit particleDurationVariationChanged(arg); - } - } - void setExtruder(QQuickParticleExtruder* arg) - { - if (m_extruder != arg) { - m_extruder = arg; - emit extruderChanged(arg); - } - } - - void setParticleSize(qreal arg) - { - if (m_particleSize != arg) { - m_particleSize = arg; - emit particleSizeChanged(arg); - } - } - - void setParticleEndSize(qreal arg) - { - if (m_particleEndSize != arg) { - m_particleEndSize = arg; - emit particleEndSizeChanged(arg); - } - } - - void setParticleSizeVariation(qreal arg) - { - if (m_particleSizeVariation != arg) { - m_particleSizeVariation = arg; - emit particleSizeVariationChanged(arg); - } - } - - void setSpeed(QQuickDirection * arg) - { - if (m_speed != arg) { - m_speed = arg; - emit speedChanged(arg); - } - } - - void setAcceleration(QQuickDirection * arg) - { - if (m_acceleration != arg) { - m_acceleration = arg; - emit accelerationChanged(arg); - } - } - - void setMaxParticleCount(int arg); - - void setStartTime(int arg) - { - if (m_startTime != arg) { - m_startTime = arg; - emit startTimeChanged(arg); - } - } - - virtual void reset(); -public: - int particleCount() const; - - QQuickParticleExtruder* extruder() const - { - return m_extruder; - } - - qreal particleSize() const - { - return m_particleSize; - } - - qreal particleEndSize() const - { - return m_particleEndSize; - } - - qreal particleSizeVariation() const - { - return m_particleSizeVariation; - } - - QQuickDirection * speed() const - { - return m_speed; - } - - QQuickDirection * acceleration() const - { - return m_acceleration; - } - - int maxParticleCount() const - { - return m_maxParticleCount; - } - - int startTime() const - { - return m_startTime; - } - -protected: - qreal m_particlesPerSecond; - int m_particleDuration; - int m_particleDurationVariation; - bool m_enabled; - QQuickParticleSystem* m_system; - QString m_group; - QQuickParticleExtruder* m_extruder; - QQuickParticleExtruder* m_defaultExtruder; - QQuickParticleExtruder* effectiveExtruder(); - QQuickDirection * m_speed; - QQuickDirection * m_acceleration; - qreal m_particleSize; - qreal m_particleEndSize; - qreal m_particleSizeVariation; - - qreal m_speedFromMovement; - int m_startTime; - bool m_overwrite; - - int m_pulseLeft; - QList > m_burstQueue; - int m_maxParticleCount; - - //Used in default implementation, but might be useful - qreal m_speed_from_movement; - - int m_emitCap; - bool m_reset_last; - qreal m_last_timestamp; - qreal m_last_emission; - - QPointF m_last_emitter; - QPointF m_last_last_emitter; - QPointF m_last_last_last_emitter; - - bool isEmitConnected(); -private: - QQuickDirection m_nullVector; - -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // PARTICLEEMITTER_H diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquickparticleextruder.cpp qt5-declarative-0.1~git20120423/src/quick/particles/qquickparticleextruder.cpp --- qt5-declarative-0.1~git20120402/src/quick/particles/qquickparticleextruder.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquickparticleextruder.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,71 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qquickparticleextruder_p.h" -#include - -QT_BEGIN_NAMESPACE - -/*! - \qmlclass Shape QQuickParticleExtruder - \inqmlmodule QtQuick.Particles 2 - \brief The Shape element allows you to specify an area for affectors and emitter. - - The base class is just a rectangle. -*/ - -QQuickParticleExtruder::QQuickParticleExtruder(QObject *parent) : - QObject(parent) -{ -} - -QPointF QQuickParticleExtruder::extrude(const QRectF &rect) -{ - return QPointF(((qreal)rand() / RAND_MAX) * rect.width() + rect.x(), - ((qreal)rand() / RAND_MAX) * rect.height() + rect.y()); -} - -bool QQuickParticleExtruder::contains(const QRectF &bounds, const QPointF &point) -{ - return bounds.contains(point); -} - -QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquickparticleextruder_p.h qt5-declarative-0.1~git20120423/src/quick/particles/qquickparticleextruder_p.h --- qt5-declarative-0.1~git20120402/src/quick/particles/qquickparticleextruder_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquickparticleextruder_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,71 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef PARTICLEEXTRUDER_H -#define PARTICLEEXTRUDER_H - -#include -#include -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -class QQuickParticleExtruder : public QObject -{ - Q_OBJECT - -public: - explicit QQuickParticleExtruder(QObject *parent = 0); - virtual QPointF extrude(const QRectF &); - virtual bool contains(const QRectF &bounds, const QPointF &point); - -signals: -public slots: -protected: -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // PARTICLEEXTRUDER_H diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquickparticlegroup.cpp qt5-declarative-0.1~git20120423/src/quick/particles/qquickparticlegroup.cpp --- qt5-declarative-0.1~git20120402/src/quick/particles/qquickparticlegroup.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquickparticlegroup.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,143 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qquickparticlegroup_p.h" - -/*! - \qmlclass ParticleGroup QQuickParticleGroup - \inqmlmodule QtQuick.Particles 2 - \brief ParticleGroup elements allow you to set attributes on a logical particle group. - - This element allows you to set timed transitions on particle groups. - - You can also use this element to group particle system elements related to the logical - particle group. Emitters, Affectors and Painters set as direct children of a ParticleGroup - will automatically apply to that logical particle group. TrailEmitters will automatically follow - the group. - - If a ParticleGroup element is not defined for a group, the group will function normally as if - none of the transition properties were set. -*/ -/*! - \qmlproperty ParticleSystem QtQuick.Particles2::ParticleGroup::system - This is the system which will contain the group. - - If the ParticleGroup is a direct child of a ParticleSystem, it will automatically be associated with it. -*/ -/*! - \qmlproperty string QtQuick.Particles2::ParticleGroup::name - This is the name of the particle group, and how it is generally referred to by other elements. - - If elements refer to a name which does not have an explicit ParticleGroup created, it will - work normally (with no transitions specified for the group). If you do not need to assign - duration based transitions to a group, you do not need to create a ParticleGroup with that name (although you may). -*/ -/*! - \qmlproperty int QtQuick.Particles2::ParticleGroup::duration - The time in milliseconds before the group will attempt to transition. - -*/ -/*! - \qmlproperty ParticleSystem QtQuick.Particles2::ParticleGroup::durationVariation - The maximum number of milliseconds that the duration of the transition cycle varies per particle in the group. - - Default value is zero. -*/ -/*! - \qmlproperty ParticleSystem QtQuick.Particles2::ParticleGroup::to - The weighted list of transitions valid for this group. - - If the chosen transition stays in this group, another duration (+/- up to durationVariation) - milliseconds will occur before another transition is attempted. -*/ - -QQuickParticleGroup::QQuickParticleGroup(QObject* parent) - : QQuickStochasticState(parent) - , m_system(0) -{ - -} - -void delayedRedirect(QQmlListProperty *prop, QObject *value) -{ - QQuickParticleGroup* pg = qobject_cast(prop->object); - if (pg) - pg->delayRedirect(value); -} - -QQmlListProperty QQuickParticleGroup::particleChildren() -{ - QQuickParticleSystem* system = qobject_cast(parent()); - if (system) - return QQmlListProperty(this, 0, &QQuickParticleSystem::statePropertyRedirect); - else - return QQmlListProperty(this, 0, &delayedRedirect); -} - -void QQuickParticleGroup::setSystem(QQuickParticleSystem* arg) -{ - if (m_system != arg) { - m_system = arg; - m_system->registerParticleGroup(this); - performDelayedRedirects(); - emit systemChanged(arg); - } -} - -void QQuickParticleGroup::delayRedirect(QObject *obj) -{ - m_delayedRedirects << obj; -} - -void QQuickParticleGroup::performDelayedRedirects() -{ - if (!m_system) - return; - foreach (QObject* obj, m_delayedRedirects) - m_system->stateRedirect(this, m_system, obj); - - m_delayedRedirects.clear(); -} - -void QQuickParticleGroup::componentComplete(){ - if (!m_system && qobject_cast(parent())) - setSystem(qobject_cast(parent())); -} diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquickparticlegroup_p.h qt5-declarative-0.1~git20120423/src/quick/particles/qquickparticlegroup_p.h --- qt5-declarative-0.1~git20120402/src/quick/particles/qquickparticlegroup_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquickparticlegroup_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,112 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef QQuickPARTICLEGROUP -#define QQuickPARTICLEGROUP -#include -#include "qquickparticlesystem_p.h" -#include "qqmlparserstatus.h" - -QT_BEGIN_NAMESPACE - -class QQuickParticleGroup : public QQuickStochasticState, public QQmlParserStatus -{ - Q_OBJECT - //### Would setting limits per group be useful? Or clutter the API? - //Q_PROPERTY(int maximumAlive READ maximumAlive WRITE setMaximumAlive NOTIFY maximumAliveChanged) - - Q_PROPERTY(QQuickParticleSystem* system READ system WRITE setSystem NOTIFY systemChanged) - - //Intercept children requests and assign to the group & system - Q_PROPERTY(QQmlListProperty particleChildren READ particleChildren DESIGNABLE false)//### Hidden property for in-state system definitions - ought not to be used in actual "Sprite" states - Q_CLASSINFO("DefaultProperty", "particleChildren") - Q_INTERFACES(QQmlParserStatus) - -public: - explicit QQuickParticleGroup(QObject* parent = 0); - - QQmlListProperty particleChildren(); - - int maximumAlive() const - { - return m_maximumAlive; - } - - QQuickParticleSystem* system() const - { - return m_system; - } - -public slots: - - void setMaximumAlive(int arg) - { - if (m_maximumAlive != arg) { - m_maximumAlive = arg; - emit maximumAliveChanged(arg); - } - } - - void setSystem(QQuickParticleSystem* arg); - - void delayRedirect(QObject* obj); - -signals: - - void maximumAliveChanged(int arg); - - void systemChanged(QQuickParticleSystem* arg); - -protected: - virtual void componentComplete(); - virtual void classBegin(){;} - -private: - - void performDelayedRedirects(); - - int m_maximumAlive; - QQuickParticleSystem* m_system; - QList m_delayedRedirects; -}; - -QT_END_NAMESPACE - -#endif diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquickparticlepainter.cpp qt5-declarative-0.1~git20120423/src/quick/particles/qquickparticlepainter.cpp --- qt5-declarative-0.1~git20120402/src/quick/particles/qquickparticlepainter.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquickparticlepainter.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,165 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qquickparticlepainter_p.h" -#include -#include -QT_BEGIN_NAMESPACE -/*! - \qmlclass ParticlePainter QQuickParticlePainter - \inqmlmodule QtQuick.Particles 2 - \inherits ParticlePainter - \brief ParticlePainter elements allow you to specify how to paint particles. - - The default implementation paints nothing. See the subclasses if you want to - paint something visible. - -*/ -/*! - \qmlproperty ParticleSystem QtQuick.Particles2::ParticlePainter::system - This is the system whose particles can be painted by the element. - If the ParticlePainter is a direct child of a ParticleSystem, it will automatically be associated with it. -*/ -/*! - \qmlproperty list QtQuick.Particles2::ParticlePainter::groups - Which logical particle groups will be painted. - - If empty, it will paint the default particle group (""). -*/ -QQuickParticlePainter::QQuickParticlePainter(QQuickItem *parent) : - QQuickItem(parent), - m_system(0), m_count(0), m_pleaseReset(true), m_canvas(0) -{ -} - -void QQuickParticlePainter::itemChange(ItemChange change, const ItemChangeData &data) -{ - if (change == QQuickItem::ItemSceneChange) { - if (m_canvas) - disconnect(m_canvas, SIGNAL(sceneGraphInvalidated()), this, SLOT(sceneGraphInvalidated())); - m_canvas = data.canvas; - if (m_canvas) - connect(m_canvas, SIGNAL(sceneGraphInvalidated()), this, SLOT(sceneGraphInvalidated()), Qt::DirectConnection); - - } -} - -void QQuickParticlePainter::componentComplete() -{ - if (!m_system && qobject_cast(parentItem())) - setSystem(qobject_cast(parentItem())); - QQuickItem::componentComplete(); -} - - -void QQuickParticlePainter::setSystem(QQuickParticleSystem *arg) -{ - if (m_system != arg) { - m_system = arg; - if (m_system){ - m_system->registerParticlePainter(this); - reset(); - } - emit systemChanged(arg); - } -} - -void QQuickParticlePainter::load(QQuickParticleData* d) -{ - initialize(d->group, d->index); - if (m_pleaseReset) - return; - m_pendingCommits << qMakePair(d->group, d->index); -} - -void QQuickParticlePainter::reload(QQuickParticleData* d) -{ - if (m_pleaseReset) - return; - m_pendingCommits << qMakePair(d->group, d->index); -} - -void QQuickParticlePainter::reset() -{ - m_pendingCommits.clear(); - m_pleaseReset = true; -} - -void QQuickParticlePainter::setCount(int c)//### TODO: some resizeing so that particles can reallocate on size change instead of recreate -{ - Q_ASSERT(c >= 0); //XXX - if (c == m_count) - return; - m_count = c; - emit countChanged(); - reset(); -} - -int QQuickParticlePainter::count() -{ - return m_count; -} - -void QQuickParticlePainter::calcSystemOffset(bool resetPending) -{ - if (!m_system || !parentItem()) - return; - QPointF lastOffset = m_systemOffset; - m_systemOffset = -1 * this->mapFromItem(m_system, QPointF(0.0, 0.0)); - if (lastOffset != m_systemOffset && !resetPending){ - //Reload all particles//TODO: Necessary? - foreach (const QString &g, m_groups){ - int gId = m_system->groupIds[g]; - foreach (QQuickParticleData* d, m_system->groupData[gId]->data) - reload(d); - } - } -} -typedef QPair intPair; -void QQuickParticlePainter::performPendingCommits() -{ - calcSystemOffset(); - foreach (intPair p, m_pendingCommits) - commit(p.first, p.second); - m_pendingCommits.clear(); -} - -QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquickparticlepainter_p.h qt5-declarative-0.1~git20120423/src/quick/particles/qquickparticlepainter_p.h --- qt5-declarative-0.1~git20120402/src/quick/particles/qquickparticlepainter_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquickparticlepainter_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,137 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef PARTICLE_H -#define PARTICLE_H - -#include -#include -#include -#include "qquickparticlesystem_p.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -class QQuickParticlePainter : public QQuickItem -{ - Q_OBJECT - Q_PROPERTY(QQuickParticleSystem* system READ system WRITE setSystem NOTIFY systemChanged) - Q_PROPERTY(QStringList groups READ groups WRITE setGroups NOTIFY groupsChanged) - -public: - explicit QQuickParticlePainter(QQuickItem *parent = 0); - //Data Interface to system - void load(QQuickParticleData*); - void reload(QQuickParticleData*); - void setCount(int c); - int count(); - void performPendingCommits();//Called from updatePaintNode - QQuickParticleSystem* system() const - { - return m_system; - } - - - QStringList groups() const - { - return m_groups; - } - - void itemChange(ItemChange, const ItemChangeData &); - -signals: - void countChanged(); - void systemChanged(QQuickParticleSystem* arg); - - void groupsChanged(QStringList arg); - -public slots: - void setSystem(QQuickParticleSystem* arg); - - void setGroups(QStringList arg) - { - if (m_groups != arg) { - m_groups = arg; - //Note: The system watches this as it has to recalc things when groups change. It will request a reset if necessary - emit groupsChanged(arg); - } - } - - void calcSystemOffset(bool resetPending = false); - -private slots: - virtual void sceneGraphInvalidated() {} - -protected: - /* Reset resets all your internal data structures. But anything attached to a particle should - be in attached data. So reset + reloads should have no visible effect. - ###Hunt down all cases where we do a complete reset for convenience and be more targeted - */ - virtual void reset(); - - virtual void componentComplete(); - virtual void initialize(int gIdx, int pIdx){//Called from main thread - Q_UNUSED(gIdx); - Q_UNUSED(pIdx); - } - virtual void commit(int gIdx, int pIdx){//Called in Render Thread - //###If you need to do something on size changed, check m_data size in this? Or we reset you every time? - Q_UNUSED(gIdx); - Q_UNUSED(pIdx); - } - - QQuickParticleSystem* m_system; - friend class QQuickParticleSystem; - int m_count; - bool m_pleaseReset;//Used by subclasses, but it's a nice optimization to know when stuff isn't going to matter. - QStringList m_groups; - QPointF m_systemOffset; - - QQuickCanvas *m_canvas; - -private: - QSet > m_pendingCommits; -}; - -QT_END_NAMESPACE -QT_END_HEADER -#endif // PARTICLE_H diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquickparticlesmodule.cpp qt5-declarative-0.1~git20120423/src/quick/particles/qquickparticlesmodule.cpp --- qt5-declarative-0.1~git20120402/src/quick/particles/qquickparticlesmodule.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquickparticlesmodule.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,120 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qquickangledirection_p.h" -#include "qquickcustomparticle_p.h" -#include "qquickellipseextruder_p.h" -#include "qquicktrailemitter_p.h" -#include "qquickfriction_p.h" -#include "qquickgravity_p.h" -#include "qquickimageparticle_p.h" -#include "qquickitemparticle_p.h" -#include "qquickage_p.h" -#include "qquicklineextruder_p.h" -#include "qquickmaskextruder_p.h" -#include "qquickparticleaffector_p.h" -#include "qquickparticleemitter_p.h" -#include "qquickparticleextruder_p.h" -#include "qquickparticlepainter_p.h" -#include "qquickparticlesmodule_p.h" -#include "qquickparticlesystem_p.h" -#include "qquickpointattractor_p.h" -#include "qquickpointdirection_p.h" -#include "qquickspritegoal_p.h" -#include "qquickdirection_p.h" -#include "qquicktargetdirection_p.h" -#include "qquickturbulence_p.h" -#include "qquickwander_p.h" -#include "qquickcumulativedirection_p.h" -#include "qquickcustomaffector_p.h" -#include "qquickrectangleextruder_p.h" -#include "qquickparticlegroup_p.h" -#include "qquickgroupgoal_p.h" - -QT_BEGIN_NAMESPACE - -void QQuickParticlesModule::defineModule() -{ - const char* uri = "QtQuick.Particles"; - - qmlRegisterType(uri, 2, 0, "ParticleSystem"); - qmlRegisterType(uri, 2, 0, "ParticleGroup"); - - qmlRegisterType(uri, 2, 0, "ImageParticle"); - qmlRegisterType(uri, 2, 0, "CustomParticle"); - qmlRegisterType(uri, 2, 0, "ItemParticle"); - - qmlRegisterType(uri, 2, 0, "Emitter"); - qmlRegisterType(uri, 2, 0, "TrailEmitter"); - - qmlRegisterType(uri, 2, 0, "EllipseShape"); - qmlRegisterType(uri, 2, 0, "RectangleShape"); - qmlRegisterType(uri, 2, 0, "LineShape"); - qmlRegisterType(uri, 2, 0, "MaskShape"); - - qmlRegisterType(uri, 2, 0, "PointDirection"); - qmlRegisterType(uri, 2, 0, "AngleDirection"); - qmlRegisterType(uri, 2, 0, "TargetDirection"); - qmlRegisterType(uri, 2, 0, "CumulativeDirection"); - - qmlRegisterType(uri, 2, 0, "Affector"); - qmlRegisterType(uri, 2, 0, "Wander"); - qmlRegisterType(uri, 2, 0, "Friction"); - qmlRegisterType(uri, 2, 0, "Attractor"); - qmlRegisterType(uri, 2, 0, "Gravity"); - qmlRegisterType(uri, 2, 0, "Age"); - qmlRegisterType(uri, 2, 0, "SpriteGoal"); - qmlRegisterType(uri, 2, 0, "GroupGoal"); - qmlRegisterType(uri, 2, 0 , "Turbulence"); - - //Exposed just for completeness - qmlRegisterUncreatableType(uri, 2, 0, "ParticleAffector", - QStringLiteral("Abstract type. Use one of the inheriting types instead.")); - qmlRegisterUncreatableType(uri, 2, 0, "ParticlePainter", - QStringLiteral("Abstract type. Use one of the inheriting types instead.")); - qmlRegisterUncreatableType(uri, 2, 0, "ParticleExtruder", - QStringLiteral("Abstract type. Use one of the inheriting types instead.")); - qmlRegisterUncreatableType(uri, 2, 0, "NullVector", - QStringLiteral("Abstract type. Use one of the inheriting types instead.")); -} - -QT_END_NAMESPACE - diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquickparticlesmodule_p.h qt5-declarative-0.1~git20120423/src/quick/particles/qquickparticlesmodule_p.h --- qt5-declarative-0.1~git20120402/src/quick/particles/qquickparticlesmodule_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquickparticlesmodule_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,61 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QQuickPARTICLESMODULE_H -#define QQuickPARTICLESMODULE_H - -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -class QQuickParticlesModule -{ -public: - static void defineModule(); -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QQuickPARTICLESMODULE_H diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquickparticlesystem.cpp qt5-declarative-0.1~git20120423/src/quick/particles/qquickparticlesystem.cpp --- qt5-declarative-0.1~git20120402/src/quick/particles/qquickparticlesystem.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquickparticlesystem.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,1164 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qquickparticlesystem_p.h" -#include -#include "qquickparticleemitter_p.h" -#include "qquickparticleaffector_p.h" -#include "qquickparticlepainter_p.h" -#include -#include -#include "qquickv8particledata_p.h" -#include "qquickparticlegroup_p.h" - -#include "qquicktrailemitter_p.h"//###For auto-follow on states, perhaps should be in emitter? -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE -//###Switch to define later, for now user-friendly (no compilation) debugging is worth it -DEFINE_BOOL_CONFIG_OPTION(qmlParticlesDebug, QML_PARTICLES_DEBUG) - - -/* \internal ParticleSystem internals documentation - - Affectors, Painters, Emitters and Groups all register themselves on construction as a callback - from their setSystem (or componentComplete if they have a system from a parent). - - Particle data is stored by group, They have a group index (used by the particle system almost - everywhere) and a global index (used by the Stochastic state engine powering stochastic group - transitions). Each group has a recycling list/heap that stores the particle data. - - The recycling list/heap is a heap of particle data sorted by when they're expected to die. If - they die prematurely then they are marked as reusable (and will probably still be alive when - they exit the heap). If they have their life extended, then they aren't dead when expected. - If this happens, they go back in the heap with the new estimate. If they have died on schedule, - then the indexes are marked as reusable. If no indexes are reusable when new particles are - requested, then the list is extended. This relatively complex datastructure is because memory - allocation and deallocation on this scale proved to be a significant performance cost. In order - to reuse the indexes validly (even when particles can have their life extended or cut short - dynamically, or particle counts grow) this seemed to be the most efficient option for keeping - track of which indices could be reused. - - When a new particle is emitted, the emitter gets a new datum from the group (through the - system), and sets properties on it. Then it's passed back to the group briefly so that it can - now guess when the particle will die. Then the painters get a change to initialize properties - as well, since particle data includes shared data from painters as well as logical particle - data. - - Every animation advance, the simulation advances by running all emitters for the elapsed - duration, then running all affectors, then telling all particle painters to update changed - particles. The ParticlePainter superclass stores these changes, and they are implemented - when the painter is called to paint in the render thread. - - Particle group changes move the particle from one group to another by killing the old particle - and then creating a new one with the same data in the new group. - - Note that currently groups only grow. Given that data is stored in vectors, it is non-trivial - to pluck out the unused indexes when the count goes down. Given the dynamic nature of the - system, it is difficult to tell if those unused data instances will be used again. Still, - some form of garbage collection is on the long term plan. -*/ - -/*! - \qmlclass ParticleSystem QQuickParticleSystem - \inqmlmodule QtQuick.Particles 2 - \brief The ParticleSystem brings together ParticlePainter, Emitter and Affector elements. - -*/ - -/*! - \qmlproperty bool QtQuick.Particles2::ParticleSystem::running - - If running is set to false, the particle system will stop the simulation. All particles - will be destroyed when the system is set to running again. - - It can also be controlled with the start() and stop() methods. -*/ - - -/*! - \qmlproperty bool QtQuick.Particles2::ParticleSystem::paused - - If paused is set to true, the particle system will not advance the simulation. When - paused is set to false again, the simulation will resume from the same point it was - paused. - - The simulation will automatically pause if it detects that there are no live particles - left, and unpause when new live particles are added. - - It can also be controlled with the pause() and resume() methods. -*/ - -/*! - \qmlproperty bool QtQuick.Particles2::ParticleSystem::empty - - empty is set to true when there are no live particles left in the system. - - You can use this to pause the system, keeping it from spending any time updating, - but you will need to resume it in order for additional particles to be generated - by the system. - - To kill all the particles in the system, use a Kill affector. -*/ - -/*! - \qmlproperty list QtQuick.Particles2::ParticleSystem::particleStates - - You can define a sub-set of particle groups in this property in order to provide them - with stochastic state transitions. - - Each QtQuick2::Sprite in this list is interpreted as corresponding to the particle group - with ths same name. Any transitions defined in these sprites will take effect on the particle - groups as well. Additionally TrailEmitters, Affectors and ParticlePainters definined - inside one of these sprites are automatically associated with the corresponding particle group. -*/ - -/*! - \qmlmethod void QtQuick.Particles2::ParticleSystem::pause - - Pauses the simulation if it is running. - - \sa resume, paused -*/ - -/*! - \qmlmethod void QtQuick.Particles2::ParticleSystem::resume - - Resumes the simulation if it is paused. - - \sa pause, paused -*/ - -/*! - \qmlmethod void QtQuick.Particles2::ParticleSystem::start - - Starts the simulation if it has not already running. - - \sa stop, restart, running -*/ - -/*! - \qmlmethod void QtQuick.Particles2::ParticleSystem::stop - - Stops the simulation if it is running. - - \sa start, restart, running -*/ - -/*! - \qmlmethod void QtQuick.Particles2::ParticleSystem::restart - - Stops the simulation if it is running, and then starts it. - - \sa stop, restart, running -*/ -/*! - \qmlmethod void QtQuick.Particles2::ParticleSystem::reset - - Discards all currently existing particles. - -*/ -const qreal EPSILON = 0.001; -//Utility functions for when within 1ms is close enough -bool timeEqualOrGreater(qreal a, qreal b) -{ - return (a+EPSILON >= b); -} - -bool timeLess(qreal a, qreal b) -{ - return (a-EPSILON < b); -} - -bool timeEqual(qreal a, qreal b) -{ - return (a+EPSILON > b) && (a-EPSILON < b); -} - -int roundedTime(qreal a) -{// in ms - return (int)qRound(a*1000.0); -} - -QQuickParticleDataHeap::QQuickParticleDataHeap() - : m_data(0) -{ - m_data.reserve(1000); - clear(); -} - -void QQuickParticleDataHeap::grow() //###Consider automatic growth vs resize() calls from GroupData -{ - m_data.resize(1 << ++m_size); -} - -void QQuickParticleDataHeap::insert(QQuickParticleData* data) -{ - insertTimed(data, roundedTime(data->t + data->lifeSpan)); -} - -void QQuickParticleDataHeap::insertTimed(QQuickParticleData* data, int time) -{ - //TODO: Optimize 0 lifespan (or already dead) case - if (m_lookups.contains(time)) { - m_data[m_lookups[time]].data << data; - return; - } - if (m_end == (1 << m_size)) - grow(); - m_data[m_end].time = time; - m_data[m_end].data.clear(); - m_data[m_end].data.insert(data); - m_lookups.insert(time, m_end); - bubbleUp(m_end++); -} - -int QQuickParticleDataHeap::top() -{ - if (m_end == 0) - return 1 << 30; - return m_data[0].time; -} - -QSet QQuickParticleDataHeap::pop() -{ - if (!m_end) - return QSet (); - QSet ret = m_data[0].data; - m_lookups.remove(m_data[0].time); - if (m_end == 1) { - --m_end; - } else { - m_data[0] = m_data[--m_end]; - bubbleDown(0); - } - return ret; -} - -void QQuickParticleDataHeap::clear() -{ - m_size = 0; - m_end = 0; - //m_size is in powers of two. So to start at 0 we have one allocated - m_data.resize(1); - m_lookups.clear(); -} - -bool QQuickParticleDataHeap::contains(QQuickParticleData* d) -{ - for (int i=0; i= m_end) - return; - int lesser = left; - int right = idx*2 + 2; - if (right < m_end) { - if (m_data[left].time > m_data[right].time) - lesser = right; - } - if (m_data[idx].time > m_data[lesser].time) { - swap(idx, lesser); - bubbleDown(lesser); - } -} - -QQuickParticleGroupData::QQuickParticleGroupData(int id, QQuickParticleSystem* sys):index(id),m_size(0),m_system(sys) -{ - initList(); -} - -QQuickParticleGroupData::~QQuickParticleGroupData() -{ - foreach (QQuickParticleData* d, data) - delete d; -} - -int QQuickParticleGroupData::size() -{ - return m_size; -} - -QString QQuickParticleGroupData::name()//### Worth caching as well? -{ - return m_system->groupIds.key(index); -} - -void QQuickParticleGroupData::setSize(int newSize) -{ - if (newSize == m_size) - return; - Q_ASSERT(newSize > m_size);//XXX allow shrinking - data.resize(newSize); - for (int i=m_size; igroup = index; - data[i]->index = i; - reusableIndexes << i; - } - int delta = newSize - m_size; - m_size = newSize; - foreach (QQuickParticlePainter* p, painters) - p->setCount(p->count() + delta); -} - -void QQuickParticleGroupData::initList() -{ - dataHeap.clear(); -} - -void QQuickParticleGroupData::kill(QQuickParticleData* d) -{ - Q_ASSERT(d->group == index); - d->lifeSpan = 0;//Kill off - foreach (QQuickParticlePainter* p, painters) - p->reload(d); - reusableIndexes << d->index; -} - -QQuickParticleData* QQuickParticleGroupData::newDatum(bool respectsLimits) -{ - //recycle();//Extra recycler round to be sure? - - while (!reusableIndexes.empty()) { - int idx = *(reusableIndexes.begin()); - reusableIndexes.remove(idx); - if (data[idx]->stillAlive()) {// ### This means resurrection of 'dead' particles. Is that allowed? - prepareRecycler(data[idx]); - continue; - } - return data[idx]; - } - if (respectsLimits) - return 0; - - int oldSize = m_size; - setSize(oldSize + 10);//###+1,10%,+10? Choose something non-arbitrarily - reusableIndexes.remove(oldSize); - return data[oldSize]; -} - -bool QQuickParticleGroupData::recycle() -{ - while (dataHeap.top() <= m_system->timeInt) { - foreach (QQuickParticleData* datum, dataHeap.pop()) { - if (!datum->stillAlive()) { - reusableIndexes << datum->index; - } else { - prepareRecycler(datum); //ttl has been altered mid-way, put it back - } - } - } - - //TODO: If the data is clear, gc (consider shrinking stack size)? - return reusableIndexes.count() == m_size; -} - -void QQuickParticleGroupData::prepareRecycler(QQuickParticleData* d) -{ - if (d->lifeSpan*1000 < m_system->maxLife) { - dataHeap.insert(d); - } else { - while ((roundedTime(d->t) + 2*m_system->maxLife/3) <= m_system->timeInt) - d->extendLife(m_system->maxLife/3000.0); - dataHeap.insertTimed(d, roundedTime(d->t) + 2*m_system->maxLife/3); - } -} - -QQuickParticleData::QQuickParticleData(QQuickParticleSystem* sys) - : group(0) - , e(0) - , system(sys) - , index(0) - , systemIndex(-1) - , colorOwner(0) - , rotationOwner(0) - , deformationOwner(0) - , animationOwner(0) - , v8Datum(0) -{ - x = 0; - y = 0; - t = -1; - lifeSpan = 0; - size = 0; - endSize = 0; - vx = 0; - vy = 0; - ax = 0; - ay = 0; - xx = 1; - xy = 0; - yx = 0; - yy = 1; - rotation = 0; - rotationSpeed = 0; - autoRotate = 0; - animIdx = 0; - frameDuration = 1; - frameAt = -1; - frameCount = 1; - animT = -1; - animX = 0; - animY = 0; - animWidth = 1; - animHeight = 1; - color.r = 255; - color.g = 255; - color.b = 255; - color.a = 255; - r = 0; - delegate = 0; - modelIndex = -1; -} - -QQuickParticleData::~QQuickParticleData() -{ - delete v8Datum; -} - -void QQuickParticleData::clone(const QQuickParticleData& other) -{ - x = other.x; - y = other.y; - t = other.t; - lifeSpan = other.lifeSpan; - size = other.size; - endSize = other.endSize; - vx = other.vx; - vy = other.vy; - ax = other.ax; - ay = other.ay; - xx = other.xx; - xy = other.xy; - yx = other.yx; - yy = other.yy; - rotation = other.rotation; - rotationSpeed = other.rotationSpeed; - autoRotate = other.autoRotate; - animIdx = other.animIdx; - frameDuration = other.frameDuration; - frameCount = other.frameCount; - animT = other.animT; - animX = other.animX; - animY = other.animY; - animWidth = other.animWidth; - animHeight = other.animHeight; - color.r = other.color.r; - color.g = other.color.g; - color.b = other.color.b; - color.a = other.color.a; - r = other.r; - delegate = other.delegate; - modelIndex = other.modelIndex; - - colorOwner = other.colorOwner; - rotationOwner = other.rotationOwner; - deformationOwner = other.deformationOwner; - animationOwner = other.animationOwner; -} - -QQmlV8Handle QQuickParticleData::v8Value() -{ - if (!v8Datum) - v8Datum = new QQuickV8ParticleData(QQmlEnginePrivate::getV8Engine(qmlEngine(system)), this); - return v8Datum->v8Value(); -} -//sets the x accleration without affecting the instantaneous x velocity or position -void QQuickParticleData::setInstantaneousAX(qreal ax) -{ - qreal t = (system->timeInt / 1000.0) - this->t; - qreal vx = (this->vx + t*this->ax) - t*ax; - qreal ex = this->x + this->vx * t + 0.5 * this->ax * t * t; - qreal x = ex - t*vx - 0.5 * t*t*ax; - - this->ax = ax; - this->vx = vx; - this->x = x; -} - -//sets the x velocity without affecting the instantaneous x postion -void QQuickParticleData::setInstantaneousVX(qreal vx) -{ - qreal t = (system->timeInt / 1000.0) - this->t; - qreal evx = vx - t*this->ax; - qreal ex = this->x + this->vx * t + 0.5 * this->ax * t * t; - qreal x = ex - t*evx - 0.5 * t*t*this->ax; - - this->vx = evx; - this->x = x; -} - -//sets the instantaneous x postion -void QQuickParticleData::setInstantaneousX(qreal x) -{ - qreal t = (system->timeInt / 1000.0) - this->t; - this->x = x - t*this->vx - 0.5 * t*t*this->ax; -} - -//sets the y accleration without affecting the instantaneous y velocity or position -void QQuickParticleData::setInstantaneousAY(qreal ay) -{ - qreal t = (system->timeInt / 1000.0) - this->t; - qreal vy = (this->vy + t*this->ay) - t*ay; - qreal ey = this->y + this->vy * t + 0.5 * this->ay * t * t; - qreal y = ey - t*vy - 0.5 * t*t*ay; - - this->ay = ay; - this->vy = vy; - this->y = y; -} - -//sets the y velocity without affecting the instantaneous y position -void QQuickParticleData::setInstantaneousVY(qreal vy) -{ - qreal t = (system->timeInt / 1000.0) - this->t; - qreal evy = vy - t*this->ay; - qreal ey = this->y + this->vy * t + 0.5 * this->ay * t * t; - qreal y = ey - t*evy - 0.5 * t*t*this->ay; - - this->vy = evy; - this->y = y; -} - -//sets the instantaneous Y position -void QQuickParticleData::setInstantaneousY(qreal y) -{ - qreal t = (system->timeInt / 1000.0) - this->t; - this->y = y - t*this->vy - 0.5 * t*t*this->ay; -} - -qreal QQuickParticleData::curX() const -{ - qreal t = (system->timeInt / 1000.0) - this->t; - return this->x + this->vx * t + 0.5 * this->ax * t * t; -} - -qreal QQuickParticleData::curVX() const -{ - qreal t = (system->timeInt / 1000.0) - this->t; - return this->vx + t*this->ax; -} - -qreal QQuickParticleData::curY() const -{ - qreal t = (system->timeInt / 1000.0) - this->t; - return y + vy * t + 0.5 * ay * t * t; -} - -qreal QQuickParticleData::curVY() const -{ - qreal t = (system->timeInt / 1000.0) - this->t; - return vy + t*ay; -} - -void QQuickParticleData::debugDump() -{ - qDebug() << "Particle" << systemIndex << group << "/" << index << stillAlive() - << "Pos: " << x << "," << y - << "Vel: " << vx << "," << vy - << "Acc: " << ax << "," << ay - << "Size: " << size << "," << endSize - << "Time: " << t << "," <timeInt / 1000.0) ; -} - -bool QQuickParticleData::stillAlive() -{ - if (!system) - return false; - return (t + lifeSpan - EPSILON) > ((qreal)system->timeInt/1000.0); -} - -bool QQuickParticleData::alive() -{ - if (!system) - return false; - qreal st = ((qreal)system->timeInt/1000.0); - return (t + EPSILON) < st && (t + lifeSpan - EPSILON) > st; -} - -float QQuickParticleData::curSize() -{ - if (!system || !lifeSpan) - return 0.0f; - return size + (endSize - size) * (1 - (lifeLeft() / lifeSpan)); -} - -float QQuickParticleData::lifeLeft() -{ - if (!system) - return 0.0f; - return (t + lifeSpan) - (system->timeInt/1000.0); -} - -void QQuickParticleData::extendLife(float time) -{ - qreal newX = curX(); - qreal newY = curY(); - qreal newVX = curVX(); - qreal newVY = curVY(); - - t += time; - animT += time; - - qreal elapsed = (system->timeInt / 1000.0) - t; - qreal evy = newVY - elapsed*ay; - qreal ey = newY - elapsed*evy - 0.5 * elapsed*elapsed*ay; - qreal evx = newVX - elapsed*ax; - qreal ex = newX - elapsed*evx - 0.5 * elapsed*elapsed*ax; - - x = ex; - vx = evx; - y = ey; - vy = evy; -} - -QQuickParticleSystem::QQuickParticleSystem(QQuickItem *parent) : - QQuickItem(parent), - stateEngine(0), - m_animation(0), - m_running(true), - initialized(0), - particleCount(0), - m_nextIndex(0), - m_componentComplete(false), - m_paused(false), - m_empty(true) -{ - connect(&m_painterMapper, SIGNAL(mapped(QObject*)), - this, SLOT(loadPainter(QObject*))); - - m_debugMode = qmlParticlesDebug(); -} - -QQuickParticleSystem::~QQuickParticleSystem() -{ - foreach (QQuickParticleGroupData* gd, groupData) - delete gd; -} - -void QQuickParticleSystem::initGroups() -{ - m_reusableIndexes.clear(); - m_nextIndex = 0; - - qDeleteAll(groupData); - groupData.clear(); - groupIds.clear(); - - QQuickParticleGroupData* gd = new QQuickParticleGroupData(0, this);//Default group - groupData.insert(0,gd); - groupIds.insert(QString(), 0); - m_nextGroupId = 1; -} - -void QQuickParticleSystem::registerParticlePainter(QQuickParticlePainter* p) -{ - if (m_debugMode) - qDebug() << "Registering Painter" << p << "to" << this; - //TODO: a way to Unregister emitters, painters and affectors - m_painters << QPointer(p);//###Set or uniqueness checking? - connect(p, SIGNAL(groupsChanged(QStringList)), - &m_painterMapper, SLOT(map())); - loadPainter(p); -} - -void QQuickParticleSystem::registerParticleEmitter(QQuickParticleEmitter* e) -{ - if (m_debugMode) - qDebug() << "Registering Emitter" << e << "to" << this; - m_emitters << QPointer(e);//###How to get them out? - connect(e, SIGNAL(particleCountChanged()), - this, SLOT(emittersChanged())); - connect(e, SIGNAL(groupChanged(QString)), - this, SLOT(emittersChanged())); - emittersChanged(); - e->reset();//Start, so that starttime factors appropriately -} - -void QQuickParticleSystem::registerParticleAffector(QQuickParticleAffector* a) -{ - if (m_debugMode) - qDebug() << "Registering Affector" << a << "to" << this; - m_affectors << QPointer(a); -} - -void QQuickParticleSystem::registerParticleGroup(QQuickParticleGroup* g) -{ - if (m_debugMode) - qDebug() << "Registering Group" << g << "to" << this; - m_groups << QPointer(g); - createEngine(); -} - -void QQuickParticleSystem::setRunning(bool arg) -{ - if (m_running != arg) { - m_running = arg; - emit runningChanged(arg); - setPaused(false); - if (m_animation)//Not created until componentCompleted - m_running ? m_animation->start() : m_animation->stop(); - reset(); - } -} - -void QQuickParticleSystem::setPaused(bool arg) { - if (m_paused != arg) { - m_paused = arg; - if (m_animation && m_animation->state() != QAbstractAnimation::Stopped) - m_paused ? m_animation->pause() : m_animation->resume(); - if (!m_paused) { - foreach (QQuickParticlePainter *p, m_painters) - p->update(); - } - emit pausedChanged(arg); - } -} - -void QQuickParticleSystem::statePropertyRedirect(QQmlListProperty *prop, QObject *value) -{ - //Hooks up automatic state-associated stuff - QQuickParticleSystem* sys = qobject_cast(prop->object->parent()); - QQuickParticleGroup* group = qobject_cast(prop->object); - if (!group || !sys || !value) - return; - stateRedirect(group, sys, value); -} - -void QQuickParticleSystem::stateRedirect(QQuickParticleGroup* group, QQuickParticleSystem* sys, QObject *value) -{ - QStringList list; - list << group->name(); - QQuickParticleAffector* a = qobject_cast(value); - if (a) { - a->setParentItem(sys); - a->setGroups(list); - a->setSystem(sys); - return; - } - QQuickTrailEmitter* fe = qobject_cast(value); - if (fe) { - fe->setParentItem(sys); - fe->setFollow(group->name()); - fe->setSystem(sys); - return; - } - QQuickParticleEmitter* e = qobject_cast(value); - if (e) { - e->setParentItem(sys); - e->setGroup(group->name()); - e->setSystem(sys); - return; - } - QQuickParticlePainter* p = qobject_cast(value); - if (p) { - p->setParentItem(sys); - p->setGroups(list); - p->setSystem(sys); - return; - } - qWarning() << value << " was placed inside a particle system state but cannot be taken into the particle system. It will be lost."; -} - -void QQuickParticleSystem::componentComplete() - -{ - QQuickItem::componentComplete(); - m_componentComplete = true; - m_animation = new QQuickParticleSystemAnimation(this); - reset();//restarts animation as well -} - -void QQuickParticleSystem::reset() -{ - if (!m_componentComplete) - return; - - timeInt = 0; - //Clear guarded pointers which have been deleted - int cleared = 0; - cleared += m_emitters.removeAll(0); - cleared += m_painters.removeAll(0); - cleared += m_affectors.removeAll(0); - - bySysIdx.resize(0); - initGroups();//Also clears all logical particles - - if (!m_running) - return; - - foreach (QQuickParticleEmitter* e, m_emitters) - e->reset(); - - emittersChanged(); - - foreach (QQuickParticlePainter *p, m_painters) { - loadPainter(p); - p->reset(); - } - - //### Do affectors need reset too? - if (m_animation) {//Animation is explicitly disabled in benchmarks - //reset restarts animation (if running) - if ((m_animation->state() == QAbstractAnimation::Running)) - m_animation->stop(); - m_animation->start(); - if (m_paused) - m_animation->pause(); - } - - initialized = true; -} - - -void QQuickParticleSystem::loadPainter(QObject *p) -{ - if (!m_componentComplete || !p) - return; - - QQuickParticlePainter* painter = qobject_cast(p); - Q_ASSERT(painter);//XXX - foreach (QQuickParticleGroupData* sg, groupData) - sg->painters.remove(painter); - int particleCount = 0; - if (painter->groups().isEmpty()) {//Uses default particle - QStringList def; - def << QString(); - painter->setGroups(def); - particleCount += groupData[0]->size(); - groupData[0]->painters << painter; - } else { - foreach (const QString &group, painter->groups()) { - if (group != QLatin1String("") && !groupIds[group]) {//new group - int id = m_nextGroupId++; - QQuickParticleGroupData* gd = new QQuickParticleGroupData(id, this); - groupIds.insert(group, id); - groupData.insert(id, gd); - } - particleCount += groupData[groupIds[group]]->size(); - groupData[groupIds[group]]->painters << painter; - } - } - painter->setCount(particleCount); - painter->update();//Initial update here - return; -} - -void QQuickParticleSystem::emittersChanged() -{ - if (!m_componentComplete) - return; - - m_emitters.removeAll(0); - - - QList previousSizes; - QList newSizes; - for (int i=0; isize(); - newSizes << 0; - } - - foreach (QQuickParticleEmitter* e, m_emitters) {//Populate groups and set sizes. - if (!groupIds.contains(e->group()) - || (!e->group().isEmpty() && !groupIds[e->group()])) {//or it was accidentally inserted by a failed lookup earlier - int id = m_nextGroupId++; - QQuickParticleGroupData* gd = new QQuickParticleGroupData(id, this); - groupIds.insert(e->group(), id); - groupData.insert(id, gd); - previousSizes << 0; - newSizes << 0; - } - newSizes[groupIds[e->group()]] += e->particleCount(); - //###: Cull emptied groups? - } - - //TODO: Garbage collection? - particleCount = 0; - for (int i=0; isetSize(qMax(newSizes[i], previousSizes[i])); - particleCount += groupData[i]->size(); - } - - if (m_debugMode) - qDebug() << "Particle system emitters changed. New particle count: " << particleCount; - - if (particleCount > bySysIdx.size())//New datum requests haven't updated it - bySysIdx.resize(particleCount); - - foreach (QQuickParticleAffector *a, m_affectors)//Groups may have changed - a->m_updateIntSet = true; - - foreach (QQuickParticlePainter *p, m_painters) - loadPainter(p); - - if (!m_groups.isEmpty()) - createEngine(); - -} - -void QQuickParticleSystem::createEngine() -{ - if (!m_componentComplete) - return; - if (stateEngine && m_debugMode) - qDebug() << "Resetting Existing Sprite Engine..."; - //### Solve the losses if size/states go down - foreach (QQuickParticleGroup* group, m_groups) { - bool exists = false; - foreach (const QString &name, groupIds.keys()) - if (group->name() == name) - exists = true; - if (!exists) { - int id = m_nextGroupId++; - QQuickParticleGroupData* gd = new QQuickParticleGroupData(id, this); - groupIds.insert(group->name(), id); - groupData.insert(id, gd); - } - } - - if (m_groups.count()) { - //Reorder groups List so as to have the same order as groupData - QList newList; - for (int i=0; iname(); - foreach (QQuickParticleGroup* existing, m_groups) { - if (existing->name() == name) { - newList << existing; - exists = true; - } - } - if (!exists) { - newList << new QQuickParticleGroup(this); - newList.back()->setName(name); - } - } - m_groups = newList; - QList states; - foreach (QQuickParticleGroup* g, m_groups) - states << (QQuickStochasticState*)g; - - if (!stateEngine) - stateEngine = new QQuickStochasticEngine(this); - stateEngine->setCount(particleCount); - stateEngine->m_states = states; - - connect(stateEngine, SIGNAL(stateChanged(int)), - this, SLOT(particleStateChange(int))); - - } else { - if (stateEngine) - delete stateEngine; - stateEngine = 0; - } - -} - -void QQuickParticleSystem::particleStateChange(int idx) -{ - moveGroups(bySysIdx[idx], stateEngine->curState(idx)); -} - -void QQuickParticleSystem::moveGroups(QQuickParticleData *d, int newGIdx) -{ - if (!d || newGIdx == d->group) - return; - - QQuickParticleData* pd = newDatum(newGIdx, false, d->systemIndex); - if (!pd) - return; - - pd->clone(*d); - finishNewDatum(pd); - - d->systemIndex = -1; - groupData[d->group]->kill(d); -} - -int QQuickParticleSystem::nextSystemIndex() -{ - if (!m_reusableIndexes.isEmpty()) { - int ret = *(m_reusableIndexes.begin()); - m_reusableIndexes.remove(ret); - return ret; - } - if (m_nextIndex >= bySysIdx.size()) { - bySysIdx.resize(bySysIdx.size() < 10 ? 10 : bySysIdx.size()*1.1);//###+1,10%,+10? Choose something non-arbitrarily - if (stateEngine) - stateEngine->setCount(bySysIdx.size()); - - } - return m_nextIndex++; -} - -QQuickParticleData* QQuickParticleSystem::newDatum(int groupId, bool respectLimits, int sysIndex) -{ - Q_ASSERT(groupId < groupData.count());//XXX shouldn't really be an assert - - QQuickParticleData* ret = groupData[groupId]->newDatum(respectLimits); - if (!ret) { - return 0; - } - if (sysIndex == -1) { - if (ret->systemIndex == -1) - ret->systemIndex = nextSystemIndex(); - } else { - if (ret->systemIndex != -1) { - if (stateEngine) - stateEngine->stop(ret->systemIndex); - m_reusableIndexes << ret->systemIndex; - bySysIdx[ret->systemIndex] = 0; - } - ret->systemIndex = sysIndex; - } - bySysIdx[ret->systemIndex] = ret; - - if (stateEngine) - stateEngine->start(ret->systemIndex, ret->group); - - m_empty = false; - return ret; -} - -void QQuickParticleSystem::emitParticle(QQuickParticleData* pd) -{// called from prepareNextFrame()->emitWindow - enforce? - //Account for relative emitter position - QPointF offset = this->mapFromItem(pd->e, QPointF(0, 0)); - if (!offset.isNull()) { - pd->x += offset.x(); - pd->y += offset.y(); - } - - finishNewDatum(pd); -} - -void QQuickParticleSystem::finishNewDatum(QQuickParticleData *pd) -{ - Q_ASSERT(pd); - groupData[pd->group]->prepareRecycler(pd); - - foreach (QQuickParticleAffector *a, m_affectors) - if (a && a->m_needsReset) - a->reset(pd); - foreach (QQuickParticlePainter* p, groupData[pd->group]->painters) - if (p) - p->load(pd); -} - -void QQuickParticleSystem::updateCurrentTime( int currentTime ) -{ - if (!initialized) - return;//error in initialization - - //### Elapsed time never shrinks - may cause problems if left emitting for weeks at a time. - qreal dt = timeInt / 1000.; - timeInt = currentTime; - qreal time = timeInt / 1000.; - dt = time - dt; - needsReset.clear(); - - m_emitters.removeAll(0); - m_painters.removeAll(0); - m_affectors.removeAll(0); - - bool oldClear = m_empty; - m_empty = true; - foreach (QQuickParticleGroupData* gd, groupData)//Recycle all groups and see if they're out of live particles - m_empty = gd->recycle() && m_empty; - - if (stateEngine) - stateEngine->updateSprites(timeInt); - - foreach (QQuickParticleEmitter* emitter, m_emitters) - emitter->emitWindow(timeInt); - foreach (QQuickParticleAffector* a, m_affectors) - a->affectSystem(dt); - foreach (QQuickParticleData* d, needsReset) - foreach (QQuickParticlePainter* p, groupData[d->group]->painters) - p->reload(d); - - if (oldClear != m_empty) - emptyChanged(m_empty); -} - -int QQuickParticleSystem::systemSync(QQuickParticlePainter* p) -{ - if (!m_running) - return 0; - if (!initialized) - return 0;//error in initialization - p->performPendingCommits(); - return timeInt; -} - - -QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquickparticlesystem_p.h qt5-declarative-0.1~git20120423/src/quick/particles/qquickparticlesystem_p.h --- qt5-declarative-0.1~git20120402/src/quick/particles/qquickparticlesystem_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquickparticlesystem_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,379 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef PARTICLESYSTEM_H -#define PARTICLESYSTEM_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include //For QQmlV8Handle - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -class QQuickParticleSystem; -class QQuickParticleAffector; -class QQuickParticleEmitter; -class QQuickParticlePainter; -class QQuickParticleData; -class QQuickParticleSystemAnimation; -class QQuickStochasticEngine; -class QQuickSprite; -class QQuickV8ParticleData; -class QQuickParticleGroup; -class QQuickImageParticle; - -struct QQuickParticleDataHeapNode{ - int time;//in ms - QSet data;//Set ptrs instead? -}; - -class QQuickParticleDataHeap { - //Idea is to do a binary heap, but which also stores a set of int,Node* so that if the int already exists, you can - //add it to the data* list. Pops return the whole list at once. -public: - QQuickParticleDataHeap(); - void insert(QQuickParticleData* data); - void insertTimed(QQuickParticleData* data, int time); - - int top(); - - QSet pop(); - - void clear(); - - bool contains(QQuickParticleData*);//O(n), for debugging purposes only -private: - void grow(); - void swap(int, int); - void bubbleUp(int); - void bubbleDown(int); - int m_size; - int m_end; - QQuickParticleDataHeapNode m_tmp; - QVector m_data; - QHash m_lookups; -}; - -class Q_AUTOTEST_EXPORT QQuickParticleGroupData { -public: - QQuickParticleGroupData(int id, QQuickParticleSystem* sys); - ~QQuickParticleGroupData(); - - int size(); - QString name(); - - void setSize(int newSize); - - int index; - QSet painters;//TODO: What if they are dynamically removed? - - //TODO: Refactor particle data list out into a separate class - QVector data; - QQuickParticleDataHeap dataHeap; - QSet reusableIndexes; - bool recycle(); //Force recycling round, returns true if all indexes are now reusable - - void initList(); - void kill(QQuickParticleData* d); - - //After calling this, initialize, then call prepareRecycler(d) - QQuickParticleData* newDatum(bool respectsLimits); - - //TODO: Find and clean up those that don't get added to the recycler (currently they get lost) - void prepareRecycler(QQuickParticleData* d); - -private: - int m_size; - QQuickParticleSystem* m_system; -}; - -struct Color4ub { - uchar r; - uchar g; - uchar b; - uchar a; -}; - -class Q_AUTOTEST_EXPORT QQuickParticleData { -public: - //TODO: QObject like memory management (without the cost, just attached to system) - QQuickParticleData(QQuickParticleSystem* sys); - ~QQuickParticleData(); - - //Convenience functions for working backwards, because parameters are from the start of particle life - //If setting multiple parameters at once, doing the conversion yourself will be faster. - - //sets the x accleration without affecting the instantaneous x velocity or position - void setInstantaneousAX(qreal ax); - //sets the x velocity without affecting the instantaneous x postion - void setInstantaneousVX(qreal vx); - //sets the instantaneous x postion - void setInstantaneousX(qreal x); - //sets the y accleration without affecting the instantaneous y velocity or position - void setInstantaneousAY(qreal ay); - //sets the y velocity without affecting the instantaneous y postion - void setInstantaneousVY(qreal vy); - //sets the instantaneous Y postion - void setInstantaneousY(qreal y); - - //TODO: Slight caching? - qreal curX() const; - qreal curVX() const; - qreal curAX() const { return ax; } - qreal curY() const; - qreal curVY() const; - qreal curAY() const { return ay; } - - int group; - QQuickParticleEmitter* e;//### Needed? - QQuickParticleSystem* system; - int index; - int systemIndex; - - //General Position Stuff - float x; - float y; - float t; - float lifeSpan; - float size; - float endSize; - float vx; - float vy; - float ax; - float ay; - - //Other stuff, now universally shared - Color4ub color; - float xx; - float xy; - float yx; - float yy; - float rotation; - float rotationSpeed; - float autoRotate;//Assume that GPUs prefer floats to bools - float animIdx; - float frameDuration; - float frameAt;//Used for duration -1 - float frameCount; - float animT; - float animX; - float animY; - float animWidth; - float animHeight; - float r; - QQuickItem* delegate; - int modelIndex; - float update;//Used by custom affectors - - //Used by image particle - QQuickImageParticle* colorOwner; - QQuickImageParticle* rotationOwner; - QQuickImageParticle* deformationOwner; - QQuickImageParticle* animationOwner; - - void debugDump(); - bool stillAlive();//Only checks end, because usually that's all you need and it's a little faster. - bool alive(); - float lifeLeft(); - float curSize(); - void clone(const QQuickParticleData& other);//Not =, leaves meta-data like index - QQmlV8Handle v8Value(); - void extendLife(float time); -private: - QQuickV8ParticleData* v8Datum; -}; - -class Q_AUTOTEST_EXPORT QQuickParticleSystem : public QQuickItem -{ - Q_OBJECT - Q_PROPERTY(bool running READ isRunning WRITE setRunning NOTIFY runningChanged) - Q_PROPERTY(bool paused READ isPaused WRITE setPaused NOTIFY pausedChanged) - Q_PROPERTY(bool empty READ isEmpty NOTIFY emptyChanged) - -public: - explicit QQuickParticleSystem(QQuickItem *parent = 0); - ~QQuickParticleSystem(); - - bool isRunning() const - { - return m_running; - } - - int count(){ return particleCount; } - - static const int maxLife = 600000; - -signals: - - void systemInitialized(); - void runningChanged(bool arg); - void pausedChanged(bool arg); - void emptyChanged(bool arg); - -public slots: - void start(){setRunning(true);} - void stop(){setRunning(false);} - void restart(){setRunning(false);setRunning(true);} - void pause(){setPaused(true);} - void resume(){setPaused(false);} - - void reset(); - void setRunning(bool arg); - void setPaused(bool arg); - - virtual int duration() const { return -1; } - - -protected: - //This one only once per frame (effectively) - void componentComplete(); - -private slots: - void emittersChanged(); - void loadPainter(QObject* p); - void createEngine(); //Not invoked by sprite engine, unlike Sprite uses - void particleStateChange(int idx); - -public: - //These can be called multiple times per frame, performance critical - void emitParticle(QQuickParticleData* p); - QQuickParticleData* newDatum(int groupId, bool respectLimits = true, int sysIdx = -1); - void finishNewDatum(QQuickParticleData*); - void moveGroups(QQuickParticleData *d, int newGIdx); - int nextSystemIndex(); - - //This one only once per painter per frame - int systemSync(QQuickParticlePainter* p); - - //Data members here for ease of related class and auto-test usage. Not "public" API. TODO: d_ptrize - QSet needsReset; - QVector bySysIdx; //Another reference to the data (data owned by group), but by sysIdx - QHash groupIds; - QHash groupData; - QQuickStochasticEngine* stateEngine; - - //Also only here for auto-test usage - void updateCurrentTime( int currentTime ); - QQuickParticleSystemAnimation* m_animation; - bool m_running; - bool m_debugMode; - - int timeInt; - bool initialized; - int particleCount; - - void registerParticlePainter(QQuickParticlePainter* p); - void registerParticleEmitter(QQuickParticleEmitter* e); - void registerParticleAffector(QQuickParticleAffector* a); - void registerParticleGroup(QQuickParticleGroup* g); - - static void statePropertyRedirect(QQmlListProperty *prop, QObject *value); - static void stateRedirect(QQuickParticleGroup* group, QQuickParticleSystem* sys, QObject *value); - bool isPaused() const - { - return m_paused; - } - - bool isEmpty() const - { - return m_empty; - } - -private: - void initializeSystem(); - void initGroups(); - QList > m_emitters; - QList > m_affectors; - QList > m_painters; - QList > m_syncList; - QList m_groups; - int m_nextGroupId; - int m_nextIndex; - QSet m_reusableIndexes; - bool m_componentComplete; - - QSignalMapper m_painterMapper; - QSignalMapper m_emitterMapper; - bool m_paused; - bool m_allDead; - bool m_empty; -}; - -// Internally, this animation drives all the timing. Painters sync up in their updatePaintNode -class QQuickParticleSystemAnimation : public QAbstractAnimation -{ - Q_OBJECT -public: - QQuickParticleSystemAnimation(QQuickParticleSystem* system) - : QAbstractAnimation(static_cast(system)), m_system(system) - { } -protected: - virtual void updateCurrentTime( int t ) - { - m_system->updateCurrentTime(t); - } - - virtual int duration() const - { - return -1; - } - -private: - QQuickParticleSystem* m_system; -}; - - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // PARTICLESYSTEM_H - - diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquickpointattractor.cpp qt5-declarative-0.1~git20120423/src/quick/particles/qquickpointattractor.cpp --- qt5-declarative-0.1~git20120402/src/quick/particles/qquickpointattractor.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquickpointattractor.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,162 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qquickpointattractor_p.h" -#include -#include -QT_BEGIN_NAMESPACE -/*! - \qmlclass Attractor QQuickAttractorAffector - \inqmlmodule QtQuick.Particles 2 - \inherits Affector - \brief The Attractor allows you to attract particles towards a specific point. - - Note that the size and position of this element affects which particles it affects. - The size of the point attracted to is always 0x0, and the location of that point - is specified by the pointX and pointY properties. - - Note that Attractor has the standard Item x,y,width and height properties. - Like other affectors, these represent the affected area. They - do not represent the 0x0 point which is the target of the attraction. -*/ - - -/*! - \qmlproperty real QtQuick.Particles2::PointAttractor::pointX - - The x coordinate of the attracting point. This is relative - to the x coordinate of the Attractor. -*/ -/*! - \qmlproperty real QtQuick.Particles2::PointAttractor::pointY - - The y coordinate of the attracting point. This is relative - to the y coordinate of the Attractor. -*/ -/*! - \qmlproperty real QtQuick.Particles2::PointAttractor::strength - - The pull, in units per second, to be exerted on an item one pixel away. - - Depending on how the attraction is proportionalToDistance this may have to - be very high or very low to have a reasonable effect on particles at a - distance. -*/ -/*! - \qmlproperty AffectableParameter QtQuick.Particles2::Attractor::affectedParameter - - What attribute of particles is directly affected. - \list - \li Attractor.Position - \li Attractor.Velocity - \li Attractor.Acceleration - \endlist -*/ -/*! - \qmlproperty Proportion QtQuick.Particles2::Attractor::proportionalToDistance - - How the distance from the particle to the point affects the strength of the attraction. - - \list - \li Attractor.Constant - \li Attractor.Linear - \li Attractor.InverseLinear - \li Attractor.Quadratic - \li Attractor.InverseQuadratic - \endlist -*/ - - -QQuickAttractorAffector::QQuickAttractorAffector(QQuickItem *parent) : - QQuickParticleAffector(parent), m_strength(0.0), m_x(0), m_y(0) - , m_physics(Velocity), m_proportionalToDistance(Linear) -{ -} - -bool QQuickAttractorAffector::affectParticle(QQuickParticleData *d, qreal dt) -{ - if (m_strength == 0.0) - return false; - qreal dx = m_x+m_offset.x() - d->curX(); - qreal dy = m_y+m_offset.y() - d->curY(); - qreal r = sqrt((dx*dx) + (dy*dy)); - qreal theta = atan2(dy,dx); - qreal ds = 0; - switch (m_proportionalToDistance){ - case InverseQuadratic: - ds = (m_strength / qMax(1.,r*r)); - break; - case InverseLinear: - ds = (m_strength / qMax(1.,r)); - break; - case Quadratic: - ds = (m_strength * qMax(1.,r*r)); - break; - case Linear: - ds = (m_strength * qMax(1.,r)); - break; - default: //also Constant - ds = m_strength; - } - ds *= dt; - dx = ds * cos(theta); - dy = ds * sin(theta); - qreal vx,vy; - switch (m_physics){ - case Position: - d->x = (d->x + dx); - d->y = (d->y + dy); - break; - case Acceleration: - d->setInstantaneousAX(d->ax + dx); - d->setInstantaneousAY(d->ay + dy); - break; - case Velocity: //also default - default: - vx = d->curVX(); - vy = d->curVY(); - d->setInstantaneousVX(vx + dx); - d->setInstantaneousVY(vy + dy); - } - - return true; -} -QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquickpointattractor_p.h qt5-declarative-0.1~git20120423/src/quick/particles/qquickpointattractor_p.h --- qt5-declarative-0.1~git20120402/src/quick/particles/qquickpointattractor_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquickpointattractor_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,167 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef ATTRACTORAFFECTOR_H -#define ATTRACTORAFFECTOR_H -#include "qquickparticleaffector_p.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -class QQuickAttractorAffector : public QQuickParticleAffector -{ - Q_OBJECT - Q_PROPERTY(qreal strength READ strength WRITE setStrength NOTIFY strengthChanged) - Q_PROPERTY(qreal pointX READ pointX WRITE setPointX NOTIFY pointXChanged) - Q_PROPERTY(qreal pointY READ pointY WRITE setPointY NOTIFY pointYChanged) - Q_PROPERTY(AffectableParameters affectedParameter READ affectedParameter WRITE setAffectedParameter NOTIFY affectedParameterChanged) - Q_PROPERTY(Proportion proportionalToDistance READ proportionalToDistance WRITE setProportionalToDistance NOTIFY proportionalToDistanceChanged) - Q_ENUMS(AffectableParameters) - Q_ENUMS(Proportion) - -public: - enum Proportion{ - Constant, - Linear, - Quadratic, - InverseLinear, - InverseQuadratic - }; - - enum AffectableParameters { - Position, - Velocity, - Acceleration - }; - - explicit QQuickAttractorAffector(QQuickItem *parent = 0); - - qreal strength() const - { - return m_strength; - } - - qreal pointX() const - { - return m_x; - } - - qreal pointY() const - { - return m_y; - } - - AffectableParameters affectedParameter() const - { - return m_physics; - } - - Proportion proportionalToDistance() const - { - return m_proportionalToDistance; - } - -signals: - - void strengthChanged(qreal arg); - - void pointXChanged(qreal arg); - - void pointYChanged(qreal arg); - - void affectedParameterChanged(AffectableParameters arg); - - void proportionalToDistanceChanged(Proportion arg); - -public slots: -void setStrength(qreal arg) -{ - if (m_strength != arg) { - m_strength = arg; - emit strengthChanged(arg); - } -} - -void setPointX(qreal arg) -{ - if (m_x != arg) { - m_x = arg; - emit pointXChanged(arg); - } -} - -void setPointY(qreal arg) -{ - if (m_y != arg) { - m_y = arg; - emit pointYChanged(arg); - } -} -void setAffectedParameter(AffectableParameters arg) -{ - if (m_physics != arg) { - m_physics = arg; - emit affectedParameterChanged(arg); - } -} - -void setProportionalToDistance(Proportion arg) -{ - if (m_proportionalToDistance != arg) { - m_proportionalToDistance = arg; - emit proportionalToDistanceChanged(arg); - } -} - -protected: - virtual bool affectParticle(QQuickParticleData *d, qreal dt); -private: -qreal m_strength; -qreal m_x; -qreal m_y; -AffectableParameters m_physics; -Proportion m_proportionalToDistance; -}; - -QT_END_NAMESPACE -QT_END_HEADER -#endif // ATTRACTORAFFECTOR_H diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquickpointdirection.cpp qt5-declarative-0.1~git20120423/src/quick/particles/qquickpointdirection.cpp --- qt5-declarative-0.1~git20120402/src/quick/particles/qquickpointdirection.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquickpointdirection.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,86 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qquickpointdirection_p.h" -#include - -QT_BEGIN_NAMESPACE - -/*! - \qmlclass PointDirection QQuickPointDirection - \inqmlmodule QtQuick.Particles 2 - \inherits Direction - \brief The PointDirection element allows you to specify a direction that varies in x and y components - - The PointDirection element allows both the specification of a direction by x and y components, - as well as varying the parameters by x or y component. -*/ -/*! - \qmlproperty real QtQuick.Particles2::PointDirection::x -*/ -/*! - \qmlproperty real QtQuick.Particles2::PointDirection::y -*/ -/*! - \qmlproperty real QtQuick.Particles2::PointDirection::xVariation -*/ -/*! - \qmlproperty real QtQuick.Particles2::PointDirection::yVariation -*/ - -QQuickPointDirection::QQuickPointDirection(QObject *parent) : - QQuickDirection(parent) - , m_x(0) - , m_y(0) - , m_xVariation(0) - , m_yVariation(0) -{ -} - -const QPointF QQuickPointDirection::sample(const QPointF &) -{ - QPointF ret; - ret.setX(m_x - m_xVariation + rand() / float(RAND_MAX) * m_xVariation * 2); - ret.setY(m_y - m_yVariation + rand() / float(RAND_MAX) * m_yVariation * 2); - return ret; -} - -QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquickpointdirection_p.h qt5-declarative-0.1~git20120423/src/quick/particles/qquickpointdirection_p.h --- qt5-declarative-0.1~git20120402/src/quick/particles/qquickpointdirection_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquickpointdirection_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,133 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef POINTVECTOR_H -#define POINTVECTOR_H -#include "qquickdirection_p.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -class QQuickPointDirection : public QQuickDirection -{ - Q_OBJECT - Q_PROPERTY(qreal x READ x WRITE setX NOTIFY xChanged) - Q_PROPERTY(qreal y READ y WRITE setY NOTIFY yChanged) - Q_PROPERTY(qreal xVariation READ xVariation WRITE setXVariation NOTIFY xVariationChanged) - Q_PROPERTY(qreal yVariation READ yVariation WRITE setYVariation NOTIFY yVariationChanged) -public: - explicit QQuickPointDirection(QObject *parent = 0); - virtual const QPointF sample(const QPointF &from); - qreal x() const - { - return m_x; - } - - qreal y() const - { - return m_y; - } - - qreal xVariation() const - { - return m_xVariation; - } - - qreal yVariation() const - { - return m_yVariation; - } - -signals: - - void xChanged(qreal arg); - - void yChanged(qreal arg); - - void xVariationChanged(qreal arg); - - void yVariationChanged(qreal arg); - -public slots: - void setX(qreal arg) - { - if (m_x != arg) { - m_x = arg; - emit xChanged(arg); - } - } - - void setY(qreal arg) - { - if (m_y != arg) { - m_y = arg; - emit yChanged(arg); - } - } - - void setXVariation(qreal arg) - { - if (m_xVariation != arg) { - m_xVariation = arg; - emit xVariationChanged(arg); - } - } - - void setYVariation(qreal arg) - { - if (m_yVariation != arg) { - m_yVariation = arg; - emit yVariationChanged(arg); - } - } - -private: - - qreal m_x; - qreal m_y; - qreal m_xVariation; - qreal m_yVariation; -}; - -QT_END_NAMESPACE -QT_END_HEADER -#endif // POINTVECTOR_H diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquickrectangleextruder.cpp qt5-declarative-0.1~git20120423/src/quick/particles/qquickrectangleextruder.cpp --- qt5-declarative-0.1~git20120402/src/quick/particles/qquickrectangleextruder.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquickrectangleextruder.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,87 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qquickrectangleextruder_p.h" -#include - -QT_BEGIN_NAMESPACE - -/*! - \qmlclass RectangleShape QQuickRectangleExtruder - \inqmlmodule QtQuick.Particles 2 - \brief The RectangleShape element allows you to specify an area for affectors and emitter. - - Just a rectangle. -*/ - -QQuickRectangleExtruder::QQuickRectangleExtruder(QObject *parent) : - QQuickParticleExtruder(parent), m_fill(true) -{ -} - -QPointF QQuickRectangleExtruder::extrude(const QRectF &rect) -{ - if (m_fill) - return QPointF(((qreal)rand() / RAND_MAX) * rect.width() + rect.x(), - ((qreal)rand() / RAND_MAX) * rect.height() + rect.y()); - int side = rand() % 4; - switch (side){//TODO: Doesn't this overlap the corners? - case 0: - return QPointF(rect.x(), - ((qreal)rand() / RAND_MAX) * rect.height() + rect.y()); - case 1: - return QPointF(rect.width() + rect.x(), - ((qreal)rand() / RAND_MAX) * rect.height() + rect.y()); - case 2: - return QPointF(((qreal)rand() / RAND_MAX) * rect.width() + rect.x(), - rect.y()); - default: - return QPointF(((qreal)rand() / RAND_MAX) * rect.width() + rect.x(), - rect.height() + rect.y()); - } -} - -bool QQuickRectangleExtruder::contains(const QRectF &bounds, const QPointF &point) -{ - return bounds.contains(point); -} - -QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquickrectangleextruder_p.h qt5-declarative-0.1~git20120423/src/quick/particles/qquickrectangleextruder_p.h --- qt5-declarative-0.1~git20120402/src/quick/particles/qquickrectangleextruder_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquickrectangleextruder_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,86 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef RECTANGLEEXTRUDER_H -#define RECTANGLEEXTRUDER_H - -#include "qquickparticleextruder_p.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -class QQuickRectangleExtruder : public QQuickParticleExtruder -{ - Q_OBJECT - Q_PROPERTY(bool fill READ fill WRITE setFill NOTIFY fillChanged) - -public: - explicit QQuickRectangleExtruder(QObject *parent = 0); - virtual QPointF extrude(const QRectF &); - virtual bool contains(const QRectF &bounds, const QPointF &point); - bool fill() const - { - return m_fill; - } - -signals: - - void fillChanged(bool arg); - -public slots: - - void setFill(bool arg) - { - if (m_fill != arg) { - m_fill = arg; - emit fillChanged(arg); - } - } -protected: - bool m_fill; -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // RectangleEXTRUDER_H diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquickspritegoal.cpp qt5-declarative-0.1~git20120423/src/quick/particles/qquickspritegoal.cpp --- qt5-declarative-0.1~git20120402/src/quick/particles/qquickspritegoal.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquickspritegoal.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,153 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qquickspritegoal_p.h" -#include -#include -#include "qquickimageparticle_p.h" -#include - -QT_BEGIN_NAMESPACE - -/*! - \qmlclass SpriteGoal QQuickSpriteGoalAffector - \inqmlmodule QtQuick.Particles 2 - \inherits Affector - \brief The SpriteGoal Affector allows you to change the state of a sprite particle. - -*/ -/*! - \qmlproperty string QtQuick.Particles2::SpriteGoal::goalState - - The name of the Sprite which the affected particles should move to. - - Sprite states have defined durations and transitions between them, setting goalState - will cause it to disregard any path weightings (including 0) and head down the path - which will reach the goalState quickest. It will pass through intermediate states - on that path. -*/ -/*! - \qmlproperty bool QtQuick.Particles2::SpriteGoal::jump - - If true, affected sprites will jump directly to the goal state instead of taking the - the shortest valid path to get there. They will also not finish their current state, - but immediately move to the beginning of the goal state. - - Default is false. -*/ -/*! - \qmlproperty bool QtQuick.Particles2::SpriteGoal::systemStates - - deprecated, use GroupGoal instead -*/ - -QQuickSpriteGoalAffector::QQuickSpriteGoalAffector(QQuickItem *parent) : - QQuickParticleAffector(parent), - m_goalIdx(-1), - m_lastEngine(0), - m_jump(false), - m_systemStates(false), - m_notUsingEngine(false) -{ - m_ignoresTime = true; -} - -void QQuickSpriteGoalAffector::updateStateIndex(QQuickStochasticEngine* e) -{ - if (m_systemStates){ - m_goalIdx = m_system->groupIds[m_goalState]; - }else{ - m_lastEngine = e; - for (int i=0; istateCount(); i++){ - if (e->state(i)->name() == m_goalState){ - m_goalIdx = i; - return; - } - } - m_goalIdx = -1;//Can't find it - } -} - -void QQuickSpriteGoalAffector::setGoalState(QString arg) -{ - if (m_goalState != arg) { - m_goalState = arg; - emit goalStateChanged(arg); - if (m_goalState.isEmpty()) - m_goalIdx = -1; - else - m_goalIdx = -2; - } -} - -bool QQuickSpriteGoalAffector::affectParticle(QQuickParticleData *d, qreal dt) -{ - Q_UNUSED(dt); - QQuickStochasticEngine *engine = 0; - if (!m_systemStates){ - //TODO: Affect all engines - foreach (QQuickParticlePainter *p, m_system->groupData[d->group]->painters) - if (qobject_cast(p)) - engine = qobject_cast(p)->spriteEngine(); - }else{ - engine = m_system->stateEngine; - if (!engine) - m_notUsingEngine = true; - } - if (!engine && !m_notUsingEngine) - return false; - - if (m_goalIdx == -2 || engine != m_lastEngine) - updateStateIndex(engine); - int index = d->index; - if (m_systemStates) - index = d->systemIndex; - if (m_notUsingEngine){//systemStates && no stochastic states defined. So cut out the engine - //TODO: It's possible to move to a group that is intermediate and not used by painters or emitters - but right now that will redirect to the default group - m_system->moveGroups(d, m_goalIdx); - }else if (engine->curState(index) != m_goalIdx){ - engine->setGoal(m_goalIdx, index, m_jump); - return true; //Doesn't affect particle data, but necessary for onceOff - } - return false; -} - -QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquickspritegoal_p.h qt5-declarative-0.1~git20120423/src/quick/particles/qquickspritegoal_p.h --- qt5-declarative-0.1~git20120402/src/quick/particles/qquickspritegoal_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquickspritegoal_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,123 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef SPRITEGOALAFFECTOR_H -#define SPRITEGOALAFFECTOR_H -#include "qquickparticleaffector_p.h" -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -class QQuickStochasticEngine; - -class QQuickSpriteGoalAffector : public QQuickParticleAffector -{ - Q_OBJECT - Q_PROPERTY(QString goalState READ goalState WRITE setGoalState NOTIFY goalStateChanged) - Q_PROPERTY(bool jump READ jump WRITE setJump NOTIFY jumpChanged) - Q_PROPERTY(bool systemStates READ systemStates WRITE setSystemStates NOTIFY systemStatesChanged) -public: - explicit QQuickSpriteGoalAffector(QQuickItem *parent = 0); - - QString goalState() const - { - return m_goalState; - } - - bool jump() const - { - return m_jump; - } - bool systemStates() const - { - return m_systemStates; - } - -protected: - virtual bool affectParticle(QQuickParticleData *d, qreal dt); -signals: - - void goalStateChanged(QString arg); - - void jumpChanged(bool arg); - - void systemStatesChanged(bool arg); - -public slots: - -void setGoalState(QString arg); - -void setJump(bool arg) -{ - if (m_jump != arg) { - m_jump = arg; - emit jumpChanged(arg); - } -} - -void setSystemStates(bool arg) -{ - if (m_systemStates != arg) { - //TODO: GroupGoal was added (and this deprecated) Oct 4 - remove it in a few weeks. - qmlInfo(this) << "systemStates is deprecated and will be removed soon. Use GroupGoal instead."; - m_systemStates = arg; - emit systemStatesChanged(arg); - } -} - -private: - void updateStateIndex(QQuickStochasticEngine* e); - QString m_goalState; - int m_goalIdx; - QQuickStochasticEngine* m_lastEngine; - bool m_jump; - bool m_systemStates; - - bool m_notUsingEngine; -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // SPRITEGOALAFFECTOR_H diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquicktargetdirection.cpp qt5-declarative-0.1~git20120423/src/quick/particles/qquicktargetdirection.cpp --- qt5-declarative-0.1~git20120402/src/quick/particles/qquicktargetdirection.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquicktargetdirection.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,131 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qquicktargetdirection_p.h" -#include "qquickparticleemitter_p.h" -#include -#include - -QT_BEGIN_NAMESPACE -/*! - \qmlclass TargetDirection QQuickTargetDirection - \inqmlmodule QtQuick.Particles 2 - \inherits Direction - \brief The TargetDirection element allows you to specify a direction towards the target point - -*/ -/*! - \qmlproperty real QtQuick.Particles2::TargetDirection::targetX -*/ -/*! - \qmlproperty real QtQuick.Particles2::TargetDirection::targetY -*/ -/*! - \qmlproperty Item QtQuick.Particles2::TargetDirection::targetItem - If specified, this will take precedence over targetX and targetY. - The targeted point will be the center of the specified Item -*/ -/*! - \qmlproperty real QtQuick.Particles2::TargetDirection::targetVariation -*/ -/*! - \qmlproperty real QtQuick.Particles2::TargetDirection::magnitude -*/ -/*! - \qmlproperty real QtQuick.Particles2::TargetDirection::magnitudeVariation -*/ -/*! - \qmlproperty bool QtQuick.Particles2::TargetDirection::proportionalMagnitude - - If true, then the value of magnitude and magnitudeVariation shall be interpreted as multiples - of the distance between the source point and the target point, per second. - - If false(default), then the value of magnitude and magnitudeVariation shall be interpreted as - pixels per second. -*/ - -QQuickTargetDirection::QQuickTargetDirection(QObject *parent) : - QQuickDirection(parent) - , m_targetX(0) - , m_targetY(0) - , m_targetVariation(0) - , m_proportionalMagnitude(false) - , m_magnitude(0) - , m_magnitudeVariation(0) - , m_targetItem(0) -{ -} - -const QPointF QQuickTargetDirection::sample(const QPointF &from) -{ - //###This approach loses interpolating the last position of the target (like we could with the emitter) is it worthwhile? - QPointF ret; - qreal targetX; - qreal targetY; - if (m_targetItem){ - QQuickParticleEmitter* parentEmitter = qobject_cast(parent()); - targetX = m_targetItem->width()/2; - targetY = m_targetItem->height()/2; - if (!parentEmitter){ - qWarning() << "Directed vector is not a child of the emitter. Mapping of target item coordinates may fail."; - targetX += m_targetItem->x(); - targetY += m_targetItem->y(); - }else{ - ret = parentEmitter->mapFromItem(m_targetItem, QPointF(targetX, targetY)); - targetX = ret.x(); - targetY = ret.y(); - } - }else{ - targetX = m_targetX; - targetY = m_targetY; - } - targetX += 0 - from.x() - m_targetVariation + rand()/(float)RAND_MAX * m_targetVariation*2; - targetY += 0 - from.y() - m_targetVariation + rand()/(float)RAND_MAX * m_targetVariation*2; - qreal theta = atan2(targetY, targetX); - qreal mag = m_magnitude + rand()/(float)RAND_MAX * m_magnitudeVariation * 2 - m_magnitudeVariation; - if (m_proportionalMagnitude) - mag *= sqrt(targetX * targetX + targetY * targetY); - ret.setX(mag * cos(theta)); - ret.setY(mag * sin(theta)); - return ret; -} - -QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquicktargetdirection_p.h qt5-declarative-0.1~git20120423/src/quick/particles/qquicktargetdirection_p.h --- qt5-declarative-0.1~git20120402/src/quick/particles/qquicktargetdirection_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquicktargetdirection_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,189 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DIRECTEDVECTOR_H -#define DIRECTEDVECTOR_H -#include "qquickdirection_p.h" -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -class QQuickItem; -class QQuickTargetDirection : public QQuickDirection -{ - Q_OBJECT - Q_PROPERTY(qreal targetX READ targetX WRITE setTargetX NOTIFY targetXChanged) - Q_PROPERTY(qreal targetY READ targetY WRITE setTargetY NOTIFY targetYChanged) - //If targetItem is set, X/Y are ignored. Aims at middle of item, use variation for variation - Q_PROPERTY(QQuickItem* targetItem READ targetItem WRITE setTargetItem NOTIFY targetItemChanged) - - Q_PROPERTY(qreal targetVariation READ targetVariation WRITE setTargetVariation NOTIFY targetVariationChanged) - - //TODO: An enum would be better - Q_PROPERTY(bool proportionalMagnitude READ proportionalMagnitude WRITE setProportionalMagnitude NOTIFY proprotionalMagnitudeChanged) - Q_PROPERTY(qreal magnitude READ magnitude WRITE setMagnitude NOTIFY magnitudeChanged) - Q_PROPERTY(qreal magnitudeVariation READ magnitudeVariation WRITE setMagnitudeVariation NOTIFY magnitudeVariationChanged) - -public: - explicit QQuickTargetDirection(QObject *parent = 0); - virtual const QPointF sample(const QPointF &from); - - qreal targetX() const - { - return m_targetX; - } - - qreal targetY() const - { - return m_targetY; - } - - qreal targetVariation() const - { - return m_targetVariation; - } - - qreal magnitude() const - { - return m_magnitude; - } - - bool proportionalMagnitude() const - { - return m_proportionalMagnitude; - } - - qreal magnitudeVariation() const - { - return m_magnitudeVariation; - } - - QQuickItem* targetItem() const - { - return m_targetItem; - } - -signals: - - void targetXChanged(qreal arg); - - void targetYChanged(qreal arg); - - void targetVariationChanged(qreal arg); - - void magnitudeChanged(qreal arg); - - void proprotionalMagnitudeChanged(bool arg); - - void magnitudeVariationChanged(qreal arg); - - void targetItemChanged(QQuickItem* arg); - -public slots: - void setTargetX(qreal arg) - { - if (m_targetX != arg) { - m_targetX = arg; - emit targetXChanged(arg); - } - } - - void setTargetY(qreal arg) - { - if (m_targetY != arg) { - m_targetY = arg; - emit targetYChanged(arg); - } - } - - void setTargetVariation(qreal arg) - { - if (m_targetVariation != arg) { - m_targetVariation = arg; - emit targetVariationChanged(arg); - } - } - - void setMagnitude(qreal arg) - { - if (m_magnitude != arg) { - m_magnitude = arg; - emit magnitudeChanged(arg); - } - } - - void setProportionalMagnitude(bool arg) - { - if (m_proportionalMagnitude != arg) { - m_proportionalMagnitude = arg; - emit proprotionalMagnitudeChanged(arg); - } - } - - void setMagnitudeVariation(qreal arg) - { - if (m_magnitudeVariation != arg) { - m_magnitudeVariation = arg; - emit magnitudeVariationChanged(arg); - } - } - - void setTargetItem(QQuickItem* arg) - { - if (m_targetItem != arg) { - m_targetItem = arg; - emit targetItemChanged(arg); - } - } - -private: - qreal m_targetX; - qreal m_targetY; - qreal m_targetVariation; - bool m_proportionalMagnitude; - qreal m_magnitude; - qreal m_magnitudeVariation; - QQuickItem *m_targetItem; -}; - -QT_END_NAMESPACE -QT_END_HEADER -#endif // DIRECTEDVECTOR_H diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquicktrailemitter.cpp qt5-declarative-0.1~git20120423/src/quick/particles/qquicktrailemitter.cpp --- qt5-declarative-0.1~git20120402/src/quick/particles/qquicktrailemitter.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquicktrailemitter.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,285 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qquicktrailemitter_p.h" -#include -#include -QT_BEGIN_NAMESPACE - -/*! - \qmlclass TrailEmitter QQuickTrailEmitter - \inqmlmodule QtQuick.Particles 2 - \inherits QQuickParticleEmitter - \brief The TrailEmitter element allows you to emit logical particles from other logical particles. - - This element emits logical particles into the ParticleSystem, with the - starting positions based on those of other logical particles. -*/ -QQuickTrailEmitter::QQuickTrailEmitter(QQuickItem *parent) : - QQuickParticleEmitter(parent) - , m_particlesPerParticlePerSecond(0) - , m_lastTimeStamp(0) - , m_emitterXVariation(0) - , m_emitterYVariation(0) - , m_followCount(0) - , m_emissionExtruder(0) - , m_defaultEmissionExtruder(new QQuickParticleExtruder(this)) -{ - //TODO: If followed increased their size - connect(this, SIGNAL(followChanged(QString)), - this, SLOT(recalcParticlesPerSecond())); - connect(this, SIGNAL(particleDurationChanged(int)), - this, SLOT(recalcParticlesPerSecond())); - connect(this, SIGNAL(particlesPerParticlePerSecondChanged(int)), - this, SLOT(recalcParticlesPerSecond())); -} - -/*! - \qmlproperty string QtQuick.Particles2::TrailEmitter::follow - - The type of logical particle which this is emitting from. -*/ -/*! - \qmlproperty qreal QtQuick.Particles2::TrailEmitter::speedFromMovement - - If this value is non-zero, then any movement of the emitter will provide additional - starting velocity to the particles based on the movement. The additional vector will be the - same angle as the emitter's movement, with a magnitude that is the magnitude of the emitters - movement multiplied by speedFromMovement. - - Default value is 0. -*/ -/*! - \qmlproperty Shape QtQuick.Particles2::TrailEmitter::emitShape - - As the area of a TrailEmitter is the area it follows, a separate shape can be provided - to be the shape it emits out of. This shape has width and height specified by emitWidth - and emitHeight, and is centered on the followed particle's position. - - The default shape is a filled Rectangle. -*/ -/*! - \qmlproperty real QtQuick.Particles2::TrailEmitter::emitWidth - - The width in pixels the emitShape is scaled to. If set to TrailEmitter.ParticleSize, - the width will be the current size of the particle being followed. - - Default is 0. -*/ -/*! - \qmlproperty real QtQuick.Particles2::TrailEmitter::emitHeight - - The height in pixels the emitShape is scaled to. If set to TrailEmitter.ParticleSize, - the height will be the current size of the particle being followed. - - Default is 0. -*/ -/*! - \qmlproperty real QtQuick.Particles2::TrailEmitter::emitRatePerParticle -*/ -/*! - \qmlsignal QtQuick.Particles2::TrailEmitter::emitFollowParticles(Array particles, real followed) - - This handler is called when particles are emitted from the \a followed particle. \a particles contains an array of particle objects which can be directly manipulated. - - If you use this signal handler, emitParticles will not be emitted. - -*/ - -bool QQuickTrailEmitter::isEmitFollowConnected() -{ - static int idx = QObjectPrivate::get(this)->signalIndex("emitFollowParticles(QQmlV8Handle,QQmlV8Handle)"); - return QObjectPrivate::get(this)->isSignalConnected(idx); -} - -void QQuickTrailEmitter::recalcParticlesPerSecond(){ - if (!m_system) - return; - m_followCount = m_system->groupData[m_system->groupIds[m_follow]]->size(); - if (!m_followCount){ - setParticlesPerSecond(1);//XXX: Fix this horrendous hack, needed so they aren't turned off from start (causes crashes - test that when gone you don't crash with 0 PPPS) - }else{ - setParticlesPerSecond(m_particlesPerParticlePerSecond * m_followCount); - m_lastEmission.resize(m_followCount); - m_lastEmission.fill(m_lastTimeStamp); - } -} - -void QQuickTrailEmitter::reset() -{ - m_followCount = 0; -} - -void QQuickTrailEmitter::emitWindow(int timeStamp) -{ - if (m_system == 0) - return; - if (!m_enabled && !m_pulseLeft && m_burstQueue.isEmpty()) - return; - if (m_followCount != m_system->groupData[m_system->groupIds[m_follow]]->size()){ - qreal oldPPS = m_particlesPerSecond; - recalcParticlesPerSecond(); - if (m_particlesPerSecond != oldPPS) - return;//system may need to update - } - - if (m_pulseLeft){ - m_pulseLeft -= timeStamp - m_lastTimeStamp * 1000.; - if (m_pulseLeft < 0){ - timeStamp += m_pulseLeft; - m_pulseLeft = 0; - } - } - - //TODO: Implement startTime and speedFromMovement - qreal time = timeStamp / 1000.; - qreal particleRatio = 1. / m_particlesPerParticlePerSecond; - qreal pt; - qreal maxLife = (m_particleDuration + m_particleDurationVariation)/1000.0; - - //Have to map it into this system, because particlesystem automaps it back - QPointF offset = m_system->mapFromItem(this, QPointF(0, 0)); - qreal sizeAtEnd = m_particleEndSize >= 0 ? m_particleEndSize : m_particleSize; - - int gId = m_system->groupIds[m_follow]; - int gId2 = m_system->groupIds[m_group]; - for (int i=0; igroupData[gId]->data.count(); i++) { - QQuickParticleData *d = m_system->groupData[gId]->data[i]; - if (!d->stillAlive()){ - m_lastEmission[i] = time; //Should only start emitting when it returns to life - continue; - } - pt = m_lastEmission[i]; - if (pt < d->t) - pt = d->t; - if (pt + maxLife < time)//We missed so much, that we should skip emiting particles that are dead by now - pt = time - maxLife; - - if ((width() || height()) && !effectiveExtruder()->contains(QRectF(offset.x(), offset.y(), width(), height()),QPointF(d->curX(), d->curY()))){ - m_lastEmission[d->index] = time;//jump over this time period without emitting, because it's outside - continue; - } - - QList toEmit; - - while (pt < time || !m_burstQueue.isEmpty()){ - QQuickParticleData* datum = m_system->newDatum(gId2, !m_overwrite); - if (datum){//else, skip this emission - datum->e = this;//###useful? - - // Particle timestamp - datum->t = pt; - datum->lifeSpan = - (m_particleDuration - + ((rand() % ((m_particleDurationVariation*2) + 1)) - m_particleDurationVariation)) - / 1000.0; - - // Particle position - // Note that burst location doesn't get used for follow emitter - qreal followT = pt - d->t; - qreal followT2 = followT * followT * 0.5; - qreal eW = m_emitterXVariation < 0 ? d->curSize() : m_emitterXVariation; - qreal eH = m_emitterYVariation < 0 ? d->curSize() : m_emitterYVariation; - //Subtract offset, because PS expects this in emitter coordinates - QRectF boundsRect(d->x - offset.x() + d->vx * followT + d->ax * followT2 - eW/2, - d->y - offset.y() + d->vy * followT + d->ay * followT2 - eH/2, - eW, eH); - - QQuickParticleExtruder* effectiveEmissionExtruder = m_emissionExtruder ? m_emissionExtruder : m_defaultEmissionExtruder; - const QPointF &newPos = effectiveEmissionExtruder->extrude(boundsRect); - datum->x = newPos.x(); - datum->y = newPos.y(); - - // Particle speed - const QPointF &speed = m_speed->sample(newPos); - datum->vx = speed.x() - + m_speed_from_movement * d->vx; - datum->vy = speed.y() - + m_speed_from_movement * d->vy; - - // Particle acceleration - const QPointF &accel = m_acceleration->sample(newPos); - datum->ax = accel.x(); - datum->ay = accel.y(); - - // Particle size - float sizeVariation = -m_particleSizeVariation - + rand() / float(RAND_MAX) * m_particleSizeVariation * 2; - - float size = qMax((qreal)0.0, m_particleSize + sizeVariation); - float endSize = qMax((qreal)0.0, sizeAtEnd + sizeVariation); - - datum->size = size * float(m_enabled); - datum->endSize = endSize * float(m_enabled); - - toEmit << datum; - - m_system->emitParticle(datum); - } - if (!m_burstQueue.isEmpty()){ - m_burstQueue.first().first--; - if (m_burstQueue.first().first <= 0) - m_burstQueue.pop_front(); - }else{ - pt += particleRatio; - } - } - - if (isEmitConnected() || isEmitFollowConnected()) { - v8::HandleScope handle_scope; - v8::Context::Scope scope(QQmlEnginePrivate::getV8Engine(qmlEngine(this))->context()); - v8::Handle array = v8::Array::New(toEmit.size()); - for (int i=0; iSet(i, toEmit[i]->v8Value().toHandle()); - - if (isEmitFollowConnected()) - emitFollowParticles(QQmlV8Handle::fromHandle(array), d->v8Value());//A chance for many arbitrary JS changes - else if (isEmitConnected()) - emitParticles(QQmlV8Handle::fromHandle(array));//A chance for arbitrary JS changes - } - foreach (QQuickParticleData* d, toEmit) - m_system->emitParticle(d); - m_lastEmission[d->index] = pt; - } - - m_lastTimeStamp = time; -} -QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquicktrailemitter_p.h qt5-declarative-0.1~git20120423/src/quick/particles/qquicktrailemitter_p.h --- qt5-declarative-0.1~git20120402/src/quick/particles/qquicktrailemitter_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquicktrailemitter_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,168 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef FOLLOWEMITTER_H -#define FOLLOWEMITTER_H -#include "qquickparticleemitter_p.h" -#include "qquickparticleaffector_p.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -class QQuickTrailEmitter : public QQuickParticleEmitter -{ - Q_OBJECT - Q_PROPERTY(QString follow READ follow WRITE setFollow NOTIFY followChanged) - Q_PROPERTY(int emitRatePerParticle READ particlesPerParticlePerSecond WRITE setParticlesPerParticlePerSecond NOTIFY particlesPerParticlePerSecondChanged) - - Q_PROPERTY(QQuickParticleExtruder* emitShape READ emissonShape WRITE setEmissionShape NOTIFY emissionShapeChanged) - Q_PROPERTY(qreal emitHeight READ emitterYVariation WRITE setEmitterYVariation NOTIFY emitterYVariationChanged) - Q_PROPERTY(qreal emitWidth READ emitterXVariation WRITE setEmitterXVariation NOTIFY emitterXVariationChanged) - - Q_ENUMS(EmitSize) -public: - enum EmitSize { - ParticleSize = -2//Anything less than 0 will do - }; - explicit QQuickTrailEmitter(QQuickItem *parent = 0); - virtual void emitWindow(int timeStamp); - virtual void reset(); - - int particlesPerParticlePerSecond() const - { - return m_particlesPerParticlePerSecond; - } - - qreal emitterXVariation() const - { - return m_emitterXVariation; - } - - qreal emitterYVariation() const - { - return m_emitterYVariation; - } - - QString follow() const - { - return m_follow; - } - - QQuickParticleExtruder* emissonShape() const - { - return m_emissionExtruder; - } - -signals: - void emitFollowParticles(QQmlV8Handle particles, QQmlV8Handle followed); - - void particlesPerParticlePerSecondChanged(int arg); - - void emitterXVariationChanged(qreal arg); - - void emitterYVariationChanged(qreal arg); - - void followChanged(QString arg); - - void emissionShapeChanged(QQuickParticleExtruder* arg); - -public slots: - - void setParticlesPerParticlePerSecond(int arg) - { - if (m_particlesPerParticlePerSecond != arg) { - m_particlesPerParticlePerSecond = arg; - emit particlesPerParticlePerSecondChanged(arg); - } - } - void setEmitterXVariation(qreal arg) - { - if (m_emitterXVariation != arg) { - m_emitterXVariation = arg; - emit emitterXVariationChanged(arg); - } - } - - void setEmitterYVariation(qreal arg) - { - if (m_emitterYVariation != arg) { - m_emitterYVariation = arg; - emit emitterYVariationChanged(arg); - } - } - - void setFollow(QString arg) - { - if (m_follow != arg) { - m_follow = arg; - emit followChanged(arg); - } - } - - void setEmissionShape(QQuickParticleExtruder* arg) - { - if (m_emissionExtruder != arg) { - m_emissionExtruder = arg; - emit emissionShapeChanged(arg); - } - } - -private slots: - void recalcParticlesPerSecond(); - -private: - QSet m_pending; - QVector m_lastEmission; - int m_particlesPerParticlePerSecond; - qreal m_lastTimeStamp; - qreal m_emitterXVariation; - qreal m_emitterYVariation; - QString m_follow; - int m_followCount; - QQuickParticleExtruder* m_emissionExtruder; - QQuickParticleExtruder* m_defaultEmissionExtruder; - bool isEmitFollowConnected(); -}; - -QT_END_NAMESPACE -QT_END_HEADER -#endif // FOLLOWEMITTER_H diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquickturbulence.cpp qt5-declarative-0.1~git20120423/src/quick/particles/qquickturbulence.cpp --- qt5-declarative-0.1~git20120402/src/quick/particles/qquickturbulence.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquickturbulence.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,205 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qquickturbulence_p.h" -#include "qquickparticlepainter_p.h"//TODO: Why was this needed again? -#include -#include -#include -QT_BEGIN_NAMESPACE - -/*! - \qmlclass Turbulence QQuickTurbulenceAffector - \inqmlmodule QtQuick.Particles 2 - \inherits Affector - \brief Turbulence provides fluid like forces based on a noise image. - - The Turbulence Element scales the noise source over the area it affects, - and uses the curl of that source to generate force vectors. - - Turbulence requires a fixed size. Unlike other affectors, a 0x0 Turbulence element - will affect no particles. - - The source should be relatively smooth black and white noise, such as perlin noise. -*/ -/*! - \qmlproperty real QtQuick.Particles2::Turbulence::strength - - The magnitude of the velocity vector at any point varies between zero and - the square root of two. It will then be multiplied by strength to get the - velocity per second for the particles affected by the turbulence. -*/ -/*! - \qmlproperty url QtQuick.Particles2::Turbulence::noiseSource - - The source image to generate the turbulence from. It will be scaled to the size of the element, - so equal or larger sizes will give better results. Tweaking this image is the only way to tweak - behavior such as where vortices are or how many exist. - - The source should be a relatively smooth black and white noise image, such as perlin noise. - A default image will be used if none is provided. -*/ - -QQuickTurbulenceAffector::QQuickTurbulenceAffector(QQuickItem *parent) : - QQuickParticleAffector(parent), - m_strength(10), m_lastT(0), m_gridSize(0), m_field(0), m_vectorField(0), m_inited(false) -{ -} - -void QQuickTurbulenceAffector::geometryChanged(const QRectF &, const QRectF &) -{ - initializeGrid(); -} - -QQuickTurbulenceAffector::~QQuickTurbulenceAffector() -{ - if (m_field) { - for (int i=0; i= m_gridSize) - x = m_gridSize - 1; - if (y < 0) - y = 0; - if (y >= m_gridSize) - y = m_gridSize - 1; - return m_field[x][y]; -} - -void QQuickTurbulenceAffector::ensureInit() -{ - if (m_inited) - return; - m_inited = true; - initializeGrid(); -} - -void QQuickTurbulenceAffector::affectSystem(qreal dt) -{ - if (!m_system || !m_enabled) - return; - ensureInit(); - if (!m_gridSize) - return; - - updateOffsets();//### Needed if an ancestor is transformed. - - QRect boundsRect(0,0,m_gridSize,m_gridSize); - foreach (QQuickParticleGroupData *gd, m_system->groupData){ - if (!activeGroup(m_system->groupData.key(gd))) - continue; - foreach (QQuickParticleData *d, gd->data){ - if (!shouldAffect(d)) - continue; - QPoint pos = (QPointF(d->curX(), d->curY()) - m_offset).toPoint(); - if (!boundsRect.contains(pos,true))//Need to redo bounds checking due to quantization. - continue; - qreal fx = 0.0; - qreal fy = 0.0; - fx += m_vectorField[pos.x()][pos.y()].x() * m_strength; - fy += m_vectorField[pos.x()][pos.y()].y() * m_strength; - if (fx || fy){ - d->setInstantaneousVX(d->curVX()+ fx * dt); - d->setInstantaneousVY(d->curVY()+ fy * dt); - postAffect(d); - } - } - } -} - -QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquickturbulence_p.h qt5-declarative-0.1~git20120423/src/quick/particles/qquickturbulence_p.h --- qt5-declarative-0.1~git20120402/src/quick/particles/qquickturbulence_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquickturbulence_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,116 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef TURBULENCEAFFECTOR_H -#define TURBULENCEAFFECTOR_H -#include "qquickparticleaffector_p.h" -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -class QQuickParticlePainter; - -class QQuickTurbulenceAffector : public QQuickParticleAffector -{ - Q_OBJECT - Q_PROPERTY(qreal strength READ strength WRITE setStrength NOTIFY strengthChanged) - Q_PROPERTY(QUrl noiseSource READ noiseSource WRITE setNoiseSource NOTIFY noiseSourceChanged) - public: - explicit QQuickTurbulenceAffector(QQuickItem *parent = 0); - ~QQuickTurbulenceAffector(); - virtual void affectSystem(qreal dt); - - qreal strength() const - { - return m_strength; - } - - QUrl noiseSource() const - { - return m_noiseSource; - } -signals: - - void strengthChanged(qreal arg); - - void noiseSourceChanged(QUrl arg); - -public slots: - - void setStrength(qreal arg) - { - if (m_strength != arg) { - m_strength = arg; - emit strengthChanged(arg); - } - } - - void setNoiseSource(QUrl arg) - { - if (m_noiseSource != arg) { - m_noiseSource = arg; - emit noiseSourceChanged(arg); - initializeGrid(); - } - } - -protected: - virtual void geometryChanged(const QRectF &newGeometry, - const QRectF &oldGeometry); -private: - void ensureInit(); - void mapUpdate(); - void initializeGrid(); - qreal boundsRespectingField(int x, int y); - qreal m_strength; - qreal m_lastT; - int m_gridSize; - qreal** m_field; - QPointF** m_vectorField; - bool m_inited; - QUrl m_noiseSource; -}; - -QT_END_NAMESPACE -QT_END_HEADER -#endif // TURBULENCEAFFECTOR_H diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquickv8particledata.cpp qt5-declarative-0.1~git20120423/src/quick/particles/qquickv8particledata.cpp --- qt5-declarative-0.1~git20120402/src/quick/particles/qquickv8particledata.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquickv8particledata.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,505 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qquickv8particledata_p.h" -#include "qquickparticlesystem_p.h"//for QQuickParticleData -#include - -QT_BEGIN_NAMESPACE - -/*! - \qmlclass Particle - \inqmlmodule QtQuick.Particles 2 - \brief Particle elements can be manipulated in custom emitters and affectors. - - Particle elements are always managed internally by the ParticleSystem and cannot be created in QML. - However, sometimes they are exposed via signals so as to allow arbitrary changes to the particle state -*/ - -/*! - \qmlproperty real QtQuick.Particles2::Particle::initialX - The x coordinate of the particle at the beginning of its lifetime. - - The method of simulation prefers to have the initial values changed, rather - than determining and changing the value at a given time. Change initial - values in CustomEmitters instead of the current values. -*/ - -/*! - \qmlproperty real QtQuick.Particles2::Particle::initialVX - The x velocity of the particle at the beginning of its lifetime. - - The method of simulation prefers to have the initial values changed, rather - than determining and changing the value at a given time. Change initial - values in CustomEmitters instead of the current values. -*/ - -/*! - \qmlproperty real QtQuick.Particles2::Particle::initialAX - The x acceleration of the particle at the beginning of its lifetime. - - The method of simulation prefers to have the initial values changed, rather - than determining and changing the value at a given time. Change initial - values in CustomEmitters instead of the current values. -*/ - -/*! - \qmlproperty real QtQuick.Particles2::Particle::initialY - The y coordinate of the particle at the beginning of its lifetime. - - The method of simulation prefers to have the initial values changed, rather - than determining and changing the value at a given time. Change initial - values in CustomEmitters instead of the current values. -*/ - -/*! - \qmlproperty real QtQuick.Particles2::Particle::initialVY - The y velocity of the particle at the beginning of its lifetime. - - The method of simulation prefers to have the initial values changed, rather - than determining and changing the value at a given time. Change initial - values in CustomEmitters instead of the current values. -*/ - -/*! - \qmlproperty real QtQuick.Particles2::Particle::initialAY - The y acceleration of the particle at the beginning of its lifetime. - - The method of simulation prefers to have the initial values changed, rather - than determining and changing the value at a given time. Change initial - values in CustomEmitters instead of the current values. -*/ - -/*! - \qmlproperty real QtQuick.Particles2::Particle::x - The current x coordinate of the particle. -*/ - -/*! - \qmlproperty real QtQuick.Particles2::Particle::vx - The current x velocity of the particle. -*/ - -/*! - \qmlproperty real QtQuick.Particles2::Particle::ax - The current x acceleration of the particle. -*/ - -/*! - \qmlproperty real QtQuick.Particles2::Particle::y - The current y coordinate of the particle. -*/ - -/*! - \qmlproperty real QtQuick.Particles2::Particle::vy - The current y velocity of the particle. -*/ - -/*! - \qmlproperty real QtQuick.Particles2::Particle::ay - The current y acceleration of the particle. -*/ - -/*! - \qmlproperty real QtQuick.Particles2::Particle::t - The time, in seconds since the beginning of the simulation, that the particle was born. -*/ - - -/*! - \qmlproperty real QtQuick.Particles2::Particle::startSize - The size in pixels that the particle image is at the start - of its life. -*/ - - -/*! - \qmlproperty real QtQuick.Particles2::Particle::endSize - The size in pixels that the particle image is at the end - of its life. If this value is less than 0, then it is - disregarded and the particle will have its startSize for the - entire lifetime. -*/ - -/*! - \qmlproperty real QtQuick.Particles2::Particle::lifeSpan - The time in seconds that the particle will live for. -*/ - -/*! - \qmlproperty real QtQuick.Particles2::Particle::rotation - Degrees clockwise that the particle image is rotated at - the beginning of its life. -*/ - -/*! - \qmlproperty real QtQuick.Particles2::Particle::rotationSpeed - Degrees clockwise per second that the particle image is rotated at while alive. -*/ -/*! - \qmlproperty bool QtQuick.Particles2::Particle::autoRotate - If autoRotate is true, then the particle's rotation will be - set so that it faces the direction of travel, plus any - rotation from the rotation or rotationSpeed properties. -*/ - -/*! - \qmlproperty bool QtQuick.Particles2::Particle::update - - Inside an Affector, the changes made to the particle will only be - applied if update is set to true. -*/ -/*! - \qmlproperty real QtQuick.Particles2::Particle::xDeformationVectorX - - The x component of the deformation vector along the X axis. ImageParticle - can draw particles across non-square shapes. It will draw the texture rectangle - across the parallelogram drawn with the x and y deformation vectors. -*/ - -/*! - \qmlproperty real QtQuick.Particles2::Particle::yDeformationVectorX - - The y component of the deformation vector along the X axis. ImageParticle - can draw particles across non-square shapes. It will draw the texture rectangle - across the parallelogram drawn with the x and y deformation vectors. -*/ - -/*! - \qmlproperty real QtQuick.Particles2::Particle::xDeformationVectorY - - The x component of the deformation vector along the X axis. ImageParticle - can draw particles across non-square shapes. It will draw the texture rectangle - across the parallelogram drawn with the x and y deformation vectors. -*/ - -/*! - \qmlproperty real QtQuick.Particles2::Particle::yDeformationVectorY - - The y component of the deformation vector along the Y axis. ImageParticle - can draw particles across non-square shapes. It will draw the texture rectangle - across the parallelogram drawn with the x and y deformation vectors. -*/ - -/*! - \qmlproperty real QtQuick.Particles2::Particle::red - - ImageParticle can draw colorized particles. When it does so, red is used - as the red channel of the color applied to the source image. - - Values are from 0.0 to 1.0. -*/ - -/*! - \qmlproperty real QtQuick.Particles2::Particle::green - - ImageParticle can draw colorized particles. When it does so, green is used - as the green channel of the color applied to the source image. - - Values are from 0.0 to 1.0. -*/ - -/*! - \qmlproperty real QtQuick.Particles2::Particle::blue - - ImageParticle can draw colorized particles. When it does so, blue is used - as the blue channel of the color applied to the source image. - - Values are from 0.0 to 1.0. -*/ - -/*! - \qmlproperty real QtQuick.Particles2::Particle::alpha - - ImageParticle can draw colorized particles. When it does so, alpha is used - as the alpha channel of the color applied to the source image. - - Values are from 0.0 to 1.0. -*/ -/*! - \qmlmethod real QtQuick.Particles2::Particle::lifeLeft - The time in seconds that the particle has left to live at - the current point in time. -*/ -/*! - \qmlmethod real QtQuick.Particles2::Particle::currentSize - The currentSize of the particle, interpolating between startSize and endSize based on the currentTime. -*/ - - - -//### Particle data handles are not locked to within certain scopes like QQuickContext2D, but there's no way to reload either... -class QV8ParticleDataResource : public QV8ObjectResource -{ - V8_RESOURCE_TYPE(ParticleDataType) -public: - QV8ParticleDataResource(QV8Engine *e) : QV8ObjectResource(e) {} - QQuickParticleData* datum;//TODO: Guard needed? -}; - -class QV8ParticleDataDeletable : public QV8Engine::Deletable -{ -public: - QV8ParticleDataDeletable(QV8Engine *engine); - ~QV8ParticleDataDeletable(); - - v8::Persistent constructor; -}; - -static v8::Handle particleData_discard(const v8::Arguments &args) -{ - QV8ParticleDataResource *r = v8_resource_cast(args.This()); - - if (!r || !r->datum) - V8THROW_ERROR("Not a valid ParticleData object"); - - r->datum->lifeSpan = 0; //Don't kill(), because it could still be in the middle of being created - return v8::Undefined(); -} - -static v8::Handle particleData_lifeLeft(const v8::Arguments &args) -{ - QV8ParticleDataResource *r = v8_resource_cast(args.This()); - if (!r || !r->datum) - V8THROW_ERROR("Not a valid ParticleData object"); - - return v8::Number::New(r->datum->lifeLeft()); -} - -static v8::Handle particleData_curSize(const v8::Arguments &args) -{ - QV8ParticleDataResource *r = v8_resource_cast(args.This()); - if (!r || !r->datum) - V8THROW_ERROR("Not a valid ParticleData object"); - - return v8::Number::New(r->datum->curSize()); -} -#define COLOR_GETTER_AND_SETTER(VAR, NAME) static v8::Handle particleData_get_ ## NAME (v8::Local, const v8::AccessorInfo &info) \ -{ \ - QV8ParticleDataResource *r = v8_resource_cast(info.This()); \ - if (!r || !r->datum) \ - V8THROW_ERROR("Not a valid ParticleData object"); \ -\ - return v8::Number::New((r->datum->color. VAR )/255.0);\ -}\ -\ -static void particleData_set_ ## NAME (v8::Local, v8::Local value, const v8::AccessorInfo &info)\ -{\ - QV8ParticleDataResource *r = v8_resource_cast(info.This());\ - if (!r || !r->datum)\ - V8THROW_ERROR_SETTER("Not a valid ParticleData object");\ -\ - r->datum->color. VAR = qMin(255, qMax(0, (int)floor(value->NumberValue() * 255.0)));\ -} - - -#define SEMIBOOL_GETTER_AND_SETTER(VARIABLE) static v8::Handle particleData_get_ ## VARIABLE (v8::Local, const v8::AccessorInfo &info) \ -{ \ - QV8ParticleDataResource *r = v8_resource_cast(info.This()); \ - if (!r || !r->datum) \ - V8THROW_ERROR("Not a valid ParticleData object"); \ -\ - return v8::Boolean::New(r->datum-> VARIABLE);\ -}\ -\ -static void particleData_set_ ## VARIABLE (v8::Local, v8::Local value, const v8::AccessorInfo &info)\ -{\ - QV8ParticleDataResource *r = v8_resource_cast(info.This());\ - if (!r || !r->datum)\ - V8THROW_ERROR_SETTER("Not a valid ParticleData object");\ -\ - r->datum-> VARIABLE = value->BooleanValue() ? 1.0 : 0.0;\ -} - -#define FLOAT_GETTER_AND_SETTER(VARIABLE) static v8::Handle particleData_get_ ## VARIABLE (v8::Local, const v8::AccessorInfo &info) \ -{ \ - QV8ParticleDataResource *r = v8_resource_cast(info.This()); \ - if (!r || !r->datum) \ - V8THROW_ERROR("Not a valid ParticleData object"); \ -\ - return v8::Number::New(r->datum-> VARIABLE);\ -}\ -\ -static void particleData_set_ ## VARIABLE (v8::Local, v8::Local value, const v8::AccessorInfo &info)\ -{\ - QV8ParticleDataResource *r = v8_resource_cast(info.This());\ - if (!r || !r->datum)\ - V8THROW_ERROR_SETTER("Not a valid ParticleData object");\ -\ - r->datum-> VARIABLE = value->NumberValue();\ -} - -#define FAKE_FLOAT_GETTER_AND_SETTER(VARIABLE, GETTER, SETTER) static v8::Handle particleData_get_ ## VARIABLE (v8::Local, const v8::AccessorInfo &info) \ -{ \ - QV8ParticleDataResource *r = v8_resource_cast(info.This()); \ - if (!r || !r->datum) \ - V8THROW_ERROR("Not a valid ParticleData object"); \ -\ - return v8::Number::New(r->datum-> GETTER ());\ -}\ -\ -static void particleData_set_ ## VARIABLE (v8::Local, v8::Local value, const v8::AccessorInfo &info)\ -{\ - QV8ParticleDataResource *r = v8_resource_cast(info.This());\ - if (!r || !r->datum)\ - V8THROW_ERROR_SETTER("Not a valid ParticleData object");\ -\ - r->datum-> SETTER ( value->NumberValue() );\ -} - -#define REGISTER_ACCESSOR(FT, ENGINE, VARIABLE, NAME) FT ->PrototypeTemplate()->SetAccessor( v8::String::New( #NAME ), particleData_get_ ## VARIABLE , particleData_set_ ## VARIABLE , v8::External::Wrap(ENGINE)) - -COLOR_GETTER_AND_SETTER(r, red) -COLOR_GETTER_AND_SETTER(g, green) -COLOR_GETTER_AND_SETTER(b, blue) -COLOR_GETTER_AND_SETTER(a, alpha) -SEMIBOOL_GETTER_AND_SETTER(autoRotate) -SEMIBOOL_GETTER_AND_SETTER(update) -FLOAT_GETTER_AND_SETTER(x) -FLOAT_GETTER_AND_SETTER(y) -FLOAT_GETTER_AND_SETTER(t) -FLOAT_GETTER_AND_SETTER(lifeSpan) -FLOAT_GETTER_AND_SETTER(size) -FLOAT_GETTER_AND_SETTER(endSize) -FLOAT_GETTER_AND_SETTER(vx) -FLOAT_GETTER_AND_SETTER(vy) -FLOAT_GETTER_AND_SETTER(ax) -FLOAT_GETTER_AND_SETTER(ay) -FLOAT_GETTER_AND_SETTER(xx) -FLOAT_GETTER_AND_SETTER(xy) -FLOAT_GETTER_AND_SETTER(yx) -FLOAT_GETTER_AND_SETTER(yy) -FLOAT_GETTER_AND_SETTER(rotation) -FLOAT_GETTER_AND_SETTER(rotationSpeed) -FLOAT_GETTER_AND_SETTER(animIdx) -FLOAT_GETTER_AND_SETTER(frameDuration) -FLOAT_GETTER_AND_SETTER(frameAt) -FLOAT_GETTER_AND_SETTER(frameCount) -FLOAT_GETTER_AND_SETTER(animT) -FLOAT_GETTER_AND_SETTER(r) -FAKE_FLOAT_GETTER_AND_SETTER(curX, curX, setInstantaneousX) -FAKE_FLOAT_GETTER_AND_SETTER(curVX, curVX, setInstantaneousVX) -FAKE_FLOAT_GETTER_AND_SETTER(curAX, curAX, setInstantaneousAX) -FAKE_FLOAT_GETTER_AND_SETTER(curY, curY, setInstantaneousY) -FAKE_FLOAT_GETTER_AND_SETTER(curVY, curVY, setInstantaneousVY) -FAKE_FLOAT_GETTER_AND_SETTER(curAY, curAY, setInstantaneousAY) - -QV8ParticleDataDeletable::QV8ParticleDataDeletable(QV8Engine *engine) -{ - v8::HandleScope handle_scope; - v8::Context::Scope scope(engine->context()); - - v8::Local ft = v8::FunctionTemplate::New(); - ft->InstanceTemplate()->SetHasExternalResource(true); - ft->PrototypeTemplate()->Set(v8::String::New("discard"), V8FUNCTION(particleData_discard, engine)); - ft->PrototypeTemplate()->Set(v8::String::New("lifeLeft"), V8FUNCTION(particleData_lifeLeft, engine)); - ft->PrototypeTemplate()->Set(v8::String::New("currentSize"), V8FUNCTION(particleData_curSize, engine)); - REGISTER_ACCESSOR(ft, engine, x, initialX); - REGISTER_ACCESSOR(ft, engine, y, initialY); - REGISTER_ACCESSOR(ft, engine, t, t); - REGISTER_ACCESSOR(ft, engine, lifeSpan, lifeSpan); - REGISTER_ACCESSOR(ft, engine, size, startSize); - REGISTER_ACCESSOR(ft, engine, endSize, endSize); - REGISTER_ACCESSOR(ft, engine, vx, initialVX); - REGISTER_ACCESSOR(ft, engine, vy, initialVY); - REGISTER_ACCESSOR(ft, engine, ax, initialAX); - REGISTER_ACCESSOR(ft, engine, ay, initialAY); - REGISTER_ACCESSOR(ft, engine, xx, xDeformationVectorX); - REGISTER_ACCESSOR(ft, engine, xy, xDeformationVectorY); - REGISTER_ACCESSOR(ft, engine, yx, yDeformationVectorX); - REGISTER_ACCESSOR(ft, engine, yy, yDeformationVectorY); - REGISTER_ACCESSOR(ft, engine, rotation, rotation); - REGISTER_ACCESSOR(ft, engine, rotationSpeed, rotationSpeed); - REGISTER_ACCESSOR(ft, engine, autoRotate, autoRotate); - REGISTER_ACCESSOR(ft, engine, animIdx, animationIndex); - REGISTER_ACCESSOR(ft, engine, frameDuration, frameDuration); - REGISTER_ACCESSOR(ft, engine, frameAt, frameAt); - REGISTER_ACCESSOR(ft, engine, frameCount, frameCount); - REGISTER_ACCESSOR(ft, engine, animT, animationT); - REGISTER_ACCESSOR(ft, engine, r, r); - REGISTER_ACCESSOR(ft, engine, update, update); - REGISTER_ACCESSOR(ft, engine, curX, x); - REGISTER_ACCESSOR(ft, engine, curVX, vx); - REGISTER_ACCESSOR(ft, engine, curAX, ax); - REGISTER_ACCESSOR(ft, engine, curY, y); - REGISTER_ACCESSOR(ft, engine, curVY, vy); - REGISTER_ACCESSOR(ft, engine, curAY, ay); - REGISTER_ACCESSOR(ft, engine, red, red); - REGISTER_ACCESSOR(ft, engine, green, green); - REGISTER_ACCESSOR(ft, engine, blue, blue); - REGISTER_ACCESSOR(ft, engine, alpha, alpha); - - constructor = qPersistentNew(ft->GetFunction()); -} - -QV8ParticleDataDeletable::~QV8ParticleDataDeletable() -{ - qPersistentDispose(constructor); -} - -V8_DEFINE_EXTENSION(QV8ParticleDataDeletable, particleV8Data); - - -QQuickV8ParticleData::QQuickV8ParticleData(QV8Engine* engine, QQuickParticleData* datum) -{ - if (!engine || !datum) - return; - v8::HandleScope handle_scope; - v8::Context::Scope scope(engine->context()); - - QV8ParticleDataDeletable *d = particleV8Data(engine); - m_v8Value = qPersistentNew(d->constructor->NewInstance()); - QV8ParticleDataResource *r = new QV8ParticleDataResource(engine); - r->datum = datum; - m_v8Value->SetExternalResource(r); -} - -QQuickV8ParticleData::~QQuickV8ParticleData() -{ - qPersistentDispose(m_v8Value); -} - -QQmlV8Handle QQuickV8ParticleData::v8Value() -{ - return QQmlV8Handle::fromHandle(m_v8Value); -} - -QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquickv8particledata_p.h qt5-declarative-0.1~git20120423/src/quick/particles/qquickv8particledata_p.h --- qt5-declarative-0.1~git20120402/src/quick/particles/qquickv8particledata_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquickv8particledata_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,67 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QQuickV8PARTICLEDATA_H -#define QQuickV8PARTICLEDATA_H - -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -class QQuickParticleData; -class QQuickV8ParticleData { -public: - QQuickV8ParticleData(QV8Engine*,QQuickParticleData*); - ~QQuickV8ParticleData(); - QQmlV8Handle v8Value(); -private: - v8::Persistent m_v8Value; -}; - - -QT_END_NAMESPACE - -QT_END_HEADER - - -#endif diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquickwander.cpp qt5-declarative-0.1~git20120423/src/quick/particles/qquickwander.cpp --- qt5-declarative-0.1~git20120402/src/quick/particles/qquickwander.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquickwander.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,181 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qquickwander_p.h" -#include "qquickparticlesystem_p.h"//for ParticlesVertices -QT_BEGIN_NAMESPACE -/*! - \qmlclass Wander QQuickWanderAffector - \inqmlmodule QtQuick.Particles 2 - \inherits Affector - \brief The Wander affector allows particles to randomly vary their trajectory. - -*/ -/*! - \qmlproperty real QtQuick.Particles2::Wander::pace - - Maximum attribute change per second. -*/ -/*! - \qmlproperty real QtQuick.Particles2::Wander::xVariance - - Maximum attribute x value (as a result of Wander). - - If unset, Wander will not affect x values. -*/ -/*! - \qmlproperty real QtQuick.Particles2::Wander::yVariance - - Maximum attribute y value (as a result of Wander). - - If unset, Wander will not affect y values. -*/ -/*! - \qmlproperty AffectableParameter QtQuick.Particles2::Wander::affectedParameter - - What attribute of particles is directly affected. - \list - \li PointAttractor.Position - \li PointAttractor.Velocity - \li PointAttractor.Acceleration - \endlist -*/ - -QQuickWanderAffector::QQuickWanderAffector(QQuickItem *parent) : - QQuickParticleAffector(parent), m_xVariance(0), m_yVariance(0), m_pace(0) - , m_affectedParameter(Velocity) -{ - m_needsReset = true; -} - -QQuickWanderAffector::~QQuickWanderAffector() -{ - for (QHash::const_iterator iter=m_wanderData.constBegin(); - iter != m_wanderData.constEnd(); iter++) - delete (*iter); -} - -WanderData* QQuickWanderAffector::getData(int idx) -{ - if (m_wanderData.contains(idx)) - return m_wanderData[idx]; - WanderData* d = new WanderData; - d->x_vel = 0; - d->y_vel = 0; - d->x_peak = m_xVariance; - d->y_peak = m_yVariance; - d->x_var = m_pace * qreal(qrand()) / RAND_MAX; - d->y_var = m_pace * qreal(qrand()) / RAND_MAX; - - m_wanderData.insert(idx, d); - return d; -} - -// TODO: see below -//void QQuickWanderAffector::reset(int systemIdx) -//{ -// if (m_wanderData.contains(systemIdx)) -// delete m_wanderData[systemIdx]; -// m_wanderData.remove(systemIdx); -//} - -bool QQuickWanderAffector::affectParticle(QQuickParticleData* data, qreal dt) -{ - /*TODO: Add a mode which does basically this - picking a direction, going in it (random speed) and then going back - WanderData* d = getData(data->systemIndex); - if (m_xVariance != 0.) { - if ((d->x_vel > d->x_peak && d->x_var > 0.0) || (d->x_vel < -d->x_peak && d->x_var < 0.0)) { - d->x_var = -d->x_var; - d->x_peak = m_xVariance + m_xVariance * qreal(qrand()) / RAND_MAX; - } - d->x_vel += d->x_var * dt; - } - qreal dx = dt * d->x_vel; - - if (m_yVariance != 0.) { - if ((d->y_vel > d->y_peak && d->y_var > 0.0) || (d->y_vel < -d->y_peak && d->y_var < 0.0)) { - d->y_var = -d->y_var; - d->y_peak = m_yVariance + m_yVariance * qreal(qrand()) / RAND_MAX; - } - d->y_vel += d->y_var * dt; - } - qreal dy = dt * d->x_vel; - - //### Should we be amending vel instead? - ParticleVertex* p = &(data->pv); - p->x += dx; - - p->y += dy; - return true; - */ - qreal dx = dt * m_pace * (2 * qreal(qrand())/RAND_MAX - 1); - qreal dy = dt * m_pace * (2 * qreal(qrand())/RAND_MAX - 1); - qreal newX, newY; - switch (m_affectedParameter){ - case Position: - newX = data->curX() + dx; - if (m_xVariance > qAbs(newX) ) - data->x += dx; - newY = data->curY() + dy; - if (m_yVariance > qAbs(newY) ) - data->y += dy; - break; - default: - case Velocity: - newX = data->curVX() + dx; - if (m_xVariance > qAbs(newX) ) - data->setInstantaneousVX(newX); - newY = data->curVY() + dy; - if (m_yVariance > qAbs(newY) ) - data->setInstantaneousVY(newY); - break; - case Acceleration: - newX = data->ax + dx; - if (m_xVariance > qAbs(newX) ) - data->setInstantaneousAX(newX); - newY = data->ay + dy; - if (m_yVariance > qAbs(newY) ) - data->setInstantaneousAY(newY); - break; - } - return true; -} -QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/quick/particles/qquickwander_p.h qt5-declarative-0.1~git20120423/src/quick/particles/qquickwander_p.h --- qt5-declarative-0.1~git20120402/src/quick/particles/qquickwander_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/particles/qquickwander_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,158 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef WANDERAFFECTOR_H -#define WANDERAFFECTOR_H -#include -#include "qquickparticleaffector_p.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -struct WanderData{ - qreal x_vel; - qreal y_vel; - qreal x_peak; - qreal x_var; - qreal y_peak; - qreal y_var; -}; - -class QQuickWanderAffector : public QQuickParticleAffector -{ - Q_OBJECT - Q_PROPERTY(qreal pace READ pace WRITE setPace NOTIFY paceChanged) - Q_PROPERTY(qreal xVariance READ xVariance WRITE setXVariance NOTIFY xVarianceChanged) - Q_PROPERTY(qreal yVariance READ yVariance WRITE setYVariance NOTIFY yVarianceChanged) - Q_PROPERTY(AffectableParameters affectedParameter READ affectedParameter WRITE setAffectedParameter NOTIFY affectedParameterChanged) - Q_ENUMS(AffectableParameters) - -public: - enum AffectableParameters { - Position, - Velocity, - Acceleration - }; - - explicit QQuickWanderAffector(QQuickItem *parent = 0); - ~QQuickWanderAffector(); -// virtual void reset(int systemIdx); - - qreal xVariance() const - { - return m_xVariance; - } - - qreal yVariance() const - { - return m_yVariance; - } - - qreal pace() const - { - return m_pace; - } - - AffectableParameters affectedParameter() const - { - return m_affectedParameter; - } - -protected: - virtual bool affectParticle(QQuickParticleData *d, qreal dt); -signals: - - void xVarianceChanged(qreal arg); - - void yVarianceChanged(qreal arg); - - void paceChanged(qreal arg); - - - void affectedParameterChanged(AffectableParameters arg); - -public slots: -void setXVariance(qreal arg) -{ - if (m_xVariance != arg) { - m_xVariance = arg; - emit xVarianceChanged(arg); - } -} - -void setYVariance(qreal arg) -{ - if (m_yVariance != arg) { - m_yVariance = arg; - emit yVarianceChanged(arg); - } -} - -void setPace(qreal arg) -{ - if (m_pace != arg) { - m_pace = arg; - emit paceChanged(arg); - } -} - - -void setAffectedParameter(AffectableParameters arg) -{ - if (m_affectedParameter != arg) { - m_affectedParameter = arg; - emit affectedParameterChanged(arg); - } -} - -private: - WanderData* getData(int idx); - QHash m_wanderData; - qreal m_xVariance; - qreal m_yVariance; - qreal m_pace; - AffectableParameters m_affectedParameter; -}; - -QT_END_NAMESPACE -QT_END_HEADER -#endif // WANDERAFFECTOR_H diff -Nru qt5-declarative-0.1~git20120402/src/quick/qtquick2.cpp qt5-declarative-0.1~git20120423/src/quick/qtquick2.cpp --- qt5-declarative-0.1~git20120402/src/quick/qtquick2.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/qtquick2.cpp 2012-04-23 11:44:59.000000000 +0000 @@ -44,8 +44,6 @@ #include #include #include -#include -#include #include #include @@ -175,8 +173,6 @@ QQuickUtilModule::defineModule(); QQmlEnginePrivate::defineModule(); QQuickItemsModule::defineModule(); - QQuickParticlesModule::defineModule(); - QQuickWindowModule::defineModule(); QQmlValueTypeFactory::registerValueTypes(); if (QQmlEngineDebugService::isDebuggingEnabled()) { diff -Nru qt5-declarative-0.1~git20120402/src/quick/quick.pro qt5-declarative-0.1~git20120423/src/quick/quick.pro --- qt5-declarative-0.1~git20120402/src/quick/quick.pro 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/quick.pro 2012-04-23 11:32:40.000000000 +0000 @@ -22,7 +22,6 @@ include(util/util.pri) include(scenegraph/scenegraph.pri) include(items/items.pri) -include(particles/particles.pri) include(designer/designer.pri) HEADERS += \ diff -Nru qt5-declarative-0.1~git20120402/src/quick/scenegraph/coreapi/qsgdefaultrenderer_p.h qt5-declarative-0.1~git20120423/src/quick/scenegraph/coreapi/qsgdefaultrenderer_p.h --- qt5-declarative-0.1~git20120402/src/quick/scenegraph/coreapi/qsgdefaultrenderer_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/scenegraph/coreapi/qsgdefaultrenderer_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -51,7 +51,7 @@ QT_BEGIN_NAMESPACE -class QSGDefaultRenderer : public QSGRenderer +class Q_QUICK_EXPORT QSGDefaultRenderer : public QSGRenderer { Q_OBJECT public: diff -Nru qt5-declarative-0.1~git20120402/src/quick/scenegraph/coreapi/qsggeometry.h qt5-declarative-0.1~git20120423/src/quick/scenegraph/coreapi/qsggeometry.h --- qt5-declarative-0.1~git20120402/src/quick/scenegraph/coreapi/qsggeometry.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/scenegraph/coreapi/qsggeometry.h 2012-04-23 11:32:40.000000000 +0000 @@ -56,7 +56,7 @@ { public: - struct Attribute + struct Q_QUICK_EXPORT Attribute { int position; int tupleSize; diff -Nru qt5-declarative-0.1~git20120402/src/quick/scenegraph/coreapi/qsgrenderer_p.h qt5-declarative-0.1~git20120423/src/quick/scenegraph/coreapi/qsgrenderer_p.h --- qt5-declarative-0.1~git20120402/src/quick/scenegraph/coreapi/qsgrenderer_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/scenegraph/coreapi/qsgrenderer_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -108,7 +108,7 @@ qreal determinant() const { return m_current_determinant; } void setProjectionMatrixToDeviceRect(); - void setProjectionMatrixToRect(const QRectF &rect); + virtual void setProjectionMatrixToRect(const QRectF &rect); void setProjectionMatrix(const QMatrix4x4 &matrix); QMatrix4x4 projectionMatrix() const { return m_projection_matrix; } bool isMirrored() const { return m_mirrored; } diff -Nru qt5-declarative-0.1~git20120402/src/quick/scenegraph/qsgshareddistancefieldglyphcache.cpp qt5-declarative-0.1~git20120423/src/quick/scenegraph/qsgshareddistancefieldglyphcache.cpp --- qt5-declarative-0.1~git20120402/src/quick/scenegraph/qsgshareddistancefieldglyphcache.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/scenegraph/qsgshareddistancefieldglyphcache.cpp 2012-04-23 11:44:59.000000000 +0000 @@ -86,11 +86,11 @@ connect(sharedGraphicsCache, SIGNAL(itemsMissing(QByteArray,QVector)), this, SLOT(reportItemsMissing(QByteArray,QVector)), Qt::DirectConnection); - connect(sharedGraphicsCache, SIGNAL(itemsAvailable(QByteArray,void*,QSize,QVector,QVector)), - this, SLOT(reportItemsAvailable(QByteArray,void*,QSize,QVector,QVector)), + connect(sharedGraphicsCache, SIGNAL(itemsAvailable(QByteArray,void*,QVector,QVector)), + this, SLOT(reportItemsAvailable(QByteArray,void*,QVector,QVector)), Qt::DirectConnection); - connect(sharedGraphicsCache, SIGNAL(itemsUpdated(QByteArray,void*,QSize,QVector,QVector)), - this, SLOT(reportItemsUpdated(QByteArray,void*,QSize,QVector,QVector)), + connect(sharedGraphicsCache, SIGNAL(itemsUpdated(QByteArray,void*,QVector,QVector)), + this, SLOT(reportItemsUpdated(QByteArray,void*,QVector,QVector)), Qt::DirectConnection); connect(sharedGraphicsCache, SIGNAL(itemsInvalidated(QByteArray,QVector)), this, SLOT(reportItemsInvalidated(QByteArray,QVector)), @@ -537,7 +537,7 @@ while (it != textureContentForBuffer.constEnd()) { Texture texture; texture.textureId = m_sharedGraphicsCache->textureIdForBuffer(it.key()); - texture.size = it.value().size; + texture.size = m_sharedGraphicsCache->sizeOfBuffer(it.key()); #if defined(QSGSHAREDDISTANCEFIELDGLYPHCACHE_DEBUG_) saveTexture(texture.textureId, texture.size.width(), texture.size.height()); @@ -557,7 +557,6 @@ void QSGSharedDistanceFieldGlyphCache::reportItemsAvailable(const QByteArray &cacheId, void *bufferId, - const QSize &bufferSize, const QVector &itemIds, const QVector &positions) { @@ -568,8 +567,8 @@ return; #if defined(QSGSHAREDDISTANCEFIELDGLYPHCACHE_DEBUG) - qDebug("QSGSharedDistanceFieldGlyphCache::reportItemsAvailable() called for %s (%d glyphs, bufferSize: %dx%d)", - cacheId.constData(), itemIds.size(), bufferSize.width(), bufferSize.height()); + qDebug("QSGSharedDistanceFieldGlyphCache::reportItemsAvailable() called for %s (%d glyphs)", + cacheId.constData(), itemIds.size()); #endif for (int i=0; i &itemIds, const QVector &positions) { @@ -597,19 +596,17 @@ Q_ASSERT(itemIds.size() == positions.size()); #if defined(QSGSHAREDDISTANCEFIELDGLYPHCACHE_DEBUG) - qDebug("QSGSharedDistanceFieldGlyphCache::reportItemsUpdated() called for %s (%d glyphs, bufferSize: %dx%d)", - cacheId.constData(), itemIds.size(), bufferSize.width(), bufferSize.height()); + qDebug("QSGSharedDistanceFieldGlyphCache::reportItemsUpdated() called for %s (%d glyphs)", + cacheId.constData(), itemIds.size()); #endif for (int i=0; i= pendingGlyph.bufferSize.height()); pendingGlyph.buffer = bufferId; pendingGlyph.position = positions.at(i); - pendingGlyph.bufferSize = bufferSize; m_sharedGraphicsCache->referenceBuffer(bufferId); if (oldBuffer != 0) diff -Nru qt5-declarative-0.1~git20120402/src/quick/scenegraph/qsgshareddistancefieldglyphcache_p.h qt5-declarative-0.1~git20120423/src/quick/scenegraph/qsgshareddistancefieldglyphcache_p.h --- qt5-declarative-0.1~git20120402/src/quick/scenegraph/qsgshareddistancefieldglyphcache_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/scenegraph/qsgshareddistancefieldglyphcache_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -77,10 +77,13 @@ private Q_SLOTS: void reportItemsMissing(const QByteArray &cacheId, const QVector &itemIds); void reportItemsAvailable(const QByteArray &cacheId, - void *bufferId, const QSize &bufferSize, - const QVector &itemIds, const QVector &positions); - void reportItemsUpdated(const QByteArray &cacheId, void *bufferId, const QSize &bufferSize, - const QVector &itemIds, const QVector &positions); + void *bufferId, + const QVector &itemIds, + const QVector &positions); + void reportItemsUpdated(const QByteArray &cacheId, + void *bufferId, + const QVector &itemIds, + const QVector &positions); void reportItemsInvalidated(const QByteArray &cacheId, const QVector &itemIds); private: diff -Nru qt5-declarative-0.1~git20120402/src/quick/scenegraph/util/qsgpainternode.cpp qt5-declarative-0.1~git20120423/src/quick/scenegraph/util/qsgpainternode.cpp --- qt5-declarative-0.1~git20120402/src/quick/scenegraph/util/qsgpainternode.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/scenegraph/util/qsgpainternode.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -73,6 +73,10 @@ } +#ifdef QT_OPENGL_ES +extern void qsg_swizzleBGRAToRGBA(QImage *image); +#endif + void QSGPainterTexture::bind() { if (m_dirty_rect.isNull()) { @@ -91,6 +95,7 @@ int h = m_dirty_rect.height(); #ifdef QT_OPENGL_ES + qsg_swizzleBGRAToRGBA(&subImage); glTexSubImage2D(GL_TEXTURE_2D, 0, m_dirty_rect.x(), m_dirty_rect.y(), w, h, GL_RGBA, GL_UNSIGNED_BYTE, subImage.constBits()); #else diff -Nru qt5-declarative-0.1~git20120402/src/quick/scenegraph/util/qsgtexture.cpp qt5-declarative-0.1~git20120423/src/quick/scenegraph/util/qsgtexture.cpp --- qt5-declarative-0.1~git20120402/src/quick/scenegraph/util/qsgtexture.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/scenegraph/util/qsgtexture.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -402,7 +402,7 @@ } #ifdef QT_OPENGL_ES -static void swizzleBGRAToRGBA(QImage *image) +void qsg_swizzleBGRAToRGBA(QImage *image) { const int width = image->width(); const int height = image->height(); @@ -500,7 +500,7 @@ updateBindOptions(m_dirty_bind_options); #ifdef QT_OPENGL_ES - swizzleBGRAToRGBA(&tmp); + qsg_swizzleBGRAToRGBA(&tmp); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, tmp.constBits()); #else glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, tmp.constBits()); diff -Nru qt5-declarative-0.1~git20120402/src/quick/util/qquickanimation.cpp qt5-declarative-0.1~git20120423/src/quick/util/qquickanimation.cpp --- qt5-declarative-0.1~git20120402/src/quick/util/qquickanimation.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/util/qquickanimation.cpp 2012-04-23 11:44:59.000000000 +0000 @@ -231,6 +231,11 @@ d->commence(); emit started(); } else { + if (d->paused) { + d->paused = false; //reset paused state to false when stopped + emit pausedChanged(d->paused); + } + if (d->animationInstance) { if (d->alwaysRunToEnd) { if (d->loopCount != 1) @@ -260,6 +265,7 @@ bool QQuickAbstractAnimation::isPaused() const { Q_D(const QQuickAbstractAnimation); + Q_ASSERT((d->paused && d->running) || !d->paused); return d->paused; } @@ -269,6 +275,11 @@ if (d->paused == p) return; + if (!d->running) { + qmlInfo(this) << "setPaused() cannot be used when animation isn't running."; + return; + } + if (d->group || d->disableUserControl) { qmlInfo(this) << "setPaused() cannot be used on non-root animation nodes."; return; @@ -445,8 +456,8 @@ \qmlmethod QtQuick2::Animation::pause() \brief Pauses the animation. - If the animation is already paused, calling this method has no effect. The - \c paused property will be true following a call to \c pause(). + If the animation is already paused or not \c running, calling this method has no effect. + The \c paused property will be true following a call to \c pause(). */ void QQuickAbstractAnimation::pause() { @@ -457,8 +468,8 @@ \qmlmethod QtQuick2::Animation::resume() \brief Resumes a paused animation. - If the animation is not paused, calling this method has no effect. The - \c paused property will be false following a call to \c resume(). + If the animation is not paused or not \c running, calling this method has no effect. + The \c paused property will be false following a call to \c resume(). */ void QQuickAbstractAnimation::resume() { @@ -469,8 +480,8 @@ \qmlmethod QtQuick2::Animation::stop() \brief Stops the animation. - If the animation is not running, calling this method has no effect. The - \c running property will be false following a call to \c stop(). + If the animation is not running, calling this method has no effect. Both the + \c running and \c paused properties will be false following a call to \c stop(). Normally \c stop() stops the animation immediately, and the animation has no further influence on property values. In this example animation diff -Nru qt5-declarative-0.1~git20120402/src/quick/util/qquickconnections.cpp qt5-declarative-0.1~git20120423/src/quick/util/qquickconnections.cpp --- qt5-declarative-0.1~git20120402/src/quick/util/qquickconnections.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/util/qquickconnections.cpp 2012-04-23 11:44:59.000000000 +0000 @@ -283,7 +283,6 @@ QQmlBoundSignalExpression *expression = ctxtdata ? new QQmlBoundSignalExpression(ctxtdata, 0, script, true, location, line, column) : 0; signal->setExpression(expression); - signal->addToObject(); d->boundsignals += signal; } else { if (!d->ignoreUnknownSignals) diff -Nru qt5-declarative-0.1~git20120402/src/quick/util/qquicktransition.cpp qt5-declarative-0.1~git20120423/src/quick/util/qquicktransition.cpp --- qt5-declarative-0.1~git20120402/src/quick/util/qquicktransition.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/util/qquicktransition.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -96,34 +96,6 @@ \sa {QML Animation and Transitions}, {declarative/animation/states}{states example}, {qmlstates}{States}, {QtQml} */ -QQuickTransitionInstance::QQuickTransitionInstance() - : m_anim(0) -{ -} - -QQuickTransitionInstance::~QQuickTransitionInstance() -{ - delete m_anim; -} - -void QQuickTransitionInstance::start() -{ - if (m_anim) - m_anim->start(); -} - -void QQuickTransitionInstance::stop() -{ - if (m_anim) - m_anim->stop(); -} - -bool QQuickTransitionInstance::isRunning() const -{ - return m_anim && m_anim->state() == QAbstractAnimationJob::Running; -} - - //ParallelAnimationWrapper allows us to do a "callback" when the animation finishes, rather than connecting //and disconnecting signals and slots frequently class ParallelAnimationWrapper : public QParallelAnimationGroupJob @@ -136,21 +108,32 @@ virtual void updateState(QAbstractAnimationJob::State newState, QAbstractAnimationJob::State oldState); }; -class QQuickTransitionPrivate : public QObjectPrivate +class QQuickTransitionPrivate : public QObjectPrivate, QAnimationJobChangeListener { Q_DECLARE_PUBLIC(QQuickTransition) public: QQuickTransitionPrivate() - : fromState(QLatin1String("*")), toState(QLatin1String("*")), - reversed(false), reversible(false), enabled(true) + : fromState(QLatin1String("*")), toState(QLatin1String("*")) + , runningInstanceCount(0), state(QAbstractAnimationJob::Stopped) + , reversed(false), reversible(false), enabled(true) { } + void removeStateChangeListener(QAbstractAnimationJob *anim) + { + if (anim) + anim->removeAnimationChangeListener(this, QAbstractAnimationJob::StateChange); + } + QString fromState; QString toState; + quint32 runningInstanceCount; + QAbstractAnimationJob::State state; bool reversed; bool reversible; bool enabled; +protected: + virtual void animationStateChanged(QAbstractAnimationJob *, QAbstractAnimationJob::State, QAbstractAnimationJob::State); static void append_animation(QQmlListProperty *list, QQuickAbstractAnimation *a); static int animation_count(QQmlListProperty *list); @@ -187,6 +170,21 @@ } } +void QQuickTransitionPrivate::animationStateChanged(QAbstractAnimationJob *, QAbstractAnimationJob::State newState, QAbstractAnimationJob::State) +{ + Q_Q(QQuickTransition); + + if (newState == QAbstractAnimationJob::Running) { + if (!runningInstanceCount) + emit q->runningChanged(); + runningInstanceCount++; + } else if (newState == QAbstractAnimationJob::Stopped) { + runningInstanceCount--; + if (!runningInstanceCount) + emit q->runningChanged(); + } +} + void ParallelAnimationWrapper::updateState(QAbstractAnimationJob::State newState, QAbstractAnimationJob::State oldState) { QParallelAnimationGroupJob::updateState(newState, oldState); @@ -198,6 +196,34 @@ } } +QQuickTransitionInstance::QQuickTransitionInstance(QQuickTransitionPrivate *transition, QAbstractAnimationJob *anim) + : m_transition(transition) + , m_anim(anim) +{ +} + +QQuickTransitionInstance::~QQuickTransitionInstance() +{ + m_transition->removeStateChangeListener(m_anim); + delete m_anim; +} + +void QQuickTransitionInstance::start() +{ + if (m_anim) + m_anim->start(); +} + +void QQuickTransitionInstance::stop() +{ + if (m_anim) + m_anim->stop(); +} + +bool QQuickTransitionInstance::isRunning() const +{ + return m_anim && m_anim->state() == QAbstractAnimationJob::Running; +} QQuickTransition::QQuickTransition(QObject *parent) : QObject(*(new QQuickTransitionPrivate), parent) @@ -240,8 +266,8 @@ group->setDirection(d->reversed ? QAbstractAnimationJob::Backward : QAbstractAnimationJob::Forward); - QQuickTransitionInstance *wrapper = new QQuickTransitionInstance; - wrapper->m_anim = group; + group->addAnimationChangeListener(d, QAbstractAnimationJob::StateChange); + QQuickTransitionInstance *wrapper = new QQuickTransitionInstance(d, group); return wrapper; } @@ -386,6 +412,20 @@ } /*! + \qmlproperty bool QtQuick2::Transition::running + + This property holds whether the transition is currently running. + + This property is read only. +*/ +bool QQuickTransition::running() const +{ + Q_D(const QQuickTransition); + return d->runningInstanceCount; +} + + +/*! \qmlproperty list QtQuick2::Transition::animations \default diff -Nru qt5-declarative-0.1~git20120402/src/quick/util/qquicktransition_p.h qt5-declarative-0.1~git20120423/src/quick/util/qquicktransition_p.h --- qt5-declarative-0.1~git20120402/src/quick/util/qquicktransition_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/quick/util/qquicktransition_p.h 2012-04-23 11:32:40.000000000 +0000 @@ -43,6 +43,7 @@ #define QQUICKTRANSITION_H #include "qquickstate_p.h" +#include #include #include @@ -55,12 +56,11 @@ class QQuickTransitionPrivate; class QQuickTransitionManager; class QQuickTransition; -class QAbstractAnimationJob; class Q_QUICK_EXPORT QQuickTransitionInstance { public: - QQuickTransitionInstance(); + QQuickTransitionInstance(QQuickTransitionPrivate *transition, QAbstractAnimationJob *anim); ~QQuickTransitionInstance(); void start(); @@ -69,6 +69,7 @@ bool isRunning() const; private: + QQuickTransitionPrivate *m_transition; QAbstractAnimationJob *m_anim; friend class QQuickTransition; }; @@ -81,6 +82,7 @@ Q_PROPERTY(QString from READ fromState WRITE setFromState NOTIFY fromChanged) Q_PROPERTY(QString to READ toState WRITE setToState NOTIFY toChanged) Q_PROPERTY(bool reversible READ reversible WRITE setReversible NOTIFY reversibleChanged) + Q_PROPERTY(bool running READ running NOTIFY runningChanged) Q_PROPERTY(QQmlListProperty animations READ animations) Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged) Q_CLASSINFO("DefaultProperty", "animations") @@ -102,6 +104,8 @@ bool enabled() const; void setEnabled(bool enabled); + bool running() const; + QQmlListProperty animations(); QQuickTransitionInstance *prepare(QQuickStateOperation::ActionList &actions, @@ -116,6 +120,7 @@ void toChanged(); void reversibleChanged(); void enabledChanged(); + void runningChanged(); }; QT_END_NAMESPACE diff -Nru qt5-declarative-0.1~git20120402/src/src.pro qt5-declarative-0.1~git20120423/src/src.pro --- qt5-declarative-0.1~git20120402/src/src.pro 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/src/src.pro 2012-04-23 11:32:40.000000000 +0000 @@ -1,6 +1,6 @@ TEMPLATE = subdirs CONFIG += ordered -SUBDIRS += qml quick plugins +SUBDIRS += qml quick particles plugins contains(QT_CONFIG, qmltest): SUBDIRS += qmltest diff -Nru qt5-declarative-0.1~git20120402/sync.profile qt5-declarative-0.1~git20120423/sync.profile --- qt5-declarative-0.1~git20120402/sync.profile 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/sync.profile 2012-04-23 11:44:59.000000000 +0000 @@ -1,6 +1,7 @@ %modules = ( # path to module name map "QtQml" => "$basedir/src/qml", "QtQuick" => "$basedir/src/quick", + "QtQuickParticles" => "$basedir/src/particles", "QtQuickTest" => "$basedir/src/qmltest", "QtQmlDevTools" => "$basedir/src/qmldevtools", "QtDeclarative" => "$basedir/src/compatibility", @@ -18,10 +19,12 @@ "network" => "#include \n", "testlib" => "#include \n", "qml" => "#include \n", + "quick" => "#include \n", ); %modulepris = ( "QtQml" => "$basedir/modules/qt_qml.pri", "QtQuick" => "$basedir/modules/qt_quick.pri", + "QtQuickParticles" => "$basedir/modules/qt_quickparticles.pri", "QtQuickTest" => "$basedir/modules/qt_qmltest.pri", "QtQmlDevTools" => "$basedir/modules/qt_qmldevtools.pri", "QtDeclarative" => "$basedir/modules/qt_declarative.pri", diff -Nru qt5-declarative-0.1~git20120402/tests/auto/particles/particles.pro qt5-declarative-0.1~git20120423/tests/auto/particles/particles.pro --- qt5-declarative-0.1~git20120402/tests/auto/particles/particles.pro 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/particles/particles.pro 2012-04-23 11:32:40.000000000 +0000 @@ -7,6 +7,7 @@ qquickcustomaffector \ qquickcustomparticle \ qquickellipseextruder \ + qquickgroupgoal \ qquickfriction \ qquickgravity \ qquickimageparticle \ @@ -18,6 +19,7 @@ qquickpointattractor \ qquickpointdirection \ qquickrectangleextruder \ + qquickspritegoal \ qquicktargetdirection \ qquicktrailemitter \ qquickturbulence \ diff -Nru qt5-declarative-0.1~git20120402/tests/auto/particles/qquickage/qquickage.pro qt5-declarative-0.1~git20120423/tests/auto/particles/qquickage/qquickage.pro --- qt5-declarative-0.1~git20120402/tests/auto/particles/qquickage/qquickage.pro 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/particles/qquickage/qquickage.pro 2012-04-23 11:32:40.000000000 +0000 @@ -6,5 +6,5 @@ include (../../shared/util.pri) TESTDATA = data/* -QT += core-private gui-private v8-private qml-private quick-private testlib +QT += core-private gui-private v8-private qml-private quick-private quickparticles-private testlib diff -Nru qt5-declarative-0.1~git20120402/tests/auto/particles/qquickangleddirection/qquickangleddirection.pro qt5-declarative-0.1~git20120423/tests/auto/particles/qquickangleddirection/qquickangleddirection.pro --- qt5-declarative-0.1~git20120402/tests/auto/particles/qquickangleddirection/qquickangleddirection.pro 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/particles/qquickangleddirection/qquickangleddirection.pro 2012-04-23 11:32:40.000000000 +0000 @@ -6,5 +6,5 @@ include (../../shared/util.pri) TESTDATA = data/* -QT += core-private gui-private v8-private qml-private quick-private testlib +QT += core-private gui-private v8-private qml-private quick-private quickparticles-private testlib diff -Nru qt5-declarative-0.1~git20120402/tests/auto/particles/qquickcumulativedirection/qquickcumulativedirection.pro qt5-declarative-0.1~git20120423/tests/auto/particles/qquickcumulativedirection/qquickcumulativedirection.pro --- qt5-declarative-0.1~git20120402/tests/auto/particles/qquickcumulativedirection/qquickcumulativedirection.pro 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/particles/qquickcumulativedirection/qquickcumulativedirection.pro 2012-04-23 11:32:40.000000000 +0000 @@ -6,5 +6,5 @@ include (../../shared/util.pri) TESTDATA = data/* -QT += core-private gui-private v8-private qml-private quick-private testlib +QT += core-private gui-private v8-private qml-private quick-private quickparticles-private testlib diff -Nru qt5-declarative-0.1~git20120402/tests/auto/particles/qquickcustomaffector/qquickcustomaffector.pro qt5-declarative-0.1~git20120423/tests/auto/particles/qquickcustomaffector/qquickcustomaffector.pro --- qt5-declarative-0.1~git20120402/tests/auto/particles/qquickcustomaffector/qquickcustomaffector.pro 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/particles/qquickcustomaffector/qquickcustomaffector.pro 2012-04-23 11:32:40.000000000 +0000 @@ -6,5 +6,5 @@ include (../../shared/util.pri) TESTDATA = data/* -QT += core-private gui-private v8-private qml-private quick-private testlib +QT += core-private gui-private v8-private qml-private quick-private quickparticles-private testlib diff -Nru qt5-declarative-0.1~git20120402/tests/auto/particles/qquickcustomparticle/data/deleteSourceItem.qml qt5-declarative-0.1~git20120423/tests/auto/particles/qquickcustomparticle/data/deleteSourceItem.qml --- qt5-declarative-0.1~git20120402/tests/auto/particles/qquickcustomparticle/data/deleteSourceItem.qml 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/particles/qquickcustomparticle/data/deleteSourceItem.qml 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 +import QtQuick.Particles 2.0 + +Rectangle { + color: "black" + width: 320 + height: 320 + + ParticleSystem { + id: sys + objectName: "system" + anchors.fill: parent + + CustomParticle { + id: cp + property variant source + } + + Emitter{ + //0,0 position + size: 32 + emitRate: 1000 + lifeSpan: 500 + } + } + + ShaderEffectSource { + id: doomedses + hideSource: true + sourceItem: Image { + id: doomed + source: "../../shared/star.png" + } + } + + function setDeletedSourceItem() { + doomed.destroy(); + cp.source = doomedses; + } +} diff -Nru qt5-declarative-0.1~git20120402/tests/auto/particles/qquickcustomparticle/qquickcustomparticle.pro qt5-declarative-0.1~git20120423/tests/auto/particles/qquickcustomparticle/qquickcustomparticle.pro --- qt5-declarative-0.1~git20120402/tests/auto/particles/qquickcustomparticle/qquickcustomparticle.pro 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/particles/qquickcustomparticle/qquickcustomparticle.pro 2012-04-23 11:32:40.000000000 +0000 @@ -6,5 +6,5 @@ include (../../shared/util.pri) TESTDATA = data/* -QT += core-private gui-private v8-private qml-private quick-private testlib +QT += core-private gui-private v8-private qml-private quick-private quickparticles-private testlib diff -Nru qt5-declarative-0.1~git20120402/tests/auto/particles/qquickcustomparticle/tst_qquickcustomparticle.cpp qt5-declarative-0.1~git20120423/tests/auto/particles/qquickcustomparticle/tst_qquickcustomparticle.cpp --- qt5-declarative-0.1~git20120402/tests/auto/particles/qquickcustomparticle/tst_qquickcustomparticle.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/particles/qquickcustomparticle/tst_qquickcustomparticle.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -55,6 +55,7 @@ private slots: void initTestCase(); void test_basic(); + void test_deleteSourceItem(); }; void tst_qquickcustomparticle::initTestCase() @@ -94,6 +95,20 @@ QVERIFY(oneNonZero);//Zero is a valid value, but it also needs to be set to a random number } +void tst_qquickcustomparticle::test_deleteSourceItem() +{ + // purely to ensure that deleting the sourceItem of a shader doesn't cause a crash + QQuickView* view = createView(testFileUrl("deleteSourceItem.qml"), 600); + QVERIFY(view); + QObject *obj = view->rootObject(); + QVERIFY(obj); + QQuickParticleSystem* system = view->rootObject()->findChild("system"); + ensureAnimTime(200, system->m_animation); + QMetaObject::invokeMethod(obj, "setDeletedSourceItem"); + ensureAnimTime(200, system->m_animation); + delete view; +} + QTEST_MAIN(tst_qquickcustomparticle); #include "tst_qquickcustomparticle.moc" diff -Nru qt5-declarative-0.1~git20120402/tests/auto/particles/qquickellipseextruder/qquickellipseextruder.pro qt5-declarative-0.1~git20120423/tests/auto/particles/qquickellipseextruder/qquickellipseextruder.pro --- qt5-declarative-0.1~git20120402/tests/auto/particles/qquickellipseextruder/qquickellipseextruder.pro 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/particles/qquickellipseextruder/qquickellipseextruder.pro 2012-04-23 11:32:40.000000000 +0000 @@ -6,5 +6,5 @@ include (../../shared/util.pri) TESTDATA = data/* -QT += core-private gui-private v8-private qml-private quick-private testlib +QT += core-private gui-private v8-private qml-private quick-private quickparticles-private testlib diff -Nru qt5-declarative-0.1~git20120402/tests/auto/particles/qquickfriction/qquickfriction.pro qt5-declarative-0.1~git20120423/tests/auto/particles/qquickfriction/qquickfriction.pro --- qt5-declarative-0.1~git20120402/tests/auto/particles/qquickfriction/qquickfriction.pro 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/particles/qquickfriction/qquickfriction.pro 2012-04-23 11:32:40.000000000 +0000 @@ -6,5 +6,5 @@ include (../../shared/util.pri) TESTDATA = data/* -QT += core-private gui-private v8-private qml-private quick-private testlib +QT += core-private gui-private v8-private qml-private quick-private quickparticles-private testlib diff -Nru qt5-declarative-0.1~git20120402/tests/auto/particles/qquickgravity/qquickgravity.pro qt5-declarative-0.1~git20120423/tests/auto/particles/qquickgravity/qquickgravity.pro --- qt5-declarative-0.1~git20120402/tests/auto/particles/qquickgravity/qquickgravity.pro 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/particles/qquickgravity/qquickgravity.pro 2012-04-23 11:32:40.000000000 +0000 @@ -6,5 +6,5 @@ include (../../shared/util.pri) TESTDATA = data/* -QT += core-private gui-private v8-private qml-private quick-private testlib +QT += core-private gui-private v8-private qml-private quick-private quickparticles-private testlib diff -Nru qt5-declarative-0.1~git20120402/tests/auto/particles/qquickgroupgoal/qquickgroupgoal.pro qt5-declarative-0.1~git20120423/tests/auto/particles/qquickgroupgoal/qquickgroupgoal.pro --- qt5-declarative-0.1~git20120402/tests/auto/particles/qquickgroupgoal/qquickgroupgoal.pro 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/particles/qquickgroupgoal/qquickgroupgoal.pro 2012-04-23 11:32:40.000000000 +0000 @@ -6,5 +6,5 @@ include (../../shared/util.pri) TESTDATA = data/* -QT += core-private gui-private v8-private qml-private testlib +QT += core-private gui-private v8-private qml-private testlib quick-private quickparticles-private diff -Nru qt5-declarative-0.1~git20120402/tests/auto/particles/qquickimageparticle/qquickimageparticle.pro qt5-declarative-0.1~git20120423/tests/auto/particles/qquickimageparticle/qquickimageparticle.pro --- qt5-declarative-0.1~git20120402/tests/auto/particles/qquickimageparticle/qquickimageparticle.pro 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/particles/qquickimageparticle/qquickimageparticle.pro 2012-04-23 11:32:40.000000000 +0000 @@ -6,4 +6,4 @@ include (../../shared/util.pri) TESTDATA = data/* -QT += core-private gui-private v8-private qml-private quick-private testlib +QT += core-private gui-private v8-private qml-private quick-private quickparticles-private testlib diff -Nru qt5-declarative-0.1~git20120402/tests/auto/particles/qquickitemparticle/qquickitemparticle.pro qt5-declarative-0.1~git20120423/tests/auto/particles/qquickitemparticle/qquickitemparticle.pro --- qt5-declarative-0.1~git20120402/tests/auto/particles/qquickitemparticle/qquickitemparticle.pro 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/particles/qquickitemparticle/qquickitemparticle.pro 2012-04-23 11:32:40.000000000 +0000 @@ -6,5 +6,5 @@ include (../../shared/util.pri) TESTDATA = data/* -QT += core-private gui-private v8-private qml-private quick-private testlib +QT += core-private gui-private v8-private qml-private quick-private quickparticles-private testlib diff -Nru qt5-declarative-0.1~git20120402/tests/auto/particles/qquicklineextruder/qquicklineextruder.pro qt5-declarative-0.1~git20120423/tests/auto/particles/qquicklineextruder/qquicklineextruder.pro --- qt5-declarative-0.1~git20120402/tests/auto/particles/qquicklineextruder/qquicklineextruder.pro 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/particles/qquicklineextruder/qquicklineextruder.pro 2012-04-23 11:32:40.000000000 +0000 @@ -6,5 +6,5 @@ include (../../shared/util.pri) TESTDATA = data/* -QT += core-private gui-private v8-private qml-private quick-private testlib +QT += core-private gui-private v8-private qml-private quick-private quickparticles-private testlib diff -Nru qt5-declarative-0.1~git20120402/tests/auto/particles/qquickmaskextruder/qquickmaskextruder.pro qt5-declarative-0.1~git20120423/tests/auto/particles/qquickmaskextruder/qquickmaskextruder.pro --- qt5-declarative-0.1~git20120402/tests/auto/particles/qquickmaskextruder/qquickmaskextruder.pro 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/particles/qquickmaskextruder/qquickmaskextruder.pro 2012-04-23 11:32:40.000000000 +0000 @@ -6,5 +6,5 @@ include (../../shared/util.pri) TESTDATA = data/* -QT += core-private gui-private v8-private qml-private quick-private testlib +QT += core-private gui-private v8-private qml-private quick-private quickparticles-private testlib diff -Nru qt5-declarative-0.1~git20120402/tests/auto/particles/qquickparticlegroup/qquickparticlegroup.pro qt5-declarative-0.1~git20120423/tests/auto/particles/qquickparticlegroup/qquickparticlegroup.pro --- qt5-declarative-0.1~git20120402/tests/auto/particles/qquickparticlegroup/qquickparticlegroup.pro 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/particles/qquickparticlegroup/qquickparticlegroup.pro 2012-04-23 11:32:40.000000000 +0000 @@ -6,5 +6,5 @@ include (../../shared/util.pri) TESTDATA = data/* -QT += core-private gui-private v8-private qml-private quick-private testlib +QT += core-private gui-private v8-private qml-private quick-private quickparticles-private testlib diff -Nru qt5-declarative-0.1~git20120402/tests/auto/particles/qquickparticlesystem/qquickparticlesystem.pro qt5-declarative-0.1~git20120423/tests/auto/particles/qquickparticlesystem/qquickparticlesystem.pro --- qt5-declarative-0.1~git20120402/tests/auto/particles/qquickparticlesystem/qquickparticlesystem.pro 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/particles/qquickparticlesystem/qquickparticlesystem.pro 2012-04-23 11:32:40.000000000 +0000 @@ -6,5 +6,5 @@ include (../../shared/util.pri) TESTDATA = data/* -QT += core-private gui-private v8-private qml-private quick-private testlib +QT += core-private gui-private v8-private qml-private quick-private quickparticles-private testlib diff -Nru qt5-declarative-0.1~git20120402/tests/auto/particles/qquickpointattractor/qquickpointattractor.pro qt5-declarative-0.1~git20120423/tests/auto/particles/qquickpointattractor/qquickpointattractor.pro --- qt5-declarative-0.1~git20120402/tests/auto/particles/qquickpointattractor/qquickpointattractor.pro 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/particles/qquickpointattractor/qquickpointattractor.pro 2012-04-23 11:32:40.000000000 +0000 @@ -6,5 +6,5 @@ include (../../shared/util.pri) TESTDATA = data/* -QT += core-private gui-private v8-private qml-private quick-private testlib +QT += core-private gui-private v8-private qml-private quick-private quickparticles-private testlib diff -Nru qt5-declarative-0.1~git20120402/tests/auto/particles/qquickpointdirection/qquickpointdirection.pro qt5-declarative-0.1~git20120423/tests/auto/particles/qquickpointdirection/qquickpointdirection.pro --- qt5-declarative-0.1~git20120402/tests/auto/particles/qquickpointdirection/qquickpointdirection.pro 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/particles/qquickpointdirection/qquickpointdirection.pro 2012-04-23 11:32:40.000000000 +0000 @@ -6,5 +6,5 @@ include (../../shared/util.pri) TESTDATA = data/* -QT += core-private gui-private v8-private qml-private quick-private testlib +QT += core-private gui-private v8-private qml-private quick-private quickparticles-private testlib diff -Nru qt5-declarative-0.1~git20120402/tests/auto/particles/qquickrectangleextruder/qquickrectangleextruder.pro qt5-declarative-0.1~git20120423/tests/auto/particles/qquickrectangleextruder/qquickrectangleextruder.pro --- qt5-declarative-0.1~git20120402/tests/auto/particles/qquickrectangleextruder/qquickrectangleextruder.pro 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/particles/qquickrectangleextruder/qquickrectangleextruder.pro 2012-04-23 11:32:40.000000000 +0000 @@ -6,5 +6,5 @@ include (../../shared/util.pri) TESTDATA = data/* -QT += core-private gui-private v8-private qml-private quick-private testlib +QT += core-private gui-private v8-private qml-private quick-private quickparticles-private testlib diff -Nru qt5-declarative-0.1~git20120402/tests/auto/particles/qquickspritegoal/data/basic.qml qt5-declarative-0.1~git20120423/tests/auto/particles/qquickspritegoal/data/basic.qml --- qt5-declarative-0.1~git20120402/tests/auto/particles/qquickspritegoal/data/basic.qml 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/particles/qquickspritegoal/data/basic.qml 2012-04-23 11:32:40.000000000 +0000 @@ -57,12 +57,12 @@ name: "happy" source: "../../shared/squarefacesprite.png" frames: 6 - duration: 120 + frameDuration: 120 }, Sprite { name: "twoHappy" source: "../../shared/squarefacesprite.png" frames: 3 - duration: 240 + frameDuration: 240 }] } diff -Nru qt5-declarative-0.1~git20120402/tests/auto/particles/qquickspritegoal/qquickspritegoal.pro qt5-declarative-0.1~git20120423/tests/auto/particles/qquickspritegoal/qquickspritegoal.pro --- qt5-declarative-0.1~git20120402/tests/auto/particles/qquickspritegoal/qquickspritegoal.pro 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/particles/qquickspritegoal/qquickspritegoal.pro 2012-04-23 11:32:40.000000000 +0000 @@ -6,5 +6,5 @@ include (../../shared/util.pri) TESTDATA = data/* -QT += core-private gui-private v8-private qml-private testlib +QT += core-private gui-private v8-private qml-private testlib quick-private quickparticles-private diff -Nru qt5-declarative-0.1~git20120402/tests/auto/particles/qquicktargetdirection/qquicktargetdirection.pro qt5-declarative-0.1~git20120423/tests/auto/particles/qquicktargetdirection/qquicktargetdirection.pro --- qt5-declarative-0.1~git20120402/tests/auto/particles/qquicktargetdirection/qquicktargetdirection.pro 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/particles/qquicktargetdirection/qquicktargetdirection.pro 2012-04-23 11:32:40.000000000 +0000 @@ -6,5 +6,5 @@ include (../../shared/util.pri) TESTDATA = data/* -QT += core-private gui-private v8-private qml-private quick-private testlib +QT += core-private gui-private v8-private qml-private quick-private quickparticles-private testlib diff -Nru qt5-declarative-0.1~git20120402/tests/auto/particles/qquicktrailemitter/qquicktrailemitter.pro qt5-declarative-0.1~git20120423/tests/auto/particles/qquicktrailemitter/qquicktrailemitter.pro --- qt5-declarative-0.1~git20120402/tests/auto/particles/qquicktrailemitter/qquicktrailemitter.pro 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/particles/qquicktrailemitter/qquicktrailemitter.pro 2012-04-23 11:32:40.000000000 +0000 @@ -6,5 +6,5 @@ include (../../shared/util.pri) TESTDATA = data/* -QT += core-private gui-private v8-private qml-private quick-private testlib +QT += core-private gui-private v8-private qml-private quick-private quickparticles-private testlib diff -Nru qt5-declarative-0.1~git20120402/tests/auto/particles/qquickturbulence/qquickturbulence.pro qt5-declarative-0.1~git20120423/tests/auto/particles/qquickturbulence/qquickturbulence.pro --- qt5-declarative-0.1~git20120402/tests/auto/particles/qquickturbulence/qquickturbulence.pro 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/particles/qquickturbulence/qquickturbulence.pro 2012-04-23 11:32:40.000000000 +0000 @@ -6,5 +6,5 @@ include (../../shared/util.pri) TESTDATA = data/* -QT += core-private gui-private v8-private qml-private quick-private testlib +QT += core-private gui-private v8-private qml-private quick-private quickparticles-private testlib diff -Nru qt5-declarative-0.1~git20120402/tests/auto/particles/qquickwander/qquickwander.pro qt5-declarative-0.1~git20120423/tests/auto/particles/qquickwander/qquickwander.pro --- qt5-declarative-0.1~git20120402/tests/auto/particles/qquickwander/qquickwander.pro 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/particles/qquickwander/qquickwander.pro 2012-04-23 11:32:40.000000000 +0000 @@ -6,5 +6,5 @@ include (../../shared/util.pri) TESTDATA = data/* -QT += core-private gui-private v8-private qml-private quick-private testlib +QT += core-private gui-private v8-private qml-private quick-private quickparticles-private testlib diff -Nru qt5-declarative-0.1~git20120402/tests/auto/qml/debugger/qv8profilerservice/qv8profilerservice.pro qt5-declarative-0.1~git20120423/tests/auto/qml/debugger/qv8profilerservice/qv8profilerservice.pro --- qt5-declarative-0.1~git20120402/tests/auto/qml/debugger/qv8profilerservice/qv8profilerservice.pro 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/qml/debugger/qv8profilerservice/qv8profilerservice.pro 2012-04-23 11:32:40.000000000 +0000 @@ -13,3 +13,5 @@ CONFIG += parallel_test declarative_debug QT += qml testlib + +macx:CONFIG += insignificant_test # QTBUG-25288 diff -Nru qt5-declarative-0.1~git20120402/tests/auto/qml/debugger/shared/debugutil_p.h qt5-declarative-0.1~git20120423/tests/auto/qml/debugger/shared/debugutil_p.h --- qt5-declarative-0.1~git20120402/tests/auto/qml/debugger/shared/debugutil_p.h 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/qml/debugger/shared/debugutil_p.h 2012-04-23 11:44:59.000000000 +0000 @@ -48,6 +48,7 @@ #include #include #include +#include #include diff -Nru qt5-declarative-0.1~git20120402/tests/auto/qml/qqmlecmascript/data/deleteLaterObjectMethodCall.qml qt5-declarative-0.1~git20120423/tests/auto/qml/qqmlecmascript/data/deleteLaterObjectMethodCall.qml --- qt5-declarative-0.1~git20120402/tests/auto/qml/qqmlecmascript/data/deleteLaterObjectMethodCall.qml 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/qml/qqmlecmascript/data/deleteLaterObjectMethodCall.qml 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,22 @@ +import QtQuick 2.0 +import Qt.test 1.0 + +QtObject { + property var fn + + property var c: Component { + MyQmlObject { + function go() { + try { methodNoArgs(); } catch(e) { } + } + } + } + + Component.onCompleted: { + var f = c.createObject().go; + + gc(); + + f(); + } +} diff -Nru qt5-declarative-0.1~git20120402/tests/auto/qml/qqmlecmascript/data/InnerObject.qml qt5-declarative-0.1~git20120423/tests/auto/qml/qqmlecmascript/data/InnerObject.qml --- qt5-declarative-0.1~git20120402/tests/auto/qml/qqmlecmascript/data/InnerObject.qml 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/qml/qqmlecmascript/data/InnerObject.qml 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,13 @@ +import QtQuick 2.0 + +QtObject { + property int foo1: 100 + property int foo2: 100 + property int foo3: { return 100; } + property int foo4: { return 100; } + + property string bar1: 'Hello' + property string bar2: 'Hello' + property string bar3: { return 'Hello'; } + property string bar4: { return 'Hello'; } +} diff -Nru qt5-declarative-0.1~git20120402/tests/auto/qml/qqmlecmascript/data/OuterObject.qml qt5-declarative-0.1~git20120423/tests/auto/qml/qqmlecmascript/data/OuterObject.qml --- qt5-declarative-0.1~git20120402/tests/auto/qml/qqmlecmascript/data/OuterObject.qml 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/qml/qqmlecmascript/data/OuterObject.qml 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +Item { + property InnerObject inner: InnerObject {} +} diff -Nru qt5-declarative-0.1~git20120402/tests/auto/qml/qqmlecmascript/data/ownershipQmlIncubated.qml qt5-declarative-0.1~git20120423/tests/auto/qml/qqmlecmascript/data/ownershipQmlIncubated.qml --- qt5-declarative-0.1~git20120402/tests/auto/qml/qqmlecmascript/data/ownershipQmlIncubated.qml 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/qml/qqmlecmascript/data/ownershipQmlIncubated.qml 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,27 @@ +import QtQuick 2.0 + +Item { + id: root + + property QtObject incubatedItem + + Component.onCompleted: { + var component = Qt.createComponent("PropertyVarBaseItem.qml"); + + var incubator = component.incubateObject(root); + if (incubator.status != Component.Ready) { + incubator.onStatusChanged = function(status) { + if (status == Component.Ready) { + incubatedItem = incubator.object; + } + } + } else { + incubatedItem = incubator.object; + } + } + + function deleteIncubatedItem() { + incubatedItem.destroy(); + gc(); + } +} diff -Nru qt5-declarative-0.1~git20120402/tests/auto/qml/qqmlecmascript/data/replaceBinding.qml qt5-declarative-0.1~git20120423/tests/auto/qml/qqmlecmascript/data/replaceBinding.qml --- qt5-declarative-0.1~git20120402/tests/auto/qml/qqmlecmascript/data/replaceBinding.qml 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/qml/qqmlecmascript/data/replaceBinding.qml 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,26 @@ +import QtQuick 2.0 + +OuterObject { + property bool success: false + + inner.foo1: 200 + inner.foo2: { return 200; } + inner.foo3: 200 + inner.foo4: { return 200; } + + inner.bar1: 'Goodbye' + inner.bar2: { return 'Goodbye' } + inner.bar3: 'Goodbye' + inner.bar4: { return 'Goodbye' } + + Component.onCompleted: { + success = (inner.foo1 == 200 && + inner.foo2 == 200 && + inner.foo3 == 200 && + inner.foo4 == 200 && + inner.bar1 == 'Goodbye' && + inner.bar2 == 'Goodbye' && + inner.bar3 == 'Goodbye' && + inner.bar4 == 'Goodbye'); + } +} diff -Nru qt5-declarative-0.1~git20120402/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp qt5-declarative-0.1~git20120423/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp --- qt5-declarative-0.1~git20120402/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp 2012-04-23 11:44:59.000000000 +0000 @@ -135,6 +135,7 @@ void ownershipCustomReturnValue(); void ownershipRootObject(); void ownershipConsistency(); + void ownershipQmlIncubated(); void qlistqobjectMethods(); void strictlyEquals(); void compiled(); @@ -245,12 +246,13 @@ void invokableWithQObjectDerived(); void realTypePrecision(); void registeredFlagMethod(); - + void deleteLaterObjectMethodCall(); void automaticSemicolon(); void unaryExpression(); void switchStatement(); void withStatement(); void tryStatement(); + void replaceBinding(); private: static void propertyVarWeakRefCallback(v8::Persistent object, void* parameter); @@ -3018,6 +3020,24 @@ delete object; } +void tst_qqmlecmascript::ownershipQmlIncubated() +{ + QQmlComponent component(&engine, testFileUrl("ownershipQmlIncubated.qml")); + QObject *object = component.create(); + QVERIFY(object); + + QTRY_VERIFY(object->property("incubatedItem").value() != 0); + + QMetaObject::invokeMethod(object, "deleteIncubatedItem"); + + QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); + QCoreApplication::processEvents(); + + QVERIFY(object->property("incubatedItem").value() == 0); + + delete object; +} + class QListQObjectMethodsObject : public QObject { Q_OBJECT @@ -5982,6 +6002,13 @@ QString::fromLatin1("string:Hello World false:0 true:1 uint32:100 int32:-100 double:3.14159 date:2011-02-11 05::30:50!")); } +void tst_qqmlecmascript::deleteLaterObjectMethodCall() +{ + QQmlComponent component(&engine, testFileUrl("deleteLaterObjectMethodCall.qml")); + QObject *object = component.create(); + QVERIFY(object != 0); +} + void tst_qqmlecmascript::automaticSemicolon() { QQmlComponent component(&engine, testFileUrl("automaticSemicolon.qml")); @@ -6390,6 +6417,18 @@ delete object; } +// QTBUG-23138 +void tst_qqmlecmascript::replaceBinding() +{ + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("replaceBinding.qml")); + QObject *obj = c.create(); + QVERIFY(obj != 0); + + QVERIFY(obj->property("success").toBool()); + delete obj; +} + QTEST_MAIN(tst_qqmlecmascript) #include "tst_qqmlecmascript.moc" diff -Nru qt5-declarative-0.1~git20120402/tests/auto/qml/qqmllanguage/data/lib/com/nokia/installedtest0/InstalledTest3.qml qt5-declarative-0.1~git20120423/tests/auto/qml/qqmllanguage/data/lib/com/nokia/installedtest0/InstalledTest3.qml --- qt5-declarative-0.1~git20120402/tests/auto/qml/qqmllanguage/data/lib/com/nokia/installedtest0/InstalledTest3.qml 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/qml/qqmllanguage/data/lib/com/nokia/installedtest0/InstalledTest3.qml 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -import QtQuick 2.0 -Rectangle {} diff -Nru qt5-declarative-0.1~git20120402/tests/auto/qml/qqmllanguage/data/lib/com/nokia/installedtest0/qmldir qt5-declarative-0.1~git20120423/tests/auto/qml/qqmllanguage/data/lib/com/nokia/installedtest0/qmldir --- qt5-declarative-0.1~git20120402/tests/auto/qml/qqmllanguage/data/lib/com/nokia/installedtest0/qmldir 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/qml/qqmllanguage/data/lib/com/nokia/installedtest0/qmldir 2012-04-23 11:32:40.000000000 +0000 @@ -1,3 +1,2 @@ InstalledTest 1.4 InstalledTest2.qml InstalledTestTP 0.0 InstalledTest.qml -Rectangle 1.5 InstalledTest3.qml diff -Nru qt5-declarative-0.1~git20120402/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp qt5-declarative-0.1~git20120423/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp --- qt5-declarative-0.1~git20120402/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp 2012-04-23 11:44:59.000000000 +0000 @@ -1881,21 +1881,19 @@ << (!qmlCheckTypes()?"QQuickRectangle":"") << (!qmlCheckTypes()?"":"InstalledTest is ambiguous. Found in lib/com/nokia/installedtest/ in version 1.0 and 1.4") << false; - - // Note: imports are now reordered by increasing order of URI length QTest::newRow("installed import versus builtin 1") << - "import com.nokia.installedtest0 1.5\n" "import com.nokia.installedtest 1.5\n" + "import QtQuick 2.0\n" "Rectangle {}" << (!qmlCheckTypes()?"QQuickRectangle":"") - << (!qmlCheckTypes()?"":"Rectangle is ambiguous. Found in lib/com/nokia/installedtest0/ and in ") + << (!qmlCheckTypes()?"":"Rectangle is ambiguous. Found in file://") << true; QTest::newRow("installed import versus builtin 2") << "import QtQuick 2.0\n" "import com.nokia.installedtest 1.5\n" "Rectangle {}" << (!qmlCheckTypes()?"QQuickText":"") - << (!qmlCheckTypes()?"":"Rectangle is ambiguous. Found in lib/com/nokia/installedtest/ and in ") + << (!qmlCheckTypes()?"":"Rectangle is ambiguous. Found in lib/com/nokia/installedtest/ and in file://") << true; QTest::newRow("namespaces cannot be overridden by types 1") << "import QtQuick 2.0 as Rectangle\n" diff -Nru qt5-declarative-0.1~git20120402/tests/auto/qml/qqmlmoduleplugin/data/importsNested.1.errors.txt qt5-declarative-0.1~git20120423/tests/auto/qml/qqmlmoduleplugin/data/importsNested.1.errors.txt --- qt5-declarative-0.1~git20120402/tests/auto/qml/qqmlmoduleplugin/data/importsNested.1.errors.txt 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/qml/qqmlmoduleplugin/data/importsNested.1.errors.txt 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1 @@ +1:1:module "com.nokia.AutoTestQmlNestedPluginType.Nested" is not installed diff -Nru qt5-declarative-0.1~git20120402/tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.cpp qt5-declarative-0.1~git20120423/tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.cpp --- qt5-declarative-0.1~git20120402/tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -354,12 +354,12 @@ QTest::addColumn("file"); QTest::addColumn("errorFile"); - // Note: specific order required to induce failure (no other test case should import the - // plugin used for this test, or the alternate order test will pass spuriously) - QTest::newRow("alternateOrder") << "importsNested.1.qml" << QString(); - QTest::newRow("expectedOrder") << "importsNested.2.qml" << QString(); + // Note: no other test case should import the plugin used for this test, or the + // wrong order test will pass spuriously + QTest::newRow("wrongOrder") << "importsNested.1.qml" << "importsNested.1.errors.txt"; QTest::newRow("missingImport") << "importsNested.3.qml" << "importsNested.3.errors.txt"; QTest::newRow("invalidVersion") << "importsNested.4.qml" << "importsNested.4.errors.txt"; + QTest::newRow("correctOrder") << "importsNested.2.qml" << QString(); } void tst_qqmlmoduleplugin::importsNested() { diff -Nru qt5-declarative-0.1~git20120402/tests/auto/qml/qqmlproperty/data/invalidBinding.qml qt5-declarative-0.1~git20120423/tests/auto/qml/qqmlproperty/data/invalidBinding.qml --- qt5-declarative-0.1~git20120402/tests/auto/qml/qqmlproperty/data/invalidBinding.qml 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/qml/qqmlproperty/data/invalidBinding.qml 2012-04-23 11:32:40.000000000 +0000 @@ -10,5 +10,7 @@ Text { id: myText + + anchors.verticalCenter: parent // invalid binding } } diff -Nru qt5-declarative-0.1~git20120402/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp qt5-declarative-0.1~git20120423/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp --- qt5-declarative-0.1~git20120402/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp 2012-04-23 11:44:59.000000000 +0000 @@ -1736,6 +1736,10 @@ expectedWarning = testUrl.toString() + QString::fromLatin1(":7:36: Unable to assign QQuickText to QQuickRectangle"); QTest::ignoreMessage(QtWarningMsg, expectedWarning.toLatin1().constData()); + // V8 error message for invalid binding to anchor + expectedWarning = testUrl.toString() + QString::fromLatin1(":14: Unable to assign QQuickItem_QML_7 to QQuickAnchorLine"); + QTest::ignoreMessage(QtWarningMsg, expectedWarning.toLatin1().constData()); + QQmlComponent component(&engine, testUrl); QObject *obj = component.create(); QVERIFY(obj); diff -Nru qt5-declarative-0.1~git20120402/tests/auto/qml/qqmlqt/data/dateTimeConversion.qml qt5-declarative-0.1~git20120423/tests/auto/qml/qqmlqt/data/dateTimeConversion.qml --- qt5-declarative-0.1~git20120402/tests/auto/qml/qqmlqt/data/dateTimeConversion.qml 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/qml/qqmlqt/data/dateTimeConversion.qml 2012-04-23 11:32:40.000000000 +0000 @@ -11,4 +11,10 @@ property variant qdatetime4: new Date(2001,1,2) // 2001/02/02 hh:mm:ss.zzz property variant qdatetime5: new Date(1999,0,1,2,3,4) // 1999/01/01 02:03:04.zzz property variant qdatetime6: new Date(2008,1,24,14,15,38,200) // 2008/02/24 14:15:38.200 + + // Use UTC for historical dates to avoid DST issues + property variant qdatetime7: new Date(Date.UTC(1970,0,1,0,0,0,0)) // 1970/01/01 00:00:00.000 + property variant qdatetime8: new Date(Date.UTC(1586,1,2)) // 1586/02/02 hh:mm:ss.zzz + property variant qdatetime9: new Date(Date.UTC(955,0,1,0,0,0,0)) // 955/01/01 00:00:00.000 + property variant qdatetime10: new Date(Date.UTC(113,1,24,14,15,38,200)) // 113/02/24 14:15:38.200 } diff -Nru qt5-declarative-0.1~git20120402/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp qt5-declarative-0.1~git20120423/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp --- qt5-declarative-0.1~git20120402/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp 2012-04-23 11:44:59.000000000 +0000 @@ -478,6 +478,10 @@ QDateTime dateTime4(QDate(2001,2,2), QTime(0,0,0,0)); QDateTime dateTime5(QDate(1999,1,1), QTime(2,3,4,0)); QDateTime dateTime6(QDate(2008,2,24), QTime(14,15,38,200)); + QDateTime dateTime7(QDate(1970,1,1), QTime(0,0,0,0), Qt::UTC); + QDateTime dateTime8(QDate(1586,2,2), QTime(0,0,0,0), Qt::UTC); + QDateTime dateTime9(QDate(955,1,1), QTime(0,0,0,0), Qt::UTC); + QDateTime dateTime10(QDate(113,2,24), QTime(14,15,38,200), Qt::UTC); QQmlEngine eng; QQmlComponent component(&eng, testFileUrl("dateTimeConversion.qml")); @@ -491,6 +495,10 @@ QCOMPARE(obj->property("qdatetime4").toDateTime(), dateTime4); QCOMPARE(obj->property("qdatetime5").toDateTime(), dateTime5); QCOMPARE(obj->property("qdatetime6").toDateTime(), dateTime6); + QCOMPARE(obj->property("qdatetime7").toDateTime(), dateTime7); + QCOMPARE(obj->property("qdatetime8").toDateTime(), dateTime8); + QCOMPARE(obj->property("qdatetime9").toDateTime(), dateTime9); + QCOMPARE(obj->property("qdatetime10").toDateTime(), dateTime10); } void tst_qqmlqt::dateTimeFormatting() diff -Nru qt5-declarative-0.1~git20120402/tests/auto/qml/v4/data/subscriptions.1.qml qt5-declarative-0.1~git20120423/tests/auto/qml/v4/data/subscriptions.1.qml --- qt5-declarative-0.1~git20120402/tests/auto/qml/v4/data/subscriptions.1.qml 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/qml/v4/data/subscriptions.1.qml 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,16 @@ +import QtQuick 2.0 + +Rectangle { + id: root + width: 400 + height: 400 + + property real targetHeight: menuItems.height + 1 + property real heightValue: if (1) menuItems.height //this must be v8? + property bool boolProp: menuItems.height > heightValue //this must be v4? + + Column { + id: menuItems + Item { height: 200; width: 10 } + } +} diff -Nru qt5-declarative-0.1~git20120402/tests/auto/qml/v4/data/variantHandling.qml qt5-declarative-0.1~git20120423/tests/auto/qml/v4/data/variantHandling.qml --- qt5-declarative-0.1~git20120402/tests/auto/qml/v4/data/variantHandling.qml 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/qml/v4/data/variantHandling.qml 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,67 @@ +import QtQuick 2.0 + +QtObject { + property bool pBool: true + property int pInt: 666 + property real pReal: 3.1415927 + property string pString: 'foo' + property url pUrl: 'http://tools.ietf.org/html/rfc3986#section-1.1.2' + property color pColor: Qt.rgba(1, 0, 0, 0.5) + property QtObject pObject: QtObject { property string foo: 'bar' } + + // Test assignment to variant + property variant pBoolVar: pBool + property variant pIntVar: pInt + property variant pRealVar: pReal + property variant pStringVar: pString + property variant pUrlVar: pUrl + property variant pColorVar: pColor + property variant pObjectVar: pObject + property variant pNullVar: null + property variant pVarVar: pUrlVar + + // Test equivalence + property bool boolConversionSuccess: (pBoolVar == true) + property bool intConversionSuccess: (pIntVar == 666) + property bool realConversionSuccess: (pRealVar == 3.1415927) + property bool stringConversionSuccess: (pStringVar == 'foo') + + property url comparisonUrl: 'http://tools.ietf.org/html/rfc3986#section-1.1.2' + property bool urlConversionSuccess: (pUrlVar == comparisonUrl) + + property color comparisonColor: Qt.rgba(1, 0, 0, 0.5) + property bool colorConversionSuccess: (pColorVar == comparisonColor) + + property bool objectConversionSuccess: (pObjectVar == pObject) + property bool nullConversionSuccess: (pNullVar == null) + + property bool variantConversionSuccess: (pVarVar == comparisonUrl) + + // Operations are not handled by V4 - they should pass through correctly + property variant pVarNot: !pBoolVar + property variant pVarComplement: ~pIntVar + property variant pVarEqual: (pBoolVar == pBoolVar) + property variant pVarLiteralEqual: (pBoolVar == true) + property variant pVarUnequal: (pUrlVar == pColorVar) + property variant pVarComparison: (pIntVar <= pIntVar) + property variant pVarShift: (pIntVar >> 1) + + Component.onCompleted: { + if (!boolConversionSuccess) console.warn('QV4: bool conversion failed'); + if (!intConversionSuccess) console.warn('QV4: int conversion failed'); + if (!realConversionSuccess) console.warn('QV4: real conversion failed'); + if (!stringConversionSuccess) console.warn('QV4: string conversion failed'); + if (!urlConversionSuccess) console.warn('QV4: url conversion failed'); + if (!colorConversionSuccess) console.warn('QV4: color conversion failed'); + if (!objectConversionSuccess) console.warn('QV4: object conversion failed'); + if (!nullConversionSuccess) console.warn('QV4: null conversion failed'); + if (!variantConversionSuccess) console.warn('QV4: variant conversion failed'); + if (pVarNot != false) console.warn('QV4: variant negation impeded'); + if (pVarComplement != ~666) console.warn('QV4: variant complement impeded'); + if (pVarEqual != true) console.warn('QV4: variant equality impeded'); + if (pVarLiteralEqual != true) console.warn('QV4: variant/literal equality impeded'); + if (pVarUnequal != false) console.warn('QV4: variant unequality impeded'); + if (pVarComparison != true) console.warn('QV4: variant comparison impeded'); + if (pVarShift != 333) console.warn('QV4: variant shift impeded'); + } +} diff -Nru qt5-declarative-0.1~git20120402/tests/auto/qml/v4/tst_v4.cpp qt5-declarative-0.1~git20120423/tests/auto/qml/v4/tst_v4.cpp --- qt5-declarative-0.1~git20120402/tests/auto/qml/v4/tst_v4.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/qml/v4/tst_v4.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -86,6 +86,7 @@ void conversions_data(); void conversions(); + void subscriptions(); void debuggingDumpInstructions(); // this test should be last. @@ -141,14 +142,15 @@ QTest::newRow("unary minus") << "unaryMinus.qml"; QTest::newRow("null qobject") << "nullQObject.qml"; QTest::newRow("qobject -> bool") << "objectToBool.qml"; - //QTest::newRow("conversion from bool") << "conversions.1.qml"; // QTBUG-24706 - //QTest::newRow("conversion from int") << "conversions.2.qml"; // QTBUG-24706 + QTest::newRow("conversion from bool") << "conversions.1.qml"; // QTBUG-24706 + QTest::newRow("conversion from int") << "conversions.2.qml"; // QTBUG-24706 QTest::newRow("conversion from float") << "conversions.3.qml"; - //QTest::newRow("conversion from double") << "conversions.4.qml"; // QTBUG-24706 - //QTest::newRow("conversion from real") << "conversions.5.qml"; // QTBUG-24706 - //QTest::newRow("conversion from string") << "conversions.6.qml"; // QTBUG-24706 - //QTest::newRow("conversion from url") << "conversions.7.qml"; // QTBUG-24706 + QTest::newRow("conversion from double") << "conversions.4.qml"; // QTBUG-24706 + QTest::newRow("conversion from real") << "conversions.5.qml"; // QTBUG-24706 + QTest::newRow("conversion from string") << "conversions.6.qml"; // QTBUG-24706 + QTest::newRow("conversion from url") << "conversions.7.qml"; // QTBUG-24706 QTest::newRow("conversion from vec3") << "conversions.8.qml"; + QTest::newRow("variantHandling") << "variantHandling.qml"; } void tst_v4::unnecessaryReeval() @@ -658,58 +660,58 @@ QTest::addColumn("vec3Prop"); QTest::newRow("from bool") << testFileUrl("conversions.1.qml") - << (QStringList()) + << (QStringList() << (testFileUrl("conversions.1.qml").toString() + QLatin1String(":11:15: Unable to assign bool to QUrl"))) << true << (int)true << (float)1.0 << (double)1.0 << (qreal)1.0 << QString(QLatin1String("true")) - << QUrl(testFileUrl("").toString() + QString(QLatin1String("true"))) + << QUrl() // cannot assign bool to url. << QVector3D(1, 1, 1); QTest::newRow("from integer") << testFileUrl("conversions.2.qml") - << (QStringList()) + << (QStringList() << (testFileUrl("conversions.2.qml").toString() + QLatin1String(":11:15: Unable to assign int to QUrl"))) << (bool)4 << 4 << (float)4.0 << (double)4.0 << (qreal)4.0 << QString(QLatin1String("4")) - << QUrl(testFileUrl("").toString() + QString(QLatin1String("4"))) + << QUrl() // cannot assign int to url. << QVector3D(4, 4, 4); QTest::newRow("from float") << testFileUrl("conversions.3.qml") - << (QStringList() << (testFileUrl("conversions.3.qml").toString() + QLatin1String(":11: Unable to assign double to QUrl"))) + << (QStringList() << (testFileUrl("conversions.3.qml").toString() + QLatin1String(":11:15: Unable to assign number to QUrl"))) << (bool)4.4 << (int)4.4 << (float)4.4 << (double)((float)4.4) << (qreal)((float)4.4) - << QString::number((double)((float)4.4), 'g', 15) - << QUrl() // cannot assign double to url. + << QString::number((double)((float)4.4), 'g', 16) + << QUrl() // cannot assign number to url. << QVector3D(4.4, 4.4, 4.4); QTest::newRow("from double") << testFileUrl("conversions.4.qml") - << (QStringList()) + << (QStringList() << (testFileUrl("conversions.4.qml").toString() + QLatin1String(":11:15: Unable to assign number to QUrl"))) << (bool)4.444444444 << (int)4.444444444 << (float)4.444444444 << (double)4.444444444 << (qreal)4.444444444 - << QString::number((double)4.444444444) - << QUrl(testFileUrl("").toString() + QString::number((double)4.444444444)) + << QString::number((double)4.444444444, 'g', 16) + << QUrl() // cannot assign number to url. << QVector3D(4.444444444, 4.444444444, 4.444444444); QTest::newRow("from qreal") << testFileUrl("conversions.5.qml") - << (QStringList()) + << (QStringList() << (testFileUrl("conversions.5.qml").toString() + QLatin1String(":11:15: Unable to assign number to QUrl"))) << (bool)4.44 << (int)4.44 << (float)4.44 << (double)4.44 << (qreal)4.44 << QString(QLatin1String("4.44")) - << QUrl(testFileUrl("").toString() + QString(QLatin1String("4.44"))) + << QUrl() // cannot assign number to url. << QVector3D(4.44, 4.44, 4.44); QTest::newRow("from string") << testFileUrl("conversions.6.qml") @@ -723,19 +725,20 @@ << QUrl(testFileUrl("").toString() + QString(QLatin1String("4"))) << QVector3D(4, 4, 4); - /* - //XXX TODO: QTBUG-24706 + // QTBUG-24706 QTest::newRow("from url") << testFileUrl("conversions.7.qml") - << (QStringList() << (testFileUrl("conversions.7.qml").toString() + QLatin1String(":7: Unable to assign QUrl to float"))) + << (QStringList() << (testFileUrl("conversions.7.qml").toString() + QLatin1String(":6:14: Unable to assign QUrl to int")) + << (testFileUrl("conversions.7.qml").toString() + QLatin1String(":7:16: Unable to assign QUrl to number")) + << (testFileUrl("conversions.7.qml").toString() + QLatin1String(":8:17: Unable to assign QUrl to number")) + << (testFileUrl("conversions.7.qml").toString() + QLatin1String(":9:16: Unable to assign QUrl to number"))) << true - << 0 // a url like "4" actually gets the value "file:///path/to/test/4" - << (float)0 // and the url.toString().toInt()/toDouble() of that is zero/qQNaN(). - << (double)0 - << (qreal)0 + << 0 + << (float) 0 + << (double) 0 + << (qreal) 0 << QString(testFileUrl("").toString() + QString(QLatin1String("4"))) << QUrl(testFileUrl("").toString() + QString(QLatin1String("4"))) - << QVector3D(0, 0, 0); - */ + << QVector3D(qQNaN(), qQNaN(), qQNaN()); QTest::newRow("from vector") << testFileUrl("conversions.8.qml") << (QStringList() << (testFileUrl("conversions.8.qml").toString() + QLatin1String(":11: Unable to assign QVector3D to QUrl")) @@ -754,6 +757,12 @@ << QVector3D(4, 4, 4); // except this one. } +#define COMPARE_NUMBER(type, prop, expected) \ + if (qIsNaN(expected)) \ + QVERIFY(qIsNaN(qvariant_cast(prop))); \ + else \ + QCOMPARE((prop), QVariant::fromValue(expected)); + void tst_v4::conversions() { QFETCH(QUrl, file); @@ -775,15 +784,35 @@ QVERIFY(o != 0); QCOMPARE(o->property("boolProp"), QVariant::fromValue(boolProp)); QCOMPARE(o->property("intProp"), QVariant::fromValue(intProp)); - QCOMPARE(o->property("floatProp"), QVariant::fromValue(floatProp)); - QCOMPARE(o->property("doubleProp"), QVariant::fromValue(doubleProp)); - QCOMPARE(o->property("qrealProp"), QVariant::fromValue(qrealProp)); + COMPARE_NUMBER(float, o->property("floatProp"), floatProp); + COMPARE_NUMBER(double, o->property("doubleProp"), doubleProp); + COMPARE_NUMBER(qreal, o->property("qrealProp"), qrealProp); QCOMPARE(o->property("qstringProp"), QVariant::fromValue(qstringProp)); QCOMPARE(o->property("qurlProp"), QVariant::fromValue(qurlProp)); - QCOMPARE(o->property("vec3Prop"), QVariant::fromValue(vec3Prop)); + + QVector3D vec3 = qvariant_cast(o->property("vec3Prop")); + COMPARE_NUMBER(qreal, QVariant::fromValue(vec3.x()), vec3Prop.x()); + COMPARE_NUMBER(qreal, QVariant::fromValue(vec3.y()), vec3Prop.y()); + COMPARE_NUMBER(qreal, QVariant::fromValue(vec3.z()), vec3Prop.z()); delete o; } +void tst_v4::subscriptions() +{ + { + QQmlComponent component(&engine, testFileUrl("subscriptions.1.qml")); + + QObject *o = component.create(); + QVERIFY(o != 0); + + QObject *ro = qobject_cast(o); + QVERIFY(ro != 0); + + QCOMPARE(ro->property("targetHeight"), QVariant::fromValue(201)); + + delete o; + } +} static QStringList messages; static void msgHandler(QtMsgType, const char *msg) @@ -821,40 +850,48 @@ expectedPreAddress << "\t\tLoadModuleObject\t\t) -> Output_Reg(0)"; expectedPreAddress << "\t\tLoadAttached\t\tObject_Reg(0) Attached_Index(0) -> Output_Reg(0)"; expectedPreAddress << "\t\tUnaryNot\t\tInput_Reg(0) -> Output_Reg(0)"; - expectedPreAddress << "\t\tUnaryMinusReal\t\tInput_Reg(0) -> Output_Reg(0)"; + expectedPreAddress << "\t\tUnaryMinusNumber\t\tInput_Reg(0) -> Output_Reg(0)"; expectedPreAddress << "\t\tUnaryMinusInt\t\tInput_Reg(0) -> Output_Reg(0)"; - expectedPreAddress << "\t\tUnaryPlusReal\t\tInput_Reg(0) -> Output_Reg(0)"; + expectedPreAddress << "\t\tUnaryPlusNumber\t\tInput_Reg(0) -> Output_Reg(0)"; expectedPreAddress << "\t\tUnaryPlusInt\t\tInput_Reg(0) -> Output_Reg(0)"; expectedPreAddress << "\t\tConvertBoolToInt\tInput_Reg(0) -> Output_Reg(0)"; - expectedPreAddress << "\t\tConvertBoolToReal\tInput_Reg(0) -> Output_Reg(0)"; + expectedPreAddress << "\t\tConvertBoolToNumber\tInput_Reg(0) -> Output_Reg(0)"; expectedPreAddress << "\t\tConvertBoolToString\tInput_Reg(0) -> Output_Reg(0)"; + expectedPreAddress << "\t\tConvertBoolToVariant\tInput_Reg(0) -> Output_Reg(0)"; expectedPreAddress << "\t\tConvertIntToBool\tInput_Reg(0) -> Output_Reg(0)"; - expectedPreAddress << "\t\tConvertIntToReal\tInput_Reg(0) -> Output_Reg(0)"; + expectedPreAddress << "\t\tConvertIntToNumber\tInput_Reg(0) -> Output_Reg(0)"; expectedPreAddress << "\t\tConvertIntToString\tInput_Reg(0) -> Output_Reg(0)"; - expectedPreAddress << "\t\tConvertRealToBool\tInput_Reg(0) -> Output_Reg(0)"; - expectedPreAddress << "\t\tConvertRealToInt\tInput_Reg(0) -> Output_Reg(0)"; - expectedPreAddress << "\t\tConvertRealToString\tInput_Reg(0) -> Output_Reg(0)"; + expectedPreAddress << "\t\tConvertIntToVariant\tInput_Reg(0) -> Output_Reg(0)"; + expectedPreAddress << "\t\tConvertNumberToBool\tInput_Reg(0) -> Output_Reg(0)"; + expectedPreAddress << "\t\tConvertNumberToInt\tInput_Reg(0) -> Output_Reg(0)"; + expectedPreAddress << "\t\tConvertNumberToString\tInput_Reg(0) -> Output_Reg(0)"; + expectedPreAddress << "\t\tConvertNumberToVariant\tInput_Reg(0) -> Output_Reg(0)"; expectedPreAddress << "\t\tConvertStringToBool\tInput_Reg(0) -> Output_Reg(0)"; expectedPreAddress << "\t\tConvertStringToInt\tInput_Reg(0) -> Output_Reg(0)"; - expectedPreAddress << "\t\tConvertStringToReal\tInput_Reg(0) -> Output_Reg(0)"; + expectedPreAddress << "\t\tConvertStringToNumber\tInput_Reg(0) -> Output_Reg(0)"; expectedPreAddress << "\t\tConvertStringToUrl\tInput_Reg(0) -> Output_Reg(0)"; expectedPreAddress << "\t\tConvertStringToColor\tInput_Reg(0) -> Output_Reg(0)"; + expectedPreAddress << "\t\tConvertStringToVariant\tInput_Reg(0) -> Output_Reg(0)"; expectedPreAddress << "\t\tConvertUrlToBool\tInput_Reg(0) -> Output_Reg(0)"; expectedPreAddress << "\t\tConvertUrlToString\tInput_Reg(0) -> Output_Reg(0)"; + expectedPreAddress << "\t\tConvertUrlToVariant\tInput_Reg(0) -> Output_Reg(0)"; expectedPreAddress << "\t\tConvertColorToBool\tInput_Reg(0) -> Output_Reg(0)"; expectedPreAddress << "\t\tConvertColorToString\tInput_Reg(0) -> Output_Reg(0)"; + expectedPreAddress << "\t\tConvertColorToVariant\tInput_Reg(0) -> Output_Reg(0)"; expectedPreAddress << "\t\tConvertObjectToBool\tInput_Reg(0) -> Output_Reg(0)"; + expectedPreAddress << "\t\tConvertObjectToVariant\tInput_Reg(0) -> Output_Reg(0)"; expectedPreAddress << "\t\tConvertNullToObject\tInput_Reg(0) -> Output_Reg(0)"; + expectedPreAddress << "\t\tConvertNullToVariant\tInput_Reg(0) -> Output_Reg(0)"; expectedPreAddress << "\t\tResolveUrl\t\tInput_Reg(0) -> Output_Reg(0)"; - expectedPreAddress << "\t\tMathSinReal\t\tInput_Reg(0) -> Output_Reg(0)"; - expectedPreAddress << "\t\tMathCosReal\t\tInput_Reg(0) -> Output_Reg(0)"; - expectedPreAddress << "\t\tMathAbsReal\t\tInput_Reg(0) -> Output_Reg(0)"; - expectedPreAddress << "\t\tMathRoundReal\t\tInput_Reg(0) -> Output_Reg(0)"; - expectedPreAddress << "\t\tMathFloorReal\t\tInput_Reg(0) -> Output_Reg(0)"; - expectedPreAddress << "\t\tMathCeilReal\t\tInput_Reg(0) -> Output_Reg(0)"; - expectedPreAddress << "\t\tMathPIReal\t\tInput_Reg(0) -> Output_Reg(0)"; + expectedPreAddress << "\t\tMathSinNumber\t\tInput_Reg(0) -> Output_Reg(0)"; + expectedPreAddress << "\t\tMathCosNumber\t\tInput_Reg(0) -> Output_Reg(0)"; + expectedPreAddress << "\t\tMathAbsNumber\t\tInput_Reg(0) -> Output_Reg(0)"; + expectedPreAddress << "\t\tMathRoundNumber\t\tInput_Reg(0) -> Output_Reg(0)"; + expectedPreAddress << "\t\tMathFloorNumber\t\tInput_Reg(0) -> Output_Reg(0)"; + expectedPreAddress << "\t\tMathCeilNumber\t\tInput_Reg(0) -> Output_Reg(0)"; + expectedPreAddress << "\t\tMathPINumber\t\tInput_Reg(0) -> Output_Reg(0)"; expectedPreAddress << "\t\tLoadNull\t\tConstant(null) -> Output_Reg(0)"; - expectedPreAddress << "\t\tLoadReal\t\tConstant(0) -> Output_Reg(0)"; + expectedPreAddress << "\t\tLoadNumber\t\tConstant(0) -> Output_Reg(0)"; expectedPreAddress << "\t\tLoadInt\t\t\tConstant(0) -> Output_Reg(0)"; expectedPreAddress << "\t\tLoadBool\t\tConstant(false) -> Output_Reg(0)"; expectedPreAddress << "\t\tLoadString\t\tString_DataIndex(0) String_Length(0) -> Output_Register(0)"; @@ -863,23 +900,23 @@ expectedPreAddress << "\t\tBitAndInt\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)"; expectedPreAddress << "\t\tBitOrInt\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)"; expectedPreAddress << "\t\tBitXorInt\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)"; - expectedPreAddress << "\t\tAddReal\t\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)"; + expectedPreAddress << "\t\tAddNumber\t\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)"; expectedPreAddress << "\t\tAddString\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)"; - expectedPreAddress << "\t\tSubReal\t\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)"; - expectedPreAddress << "\t\tMulReal\t\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)"; - expectedPreAddress << "\t\tDivReal\t\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)"; - expectedPreAddress << "\t\tModReal\t\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)"; + expectedPreAddress << "\t\tSubNumber\t\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)"; + expectedPreAddress << "\t\tMulNumber\t\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)"; + expectedPreAddress << "\t\tDivNumber\t\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)"; + expectedPreAddress << "\t\tModNumber\t\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)"; expectedPreAddress << "\t\tLShiftInt\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)"; expectedPreAddress << "\t\tRShiftInt\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)"; expectedPreAddress << "\t\tURShiftInt\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)"; - expectedPreAddress << "\t\tGtReal\t\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)"; - expectedPreAddress << "\t\tLtReal\t\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)"; - expectedPreAddress << "\t\tGeReal\t\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)"; - expectedPreAddress << "\t\tLeReal\t\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)"; - expectedPreAddress << "\t\tEqualReal\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)"; - expectedPreAddress << "\t\tNotEqualReal\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)"; - expectedPreAddress << "\t\tStrictEqualReal\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)"; - expectedPreAddress << "\t\tStrictNotEqualReal\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)"; + expectedPreAddress << "\t\tGtNumber\t\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)"; + expectedPreAddress << "\t\tLtNumber\t\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)"; + expectedPreAddress << "\t\tGeNumber\t\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)"; + expectedPreAddress << "\t\tLeNumber\t\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)"; + expectedPreAddress << "\t\tEqualNumber\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)"; + expectedPreAddress << "\t\tNotEqualNumber\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)"; + expectedPreAddress << "\t\tStrictEqualNumber\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)"; + expectedPreAddress << "\t\tStrictNotEqualNumber\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)"; expectedPreAddress << "\t\tGtString\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)"; expectedPreAddress << "\t\tLtString\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)"; expectedPreAddress << "\t\tGeString\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)"; @@ -892,8 +929,8 @@ expectedPreAddress << "\t\tNotEqualObject\t\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)"; expectedPreAddress << "\t\tStrictEqualObject\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)"; expectedPreAddress << "\t\tStrictNotEqualObject\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)"; - expectedPreAddress << "\t\tMathMaxReal\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)"; - expectedPreAddress << "\t\tMathMinReal\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)"; + expectedPreAddress << "\t\tMathMaxNumber\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)"; + expectedPreAddress << "\t\tMathMinNumber\tInput_Reg(0) Input_Reg(0) -> Output_Reg(0)"; expectedPreAddress << "\t\tNewString\t\tRegister(0)"; expectedPreAddress << "\t\tNewUrl\t\t\tRegister(0)"; expectedPreAddress << "\t\tCleanupRegister\t\tRegister(0)"; @@ -905,6 +942,7 @@ expectedPreAddress << "\t\tBranchFalse\t\tAddress(UNIT_TEST_BRANCH_ADDRESS) [if false == Input_Reg(0)]"; //(address + size() + i->branchop.offset) expectedPreAddress << "\t\tBranch\t\t\tAddress(UNIT_TEST_BRANCH_ADDRESS)"; //(address + size() + i->branchop.offset) expectedPreAddress << "\t\tBlock\t\t\tMask(0)"; + expectedPreAddress << "\t\tThrow\t\t\tInputReg(0)"; expectedPreAddress << "\t\tInitString\t\tString_DataIndex(0) -> String_Slot(0)"; QStringList expected; @@ -920,7 +958,7 @@ const char *codeAddr = start; int whichExpected = 0; #define DUMP_INSTR_SIZE_IN_UNIT_TEST(I, FMT) { \ - QString currExpected = expectedPreAddress.at(whichExpected++); \ + QString currExpected = whichExpected < expectedPreAddress.size() ? expectedPreAddress.at(whichExpected++) : QString(); \ currExpected.prepend(getLeading(codeAddr - start)); \ expected.append(currExpected); \ codeAddr += QQmlJS::V4Instr::size(static_cast(QQmlJS::V4Instr::I)); \ diff -Nru qt5-declarative-0.1~git20120402/tests/auto/qmltest/qmltest.pro qt5-declarative-0.1~git20120423/tests/auto/qmltest/qmltest.pro --- qt5-declarative-0.1~git20120402/tests/auto/qmltest/qmltest.pro 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/qmltest/qmltest.pro 2012-04-23 11:32:40.000000000 +0000 @@ -9,4 +9,4 @@ importFiles.path = . DEPLOYMENT += importFiles -CONFIG+=insignificant_test \ No newline at end of file +CONFIG+=insignificant_test # QTBUG-25306 diff -Nru qt5-declarative-0.1~git20120402/tests/auto/qmltest/selftests/tst_datadriven.qml qt5-declarative-0.1~git20120423/tests/auto/qmltest/selftests/tst_datadriven.qml --- qt5-declarative-0.1~git20120402/tests/auto/qmltest/selftests/tst_datadriven.qml 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/qmltest/selftests/tst_datadriven.qml 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 +import QtTest 1.0 + +Item { + TestCase { + name:"data-driven-empty-init-data" + property int tests:0; + property int init_data_called_times:0; + function init_data() {init_data_called_times++;} + function initTestCase() {tests = 0; init_data_called_times = 0;} + function cleanupTestCase() {compare(tests, 2); compare(init_data_called_times, 2);} + + function test_test1() {tests++;} + function test_test2() {tests++;} + } + TestCase { + name:"data-driven-no-init-data" + property int tests:0; + function initTestCase() {tests = 0;} + function cleanupTestCase() {compare(tests, 2);} + + function test_test1() {tests++;} + function test_test2() {tests++;} + } + TestCase { + name:"data-driven-init-data" + property int tests:0; + property int init_data_called_times:0; + function initTestCase() {tests = 0; init_data_called_times = 0;} + function cleanupTestCase() {compare(tests, 2); compare(init_data_called_times, 1);} + function init_data() {init_data_called_times++; return [{tag:"data1", data:"test data 1"}];} + + function test_test1(row) {tests++; compare(row.data, "test data 1");} + function test_test2_data() {return [{tag:"data2", data:"test data 2"}]; } + function test_test2(row) {tests++; compare(row.data, "test data 2");} + } +} diff -Nru qt5-declarative-0.1~git20120402/tests/auto/quick/qquickaccessible/data/statictext.qml qt5-declarative-0.1~git20120423/tests/auto/quick/qquickaccessible/data/statictext.qml --- qt5-declarative-0.1~git20120402/tests/auto/quick/qquickaccessible/data/statictext.qml 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/quick/qquickaccessible/data/statictext.qml 2012-04-23 11:32:40.000000000 +0000 @@ -10,6 +10,10 @@ width: 200 height: 50 text : "Hello Accessibility" + + // Setting any value of the attached property + // makes an item accessible. + Accessible.name: text } Text { diff -Nru qt5-declarative-0.1~git20120402/tests/auto/quick/qquickaccessible/tst_qquickaccessible.cpp qt5-declarative-0.1~git20120423/tests/auto/quick/qquickaccessible/tst_qquickaccessible.cpp --- qt5-declarative-0.1~git20120402/tests/auto/quick/qquickaccessible/tst_qquickaccessible.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/quick/qquickaccessible/tst_qquickaccessible.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -340,23 +340,25 @@ canvas->setSource(testFileUrl("hittest.qml")); canvas->show(); - QAI iface = QAI(QAccessible::queryAccessibleInterface(canvas)); - QVERIFY(iface.data()); - QAI rootItem = QAI(iface->child(0)); + QAI canvasIface = QAI(QAccessible::queryAccessibleInterface(canvas)); + QVERIFY(canvasIface.data()); + QAI rootItem = QAI(canvasIface->child(0)); QRect rootRect = rootItem->rect(); - // hit the root item - QAI itemHit(iface->childAt(rootRect.x() + 200, rootRect.y() + 50)); + // check the root item from app + QAI appIface = QAI(QAccessible::queryAccessibleInterface(qApp)); + QVERIFY(appIface); + QAI itemHit(appIface->childAt(rootRect.x() + 200, rootRect.y() + 50)); QVERIFY(itemHit); QCOMPARE(rootRect, itemHit->rect()); // hit rect1 - QAI rect1(rootItem->child(1)); + QAI rect1(rootItem->child(0)); QRect rect1Rect = rect1->rect(); - itemHit = QAI(rootItem->childAt(rect1Rect.x() + 10, rect1Rect.y() + 10)); - QVERIFY(itemHit); - QCOMPARE(rect1Rect, itemHit->rect()); - QCOMPARE(itemHit->text(QAccessible::Name), QLatin1String("rect1")); + QAI rootItemIface = QAI(rootItem->childAt(rect1Rect.x() + 10, rect1Rect.y() + 10)); + QVERIFY(rootItemIface); + QCOMPARE(rect1Rect, rootItemIface->rect()); + QCOMPARE(rootItemIface->text(QAccessible::Name), QLatin1String("rect1")); // should also work from top level (app) QAI app(QAccessible::queryAccessibleInterface(qApp)); @@ -366,16 +368,20 @@ QCOMPARE(itemHit2->text(QAccessible::Name), QLatin1String("rect1")); // hit rect201 - QAI rect2(rootItem->child(2)); - QAI rect20(rect2->child(1)); - QAI rect201(rect20->child(2)); + QAI rect2(rootItem->child(1)); + QVERIFY(rect2); + // FIXME: This is seems broken on mac + // QCOMPARE(rect2->rect().translated(rootItem->rect().x(), rootItem->rect().y()), QRect(0, 50, 100, 100)); + QAI rect20(rect2->child(0)); + QVERIFY(rect20); + QAI rect201(rect20->child(1)); QVERIFY(rect201); QRect rect201Rect = rect201->rect(); - itemHit = QAI(iface->childAt(rect201Rect.x() + 20, rect201Rect.y() + 20)); - QVERIFY(itemHit); - QCOMPARE(itemHit->rect(), rect201Rect); - QCOMPARE(itemHit->text(QAccessible::Name), QLatin1String("rect201")); + rootItemIface = QAI(canvasIface->childAt(rect201Rect.x() + 20, rect201Rect.y() + 20)); + QVERIFY(rootItemIface); + QCOMPARE(rootItemIface->rect(), rect201Rect); + QCOMPARE(rootItemIface->text(QAccessible::Name), QLatin1String("rect201")); delete canvas; } diff -Nru qt5-declarative-0.1~git20120402/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp qt5-declarative-0.1~git20120423/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp --- qt5-declarative-0.1~git20120402/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -624,6 +624,32 @@ QTest::qWait(400); animation.stop(); QVERIFY(rect.x() > x); + + animation.start(); + QVERIFY(animation.isRunning()); + animation.pause(); + QVERIFY(animation.isPaused()); + animation.resume(); + QVERIFY(!animation.isPaused()); + + QSignalSpy spy(&animation, SIGNAL(pausedChanged(bool))); + animation.pause(); + QCOMPARE(spy.count(), 1); + QVERIFY(animation.isPaused()); + animation.stop(); + QVERIFY(!animation.isPaused()); + QCOMPARE(spy.count(), 2); + + qmlRegisterType("QtQuick",2,0,"PropertyAnimation"); //make sure QQuickPropertyAnimation has correct qml type name + QByteArray message = ": QML PropertyAnimation: setPaused() cannot be used when animation isn't running."; + QTest::ignoreMessage(QtWarningMsg, message); + animation.pause(); + QCOMPARE(spy.count(), 2); + QVERIFY(!animation.isPaused()); + animation.resume(); + QVERIFY(!animation.isPaused()); + QVERIFY(!animation.isRunning()); + QCOMPARE(spy.count(), 2); } void tst_qquickanimations::dotProperty() @@ -961,11 +987,12 @@ QCOMPARE(myRect->x(),qreal(200)); trans->setEnabled(true); - + QSignalSpy runningSpy(trans, SIGNAL(runningChanged())); QQuickItemPrivate::get(rect)->setState(""); QCOMPARE(myRect->x(),qreal(200)); QTest::qWait(300); QTIMED_COMPARE(myRect->x(),qreal(100)); + QCOMPARE(runningSpy.count(), 2); //stopped, running, stopped } void tst_qquickanimations::invalidDuration() diff -Nru qt5-declarative-0.1~git20120402/tests/auto/quick/qquickcanvas/tst_qquickcanvas.cpp qt5-declarative-0.1~git20120423/tests/auto/quick/qquickcanvas/tst_qquickcanvas.cpp --- qt5-declarative-0.1~git20120402/tests/auto/quick/qquickcanvas/tst_qquickcanvas.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/quick/qquickcanvas/tst_qquickcanvas.cpp 2012-04-23 11:44:59.000000000 +0000 @@ -620,7 +620,7 @@ c->setPos(100 + i * 30, 100 + i * 20); c->show(); windows << c; - QVERIFY(c->visible()); + QVERIFY(c->isVisible()); } // move them @@ -647,15 +647,15 @@ QQuickCanvas* canvas = qobject_cast(created); QVERIFY(canvas); - QVERIFY(canvas->visible()); + QVERIFY(canvas->isVisible()); // Now hide the window and verify that it went off screen canvas->hide(); QTest::qWait(10); - QVERIFY(!canvas->visible()); + QVERIFY(!canvas->isVisible()); // Running animaiton should cause it to become visible again shortly. - QTRY_VERIFY(canvas->visible()); + QTRY_VERIFY(canvas->isVisible()); delete canvas; } @@ -672,7 +672,7 @@ QVERIFY(canvas); QTest::qWaitForWindowShown(canvas); - QVERIFY(canvas->visible()); + QVERIFY(canvas->isVisible()); QSignalSpy initialized(canvas, SIGNAL(sceneGraphInitialized())); QSignalSpy invalidated(canvas, SIGNAL(sceneGraphInvalidated())); diff -Nru qt5-declarative-0.1~git20120402/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp qt5-declarative-0.1~git20120423/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp --- qt5-declarative-0.1~git20120402/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -443,11 +443,14 @@ // Vertical with a quick press-move-release: should cause a flick in release. QSignalSpy vFlickSpy(flickable, SIGNAL(flickingVerticallyChanged())); - - QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(50, 90)); - QTest::qWait(10); - QTest::mouseMove(canvas, QPoint(50, 40)); - QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(50, 40)); + // Use something that generates a huge velocity just to make it testable. + // In practice this feature matters on touchscreen devices where the + // underlying drivers will hopefully provide a pre-calculated velocity + // (based on more data than what the UI gets), thus making this use case + // working even with small movements. + QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(50, 10)); + QTest::mouseMove(canvas, QPoint(50, 300), 10); + QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(50, 100), 10); QCOMPARE(vFlickSpy.count(), 1); diff -Nru qt5-declarative-0.1~git20120402/tests/auto/quick/qquickgridview/data/gridview1.qml qt5-declarative-0.1~git20120423/tests/auto/quick/qquickgridview/data/gridview1.qml --- qt5-declarative-0.1~git20120402/tests/auto/quick/qquickgridview/data/gridview1.qml 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/quick/qquickgridview/data/gridview1.qml 2012-04-23 11:32:40.000000000 +0000 @@ -26,8 +26,9 @@ text: index } Text { - x: 40 + x: 30 text: wrapper.x + ", " + wrapper.y + font.pixelSize: 12 } Text { y: 20 @@ -58,12 +59,11 @@ height: 320 cellWidth: 80 cellHeight: 60 - flow: (testTopToBottom == false) ? GridView.LeftToRight : GridView.TopToBottom - layoutDirection: (testRightToLeft == true) ? Qt.RightToLeft : Qt.LeftToRight model: testModel delegate: myDelegate header: root.showHeader ? headerFooter : null footer: root.showFooter ? headerFooter : null cacheBuffer: root.cacheBuffer + focus: true } } diff -Nru qt5-declarative-0.1~git20120402/tests/auto/quick/qquickgridview/data/headerfooter.qml qt5-declarative-0.1~git20120423/tests/auto/quick/qquickgridview/data/headerfooter.qml --- qt5-declarative-0.1~git20120402/tests/auto/quick/qquickgridview/data/headerfooter.qml 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/quick/qquickgridview/data/headerfooter.qml 2012-04-23 11:32:40.000000000 +0000 @@ -2,24 +2,22 @@ GridView { id: view - property bool horizontal: false - property bool rtl: false + width: 240 height: 320 model: testModel - - flow: horizontal ? GridView.TopToBottom : GridView.LeftToRight + header: Rectangle { objectName: "header" - width: horizontal ? 20 : view.width - height: horizontal ? view.height : 20 + width: flow == GridView.TopToBottom ? 20 : view.width + height: flow == GridView.TopToBottom ? view.height : 20 color: "red" } footer: Rectangle { objectName: "footer" - width: horizontal ? 30 : view.width - height: horizontal ? view.height : 30 + width: flow == GridView.TopToBottom ? 30 : view.width + height: flow == GridView.TopToBottom ? view.height : 30 color: "blue" } @@ -27,5 +25,4 @@ cellHeight: 80; delegate: Text { width: 80; height: 80; text: index + "(" + x + ")" } - layoutDirection: rtl ? Qt.RightToLeft : Qt.LeftToRight } diff -Nru qt5-declarative-0.1~git20120402/tests/auto/quick/qquickgridview/data/layouts.qml qt5-declarative-0.1~git20120423/tests/auto/quick/qquickgridview/data/layouts.qml --- qt5-declarative-0.1~git20120402/tests/auto/quick/qquickgridview/data/layouts.qml 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/quick/qquickgridview/data/layouts.qml 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,62 @@ +import QtQuick 2.0 + +Rectangle { + id: root + width: 240 + height: 320 + + property bool showHeader: false + property bool showFooter: false + + Component { + id: myDelegate + Rectangle { + id: wrapper + objectName: "wrapper" + width: 80 + height: 60 + border.width: 1 + Text { text: index } + Text { + x: 30 + text: wrapper.x + ", " + wrapper.y + font.pixelSize: 12 + } + Text { + y: 20 + id: textName + objectName: "textName" + text: name + } + Text { + y: 40 + id: textNumber + objectName: "textNumber" + text: number + } + + property string theName: name + color: GridView.isCurrentItem ? "lightsteelblue" : "white" + } + } + + Component { + id: headerFooter + Rectangle { width: 30; height: 320; color: "blue" } + } + + GridView { + objectName: "grid" + width: 240 + height: 320 + cellWidth: 80 + cellHeight: 60 + flow: (testTopToBottom == false) ? GridView.LeftToRight : GridView.TopToBottom + layoutDirection: (testRightToLeft == true) ? Qt.RightToLeft : Qt.LeftToRight + verticalLayoutDirection: (testBottomToTop == true) ? GridView.BottomToTop : GridView.TopToBottom + model: testModel + delegate: myDelegate + header: root.showHeader ? headerFooter : null + footer: root.showFooter ? headerFooter : null + } +} diff -Nru qt5-declarative-0.1~git20120402/tests/auto/quick/qquickgridview/data/resizegrid.qml qt5-declarative-0.1~git20120423/tests/auto/quick/qquickgridview/data/resizegrid.qml --- qt5-declarative-0.1~git20120402/tests/auto/quick/qquickgridview/data/resizegrid.qml 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/quick/qquickgridview/data/resizegrid.qml 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,51 @@ +import QtQuick 2.0 + +Rectangle { + id: root + + Component { + id: myDelegate + Rectangle { + id: wrapper + objectName: "wrapper" + width: 80 + height: 60 + border.width: 1 + Text { text: index } + Text { + x: 30 + text: wrapper.x + ", " + wrapper.y + font.pixelSize: 12 + } + Text { + y: 20 + id: textName + objectName: "textName" + text: name + } + color: GridView.isCurrentItem ? "lightsteelblue" : "white" + } + } + + // the grid is specifically placed inside another item to test a bug where + // resizing from anchor changes did not update the content pos correctly + Item { + anchors.fill: parent + + GridView { + clip: true + objectName: "grid" + anchors.fill: parent + cellWidth: 80 + cellHeight: 60 + + flow: (testTopToBottom == false) ? GridView.LeftToRight : GridView.TopToBottom + layoutDirection: (testRightToLeft == true) ? Qt.RightToLeft : Qt.LeftToRight + verticalLayoutDirection: (testBottomToTop == true) ? GridView.BottomToTop : GridView.TopToBottom + model: testModel + delegate: myDelegate + } + + } +} + diff -Nru qt5-declarative-0.1~git20120402/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp qt5-declarative-0.1~git20120423/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp --- qt5-declarative-0.1~git20120402/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp 2012-04-23 11:44:59.000000000 +0000 @@ -58,8 +58,10 @@ #include "../shared/visualtestutil.h" #include -Q_DECLARE_METATYPE(Qt::LayoutDirection) Q_DECLARE_METATYPE(QQuickGridView::Flow) +Q_DECLARE_METATYPE(Qt::LayoutDirection) +Q_DECLARE_METATYPE(QQuickItemView::VerticalLayoutDirection) +Q_DECLARE_METATYPE(Qt::Key) using namespace QQuickViewTestUtil; using namespace QQuickVisualTestUtil; @@ -76,25 +78,29 @@ void init(); void items(); void changed(); - void inserted(); - void inserted_more(); - void inserted_more_data(); + void inserted_basic(); + void inserted_defaultLayout(QQuickGridView::Flow flow = QQuickGridView::FlowLeftToRight, Qt::LayoutDirection horizLayout = Qt::LeftToRight, QQuickItemView::VerticalLayoutDirection verticalLayout = QQuickItemView::TopToBottom); + void inserted_defaultLayout_data(); void insertBeforeVisible(); void insertBeforeVisible_data(); - void removed(); - void removed_more(); - void removed_more_data(); + void removed_basic(); + void removed_defaultLayout(QQuickGridView::Flow flow = QQuickGridView::FlowLeftToRight, Qt::LayoutDirection horizLayout = Qt::LeftToRight, QQuickItemView::VerticalLayoutDirection verticalLayout = QQuickItemView::TopToBottom); + void removed_defaultLayout_data(); void addOrRemoveBeforeVisible(); void addOrRemoveBeforeVisible_data(); void clear(); - void moved(); - void moved_data(); - void multipleChanges(); - void multipleChanges_data(); + void moved_defaultLayout(QQuickGridView::Flow flow = QQuickGridView::FlowLeftToRight, Qt::LayoutDirection horizLayout = Qt::LeftToRight, QQuickItemView::VerticalLayoutDirection verticalLayout = QQuickItemView::TopToBottom); + void moved_defaultLayout_data(); + void multipleChanges_condensed() { multipleChanges(true); } + void multipleChanges_condensed_data() { multipleChanges_data(); } + void multipleChanges_uncondensed() { multipleChanges(false); } + void multipleChanges_uncondensed_data() { multipleChanges_data(); } void swapWithFirstItem(); void changeFlow(); void currentIndex(); void noCurrentIndex(); + void keyNavigation(); + void keyNavigation_data(); void defaultValues(); void properties(); void propertyChanges(); @@ -114,7 +120,11 @@ void header(); void header_data(); void headerFooter(); + void headerFooter_data(); + void resetModel_headerFooter(); void resizeViewAndRepaint(); + void resizeGrid(); + void resizeGrid_data(); void changeColumnCount(); void indexAt_itemAt_data(); void indexAt_itemAt(); @@ -148,12 +158,117 @@ void multipleTransitions_data(); void multipleDisplaced(); + void inserted_leftToRight_RtL_TtB(); + void inserted_leftToRight_RtL_TtB_data(); + void inserted_leftToRight_LtR_BtT(); + void inserted_leftToRight_LtR_BtT_data(); + void inserted_leftToRight_RtL_BtT(); + void inserted_leftToRight_RtL_BtT_data(); + void inserted_topToBottom_LtR_TtB(); + void inserted_topToBottom_LtR_TtB_data(); + void inserted_topToBottom_RtL_TtB(); + void inserted_topToBottom_RtL_TtB_data(); + void inserted_topToBottom_LtR_BtT(); + void inserted_topToBottom_LtR_BtT_data(); + void inserted_topToBottom_RtL_BtT(); + void inserted_topToBottom_RtL_BtT_data(); + + void removed_leftToRight_RtL_TtB(); + void removed_leftToRight_RtL_TtB_data(); + void removed_leftToRight_LtR_BtT(); + void removed_leftToRight_LtR_BtT_data(); + void removed_leftToRight_RtL_BtT(); + void removed_leftToRight_RtL_BtT_data(); + void removed_topToBottom_LtR_TtB(); + void removed_topToBottom_LtR_TtB_data(); + void removed_topToBottom_RtL_TtB(); + void removed_topToBottom_RtL_TtB_data(); + void removed_topToBottom_LtR_BtT(); + void removed_topToBottom_LtR_BtT_data(); + void removed_topToBottom_RtL_BtT(); + void removed_topToBottom_RtL_BtT_data(); + + void moved_leftToRight_RtL_TtB(); + void moved_leftToRight_RtL_TtB_data(); + void moved_leftToRight_LtR_BtT(); + void moved_leftToRight_LtR_BtT_data(); + void moved_leftToRight_RtL_BtT(); + void moved_leftToRight_RtL_BtT_data(); + void moved_topToBottom_LtR_TtB(); + void moved_topToBottom_LtR_TtB_data(); + void moved_topToBottom_RtL_TtB(); + void moved_topToBottom_RtL_TtB_data(); + void moved_topToBottom_LtR_BtT(); + void moved_topToBottom_LtR_BtT_data(); + void moved_topToBottom_RtL_BtT(); + void moved_topToBottom_RtL_BtT_data(); + private: QList toIntList(const QVariantList &list); void matchIndexLists(const QVariantList &indexLists, const QList &expectedIndexes); void matchItemsAndIndexes(const QVariantMap &items, const QaimModel &model, const QList &expectedIndexes); void matchItemLists(const QVariantList &itemLists, const QList &expectedItems); + void multipleChanges(bool condensed); + void multipleChanges_data(); + + QPointF expectedItemPos(QQuickGridView *grid, int index, qreal rowOffset = 0) { + qreal x; + qreal y; + if (grid->flow() == QQuickGridView::FlowLeftToRight) { + int columns = grid->width() / grid->cellWidth(); + x = (index % columns) * grid->cellWidth(); + y = (index / columns) * grid->cellHeight(); + if (grid->effectiveLayoutDirection() == Qt::RightToLeft) { + int col = (index % columns) * grid->cellWidth(); + x = grid->cellWidth() * (columns - 1) - col; + } + + qreal offset = grid->cellHeight() * rowOffset; + if (grid->verticalLayoutDirection() == QQuickItemView::TopToBottom) + y += offset; + else + y = -grid->cellHeight() - y - offset; + } else { + int rows = grid->height() / grid->cellHeight(); + x = (index / rows) * grid->cellWidth(); + y = (index % rows) * grid->cellHeight(); + if (grid->effectiveLayoutDirection() == Qt::RightToLeft) + x = -x - grid->cellWidth(); + + qreal offset = grid->cellWidth() * rowOffset; + if (grid->effectiveLayoutDirection() == Qt::RightToLeft) + x -= offset; + else + x += offset; + if (grid->verticalLayoutDirection() == QQuickItemView::BottomToTop) + y = -grid->cellHeight() - y; + } + return QPointF(x, y); + } + + // Sets contentY (or contentX in TopToBottom flow) according to given row offset + // (in LeftToRight flow) or col offset (in TopToBottom). + bool setContentPos(QQuickGridView *gridview, qreal rowOrColOffset) { + bool contentPosChanged = (rowOrColOffset != 0); + qreal contentOffset = gridview->flow() == QQuickGridView::FlowLeftToRight + ? rowOrColOffset * gridview->cellHeight() + : rowOrColOffset * gridview->cellWidth(); + + if (gridview->flow() == QQuickGridView::FlowLeftToRight) { + if (gridview->verticalLayoutDirection() == QQuickItemView::BottomToTop) + contentOffset = -gridview->height() - contentOffset; + } else { + if (gridview->effectiveLayoutDirection() == Qt::RightToLeft) + contentOffset = -gridview->width() - contentOffset; + } + if (gridview->flow() == QQuickGridView::FlowLeftToRight) + gridview->setContentY(contentOffset); + else + gridview->setContentX(contentOffset); + return contentPosChanged; + } + #ifdef SHARE_VIEWS QQuickView *getView() { if (m_view) { @@ -217,8 +332,6 @@ QQmlContext *ctxt = canvas->rootContext(); ctxt->setContextProperty("testModel", &model); - ctxt->setContextProperty("testRightToLeft", QVariant(false)); - ctxt->setContextProperty("testTopToBottom", QVariant(false)); canvas->setSource(testFileUrl("gridview1.qml")); qApp->processEvents(); @@ -267,8 +380,6 @@ QQmlContext *ctxt = canvas->rootContext(); ctxt->setContextProperty("testModel", &model); - ctxt->setContextProperty("testRightToLeft", QVariant(false)); - ctxt->setContextProperty("testTopToBottom", QVariant(false)); canvas->setSource(testFileUrl("gridview1.qml")); qApp->processEvents(); @@ -290,7 +401,7 @@ delete canvas; } -void tst_QQuickGridView::inserted() +void tst_QQuickGridView::inserted_basic() { QQuickView *canvas = createView(); canvas->show(); @@ -300,11 +411,7 @@ model.addItem("John", "2345"); model.addItem("Bob", "54321"); - QQmlContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - ctxt->setContextProperty("testRightToLeft", QVariant(false)); - ctxt->setContextProperty("testTopToBottom", QVariant(false)); - + canvas->rootContext()->setContextProperty("testModel", &model); canvas->setSource(testFileUrl("gridview1.qml")); qApp->processEvents(); @@ -370,12 +477,16 @@ delete canvas; } -void tst_QQuickGridView::inserted_more() +void tst_QQuickGridView::inserted_defaultLayout(QQuickGridView::Flow flow, + Qt::LayoutDirection horizLayout, + QQuickItemView::VerticalLayoutDirection verticalLayout) { - QFETCH(qreal, contentY); + QFETCH(qreal, contentYRowOffset); QFETCH(int, insertIndex); QFETCH(int, insertCount); - QFETCH(qreal, itemsOffsetAfterMove); + QFETCH(int, insertIndex_ttb); + QFETCH(int, insertCount_ttb); + QFETCH(qreal, rowOffsetAfterMove); QaimModel model; for (int i = 0; i < 30; i++) @@ -384,10 +495,10 @@ QQuickView *canvas = getView(); QQmlContext *ctxt = canvas->rootContext(); ctxt->setContextProperty("testModel", &model); - ctxt->setContextProperty("testRightToLeft", QVariant(false)); - ctxt->setContextProperty("testTopToBottom", QVariant(false)); - - canvas->setSource(testFileUrl("gridview1.qml")); + ctxt->setContextProperty("testTopToBottom", flow == QQuickGridView::FlowTopToBottom); + ctxt->setContextProperty("testRightToLeft", horizLayout == Qt::RightToLeft); + ctxt->setContextProperty("testBottomToTop", verticalLayout == QQuickGridView::BottomToTop); + canvas->setSource(testFileUrl("layouts.qml")); canvas->show(); qApp->processEvents(); @@ -396,8 +507,12 @@ QQuickItem *contentItem = gridview->contentItem(); QTRY_VERIFY(contentItem != 0); - gridview->setContentY(contentY); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + if (flow == QQuickGridView::FlowTopToBottom) { + insertIndex = insertIndex_ttb; + insertCount = insertCount_ttb; + } + if (setContentPos(gridview, contentYRowOffset)) + QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); QList > newData; for (int i=0; i(contentItem, "wrapper", 0); QVERIFY(item0); - QCOMPARE(item0->y(), 0.0); + QPointF firstPos(0, 0); + if (horizLayout == Qt::RightToLeft) + firstPos.rx() = flow == QQuickGridView::FlowLeftToRight ? gridview->width() - gridview->cellWidth() : -gridview->cellWidth(); + if (verticalLayout == QQuickItemView::BottomToTop) + firstPos.ry() -= gridview->cellHeight(); + QCOMPARE(item0->pos(), firstPos); QList items = findItems(contentItem, "wrapper"); int firstVisibleIndex = -1; for (int i=0; iy() >= contentY) { - QQmlExpression e(qmlContext(items[i]), items[i], "index"); - firstVisibleIndex = e.evaluate().toInt(); + QQuickItem *item = findItem(contentItem, "wrapper", i); + if (item && item->isVisible()) { + firstVisibleIndex = i; break; } } QVERIFY2(firstVisibleIndex >= 0, QTest::toString(firstVisibleIndex)); // Confirm items positioned correctly and indexes correct - int itemCount = findItems(contentItem, "wrapper").count(); - QQuickText *name; - QQuickText *number; - for (int i = firstVisibleIndex; i < model.count() && i < itemCount; ++i) { + for (int i = firstVisibleIndex; i < model.count() && i < items.count(); ++i) { QQuickItem *item = findItem(contentItem, "wrapper", i); QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i))); - - QCOMPARE(item->x(), (i%3)*80.0); - QCOMPARE(item->y(), (i/3)*60.0 + itemsOffsetAfterMove); - - name = findItem(contentItem, "textName", i); + QCOMPARE(item->pos(), expectedItemPos(gridview, i, rowOffsetAfterMove)); + QQuickText *name = findItem(contentItem, "textName", i); QVERIFY(name != 0); QCOMPARE(name->text(), model.name(i)); - number = findItem(contentItem, "textNumber", i); - QVERIFY(number != 0); - QCOMPARE(number->text(), model.number(i)); } releaseView(canvas); } -void tst_QQuickGridView::inserted_more_data() +void tst_QQuickGridView::inserted_defaultLayout_data() { - QTest::addColumn("contentY"); + QTest::addColumn("contentYRowOffset"); QTest::addColumn("insertIndex"); QTest::addColumn("insertCount"); - QTest::addColumn("itemsOffsetAfterMove"); + QTest::addColumn("insertIndex_ttb"); + QTest::addColumn("insertCount_ttb"); + QTest::addColumn("rowOffsetAfterMove"); QTest::newRow("add 1, before visible items") - << 120.0 // show 6-23 + << 2.0 // show 6-23 << 5 << 1 + << 9 << 1 << 0.0; // insert 1 above first visible, grid is rearranged; first visible moves forward within its row // new 1st visible item is at 0 QTest::newRow("add 2, before visible items") - << 120.0 // show 6-23 + << 2.0 // show 6-23 << 5 << 2 + << 9 << 2 << 0.0; // insert 2 above first visible, grid is rearranged; first visible moves forward within its row QTest::newRow("add 3, before visible items") - << 120.0 // show 6-23 + << 2.0 // show 6-23 << 5 << 3 - << -60.0; // insert 3 (1 row) above first visible in negative pos, first visible does not move + << 9 << 5 + << -1.0; // insert 3 (1 row) above first visible in negative pos, first visible does not move QTest::newRow("add 5, before visible items") - << 120.0 // show 6-23 + << 2.0 // show 6-23 << 5 << 5 - << -60.0; // insert 1 row + 2 items above first visible, 1 row added at negative pos, + << 9 << 7 + << -1.0; // insert 1 row + 2 items above first visible, 1 row added at negative pos, // grid is rearranged and first visible moves forward within its row QTest::newRow("add 6, before visible items") - << 120.0 // show 6-23 + << 2.0 // show 6-23 << 5 << 6 - << -60.0 * 2; // insert 2 rows above first visible in negative pos, first visible does not move + << 9 << 10 + << -1.0 * 2; // insert 2 rows above first visible in negative pos, first visible does not move QTest::newRow("add 1, at start of visible, content at start") << 0.0 << 0 << 1 + << 0 << 1 << 0.0; QTest::newRow("add multiple, at start of visible, content at start") << 0.0 << 0 << 3 + << 0 << 5 << 0.0; QTest::newRow("add 1, at start of visible, content not at start") - << 120.0 // show 6-23 + << 2.0 // show 6-23 << 6 << 1 + << 10 << 1 << 0.0; QTest::newRow("add multiple, at start of visible, content not at start") - << 120.0 // show 6-23 + << 2.0 // show 6-23 << 6 << 3 + << 10 << 5 << 0.0; QTest::newRow("add 1, at end of visible, content at start") << 0.0 << 17 << 1 + << 14 << 1 << 0.0; - QTest::newRow("add 1, at end of visible, content at start") + QTest::newRow("add row, at end of visible, content at start") << 0.0 << 17 << 3 + << 14 << 5 << 0.0; QTest::newRow("add 1, at end of visible, content not at start") - << 120.0 // show 6-23 - << 23 << 1 + << 2.0 // show 6-23 + << 17+6 << 1 + << 14+10 << 1 << 0.0; QTest::newRow("add multiple, at end of visible, content not at start") - << 120.0 // show 6-23 - << 23 << 3 + << 2.0 // show 6-23 + << 17+6 << 3 + << 14+10 << 5 << 0.0; QTest::newRow("add 1, after visible, content at start") << 0.0 << 20 << 1 + << 18 << 1 << 0.0; - QTest::newRow("add 1, after visible, content at start") + QTest::newRow("add row, after visible, content at start") << 0.0 << 20 << 3 + << 18 << 5 << 0.0; QTest::newRow("add 1, after visible, content not at start") - << 120.0 // show 6-23 - << 24 << 1 + << 2.0 // show 6-23 + << 20+6 << 1 + << 18+10 << 1 << 0.0; QTest::newRow("add multiple, after visible, content not at start") - << 120.0 // show 6-23 - << 24 << 3 + << 2.0 // show 6-23 + << 20+6 << 3 + << 18+10 << 3 << 0.0; } @@ -557,8 +687,6 @@ QQmlContext *ctxt = canvas->rootContext(); ctxt->setContextProperty("testModel", &model); - ctxt->setContextProperty("testRightToLeft", QVariant(false)); - ctxt->setContextProperty("testTopToBottom", QVariant(false)); canvas->setSource(testFileUrl("gridview1.qml")); canvas->show(); qApp->processEvents(); @@ -633,7 +761,7 @@ QTest::newRow("insert multiple at 1, 500 buffer") << 1 << 6 << 500; } -void tst_QQuickGridView::removed() +void tst_QQuickGridView::removed_basic() { QQuickView *canvas = createView(); canvas->show(); @@ -642,11 +770,7 @@ for (int i = 0; i < 40; i++) model.addItem("Item" + QString::number(i), ""); - QQmlContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - ctxt->setContextProperty("testRightToLeft", QVariant(false)); - ctxt->setContextProperty("testTopToBottom", QVariant(false)); - + canvas->rootContext()->setContextProperty("testModel", &model); canvas->setSource(testFileUrl("gridview1.qml")); qApp->processEvents(); @@ -778,16 +902,19 @@ delete canvas; } -void tst_QQuickGridView::removed_more() +void tst_QQuickGridView::removed_defaultLayout(QQuickGridView::Flow flow, + Qt::LayoutDirection horizLayout, + QQuickItemView::VerticalLayoutDirection verticalLayout) { - QFETCH(qreal, contentY); + QFETCH(qreal, contentYRowOffset); QFETCH(int, removeIndex); QFETCH(int, removeCount); - QFETCH(qreal, itemsOffsetAfterMove); + QFETCH(int, removeIndex_ttb); + QFETCH(int, removeCount_ttb); + QFETCH(qreal, rowOffsetAfterMove); QFETCH(QString, firstVisible); + QFETCH(QString, firstVisible_ttb); - QQuickText *name; - QQuickText *number; QQuickView *canvas = getView(); QaimModel model; @@ -796,9 +923,10 @@ QQmlContext *ctxt = canvas->rootContext(); ctxt->setContextProperty("testModel", &model); - ctxt->setContextProperty("testRightToLeft", QVariant(false)); - ctxt->setContextProperty("testTopToBottom", QVariant(false)); - canvas->setSource(testFileUrl("gridview1.qml")); + ctxt->setContextProperty("testTopToBottom", flow == QQuickGridView::FlowTopToBottom); + ctxt->setContextProperty("testRightToLeft", horizLayout == Qt::RightToLeft); + ctxt->setContextProperty("testBottomToTop", verticalLayout == QQuickGridView::BottomToTop); + canvas->setSource(testFileUrl("layouts.qml")); canvas->show(); qApp->processEvents(); @@ -807,8 +935,13 @@ QQuickItem *contentItem = gridview->contentItem(); QTRY_VERIFY(contentItem != 0); - gridview->setContentY(contentY); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + if (flow == QQuickGridView::FlowTopToBottom) { + removeIndex = removeIndex_ttb; + removeCount = removeCount_ttb; + firstVisible = firstVisible_ttb; + } + if (setContentPos(gridview, contentYRowOffset)) + QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); model.removeItems(removeIndex, removeCount); QTRY_COMPARE(gridview->property("count").toInt(), model.count()); @@ -816,161 +949,183 @@ QString firstName; int firstVisibleIndex = -1; QList items = findItems(contentItem, "wrapper"); + QRectF viewRect(gridview->contentX(), gridview->contentY(), gridview->width(), gridview->height()); for (int i=0; iy() >= contentY) { - QQmlExpression e(qmlContext(items[i]), items[i], "index"); - firstVisibleIndex = e.evaluate().toInt(); - QQmlExpression en(qmlContext(items[i]), items[i], "name"); - firstName = en.evaluate().toString(); - break; + QQuickItem *item = findItem(contentItem, "wrapper", i); + if (item) { + QRectF itemRect(item->x(), item->y(), item->width(), item->height()); + if (item->isVisible() && viewRect.intersects(itemRect)) { + firstVisibleIndex = i; + QQmlExpression en(qmlContext(item), item, "name"); + firstName = en.evaluate().toString(); + break; + } } } QVERIFY2(firstVisibleIndex >= 0, QTest::toString(firstVisibleIndex)); QCOMPARE(firstName, firstVisible); // Confirm items positioned correctly and indexes correct - int itemCount = findItems(contentItem, "wrapper").count(); - for (int i = firstVisibleIndex; i < model.count() && i < itemCount; ++i) { + for (int i = firstVisibleIndex; i < model.count() && i < items.count(); ++i) { QQuickItem *item = findItem(contentItem, "wrapper", i); QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i))); - - QTRY_COMPARE(item->x(), (i%3)*80.0); - QTRY_COMPARE(item->y(), (i/3)*60.0 + itemsOffsetAfterMove); - - name = findItem(contentItem, "textName", i); + QCOMPARE(item->pos(), expectedItemPos(gridview, i, rowOffsetAfterMove)); + QQuickText *name = findItem(contentItem, "textName", i); QVERIFY(name != 0); QTRY_COMPARE(name->text(), model.name(i)); - number = findItem(contentItem, "textNumber", i); - QVERIFY(number != 0); - QTRY_COMPARE(number->text(), model.number(i)); } releaseView(canvas); } -void tst_QQuickGridView::removed_more_data() +void tst_QQuickGridView::removed_defaultLayout_data() { - QTest::addColumn("contentY"); + QTest::addColumn("contentYRowOffset"); QTest::addColumn("removeIndex"); QTest::addColumn("removeCount"); - QTest::addColumn("itemsOffsetAfterMove"); + QTest::addColumn("removeIndex_ttb"); + QTest::addColumn("removeCount_ttb"); + QTest::addColumn("rowOffsetAfterMove"); QTest::addColumn("firstVisible"); + QTest::addColumn("firstVisible_ttb"); QTest::newRow("remove 1, before visible items") - << 120.0 // show 6-23 + << 2.0 // show 6-23 << 2 << 1 - << 0.0 << "Item7"; + << 4 << 1 + << 0.0 << "Item7" << "Item11"; QTest::newRow("remove 1, before visible position") - << 120.0 // show 6-23 + << 2.0 // show 6-23 << 3 << 1 - << 0.0 << "Item7"; + << 5 << 1 + << 0.0 << "Item7" << "Item11"; - QTest::newRow("remove multiple, all before visible items") - << 120.0 + QTest::newRow("remove multiple (1 row), all before visible items") + << 2.0 << 1 << 3 - << 60.0 << "Item6"; // removed top row, slide down by 1 row + << 1 << 5 + << 1.0 << "Item6" << "Item10"; // removed top row, slide down by 1 row QTest::newRow("remove multiple, all before visible items, remove item 0") - << 120.0 + << 2.0 << 0 << 4 - << 60.0 << "Item7"; // removed top row, slide down by 1 row + << 0 << 6 + << 1.0 << "Item7" << "Item11"; // removed top row, slide down by 1 row QTest::newRow("remove multiple rows, all before visible items") - << 240.0 // show 12-29 + << 4.0 // show 12-29 << 1 << 7 - << 120.0 << "Item13"; + << 1 << 12 + << 2.0 << "Item13" << "Item17"; QTest::newRow("remove one row before visible, content y not on item border") - << 100.0 + << 1.5 << 0 << 3 - << 60.0 << "Item6"; // 1 row removed + << 0 << 5 + << 1.0 << "Item3" << "Item5"; // 1 row removed QTest::newRow("remove mix of visible/non-visible") - << 120.0 // show 6-23 + << 2.0 // show 6-23 << 2 << 3 - << 60.0 << "Item6"; // 1 row removed + << 4 << 3 + << 1.0 << "Item6" << "Item8"; // 1 row removed // remove 3,4,5 before the visible pos, first row moves down to just before the visible pos, // items 6,7 are removed from view, item 8 slides up to original pos of item 6 (120px) QTest::newRow("remove multiple, mix of items from before and within visible items") - << 120.0 + << 2.0 << 3 << 5 - << 60.0 << "Item8"; // adjust for the 1 row removed before the visible + << 5 << 7 + << 1.0 << "Item8" << "Item12"; // adjust for the 1 row removed before the visible QTest::newRow("remove multiple, mix of items from before and within visible items, remove item 0") - << 120.0 + << 2.0 << 0 << 8 - << 60.0 * 2 << "Item8"; // adjust for the 2 rows removed before the visible + << 0 << 12 + << 1.0 * 2 << "Item8" << "Item12"; // adjust for the 2 rows removed before the visible QTest::newRow("remove 1, from start of visible, content at start") << 0.0 << 0 << 1 - << 0.0 << "Item1"; + << 0 << 1 + << 0.0 << "Item1" << "Item1"; QTest::newRow("remove multiple, from start of visible, content at start") << 0.0 << 0 << 3 - << 0.0 << "Item3"; + << 0 << 5 + << 0.0 << "Item3" << "Item5"; QTest::newRow("remove 1, from start of visible, content not at start") - << 120.0 // show 6-23 + << 2.0 // show 6-23 << 4 << 1 - << 0.0 << "Item7"; + << 7 << 1 + << 0.0 << "Item7" << "Item11"; QTest::newRow("remove multiple, from start of visible, content not at start") - << 120.0 // show 6-23 + << 2.0 // show 6-23 << 4 << 3 - << 0.0 << "Item9"; + << 7 << 5 + << 0.0 << "Item9" << "Item15"; QTest::newRow("remove 1, from middle of visible, content at start") << 0.0 << 10 << 1 - << 0.0 << "Item0"; + << 12 << 1 + << 0.0 << "Item0" << "Item0"; QTest::newRow("remove multiple, from middle of visible, content at start") << 0.0 << 10 << 5 - << 0.0 << "Item0"; + << 12 << 5 + << 0.0 << "Item0" << "Item0"; QTest::newRow("remove 1, from middle of visible, content not at start") - << 120.0 // show 6-23 + << 2.0 // show 6-23 << 10 << 1 - << 0.0 << "Item6"; + << 12 << 1 + << 0.0 << "Item6" << "Item10"; QTest::newRow("remove multiple, from middle of visible, content not at start") - << 120.0 // show 6-23 + << 2.0 // show 6-23 << 10 << 5 - << 0.0 << "Item6"; + << 12 << 7 + << 0.0 << "Item6" << "Item10"; QTest::newRow("remove 1, after visible, content at start") << 0.0 << 16 << 1 - << 0.0 << "Item0"; + << 15 << 1 + << 0.0 << "Item0" << "Item0"; QTest::newRow("remove multiple, after visible, content at start") << 0.0 << 16 << 5 - << 0.0 << "Item0"; + << 15 << 7 + << 0.0 << "Item0" << "Item0"; QTest::newRow("remove 1, after visible, content not at start") - << 120.0 // show 6-23 + << 2.0 // show 6-23 << 16+4 << 1 - << 0.0 << "Item6"; + << 15+10 << 1 + << 0.0 << "Item6" << "Item10"; QTest::newRow("remove multiple, after visible, content not at start") - << 120.0 // show 6-23 + << 2.0 // show 6-23 << 16+4 << 5 - << 0.0 << "Item6"; + << 15+10 << 7 + << 0.0 << "Item6" << "Item10"; QTest::newRow("remove multiple, mix of items from within and after visible items") - << 120.0 // show 6-23 + << 2.0 // show 6-23 << 20 << 5 - << 0.0 << "Item6"; + << 22 << 7 + << 0.0 << "Item6" << "Item10"; } void tst_QQuickGridView::addOrRemoveBeforeVisible() @@ -988,10 +1143,7 @@ for (int i = 0; i < 30; i++) model.addItem("Item" + QString::number(i), ""); - QQmlContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - ctxt->setContextProperty("testRightToLeft", QVariant(false)); - ctxt->setContextProperty("testTopToBottom", QVariant(false)); + canvas->rootContext()->setContextProperty("testModel", &model); canvas->setSource(testFileUrl("gridview1.qml")); QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); @@ -1067,11 +1219,7 @@ for (int i = 0; i < 30; i++) model.addItem("Item" + QString::number(i), ""); - QQmlContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - ctxt->setContextProperty("testRightToLeft", QVariant(false)); - ctxt->setContextProperty("testTopToBottom", QVariant(false)); - + canvas->rootContext()->setContextProperty("testModel", &model); canvas->setSource(testFileUrl("gridview1.qml")); canvas->show(); qApp->processEvents(); @@ -1098,28 +1246,31 @@ delete canvas; } -void tst_QQuickGridView::moved() +void tst_QQuickGridView::moved_defaultLayout(QQuickGridView::Flow flow, + Qt::LayoutDirection horizLayout, + QQuickItemView::VerticalLayoutDirection verticalLayout) { - QFETCH(qreal, contentY); + QFETCH(qreal, contentYRowOffset); QFETCH(int, from); QFETCH(int, to); QFETCH(int, count); - QFETCH(qreal, itemsOffsetAfterMove); + QFETCH(int, from_ttb); + QFETCH(int, to_ttb); + QFETCH(int, count_ttb); + QFETCH(qreal, rowOffsetAfterMove); - QQuickText *name; - QQuickText *number; QQuickView *canvas = getView(); QaimModel model; for (int i = 0; i < 30; i++) model.addItem("Item" + QString::number(i), ""); - QQmlContext *ctxt = canvas->rootContext(); + QDeclarativeContext *ctxt = canvas->rootContext(); ctxt->setContextProperty("testModel", &model); - ctxt->setContextProperty("testRightToLeft", QVariant(false)); - ctxt->setContextProperty("testTopToBottom", QVariant(false)); - - canvas->setSource(testFileUrl("gridview1.qml")); + ctxt->setContextProperty("testTopToBottom", flow == QQuickGridView::FlowTopToBottom); + ctxt->setContextProperty("testRightToLeft", horizLayout == Qt::RightToLeft); + ctxt->setContextProperty("testBottomToTop", verticalLayout == QQuickGridView::BottomToTop); + canvas->setSource(testFileUrl("layouts.qml")); canvas->show(); qApp->processEvents(); @@ -1132,32 +1283,41 @@ QQuickItem *currentItem = gridview->currentItem(); QTRY_VERIFY(currentItem != 0); - if (contentY != 0) { - gridview->setContentY(contentY); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + if (flow == QQuickGridView::FlowTopToBottom) { + from = from_ttb; + to = to_ttb; + count = count_ttb; } + if (setContentPos(gridview, contentYRowOffset)) + QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); model.moveItems(from, to, count); QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); // Confirm items positioned correctly and indexes correct - int firstVisibleIndex = qCeil(contentY / 60.0) * 3; - int itemCount = findItems(contentItem, "wrapper").count(); - for (int i = firstVisibleIndex; i < model.count() && i < itemCount; ++i) { - if (i >= firstVisibleIndex + 18) // index has moved out of view - continue; + QList items = findItems(contentItem, "wrapper"); + int firstVisibleIndex = -1; + for (int i=0; i(contentItem, "wrapper", i); - QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i))); - - QTRY_COMPARE(item->x(), (i%3)*80.0); - QTRY_COMPARE(item->y(), (i/3)*60.0 + itemsOffsetAfterMove); + if (item && item->isVisible()) { + firstVisibleIndex = i; + break; + } + } + QVERIFY2(firstVisibleIndex >= 0, QTest::toString(firstVisibleIndex)); - name = findItem(contentItem, "textName", i); + for (int i = firstVisibleIndex; i < model.count() && i < items.count(); ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + if (!item && + ( (flow == QQuickGridView::FlowLeftToRight && i >= firstVisibleIndex + (3*6)) + || flow == QQuickGridView::FlowTopToBottom && i >= firstVisibleIndex + (5*3) ) ) { + continue; // index has moved out of view + } + QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i))); + QCOMPARE(item->pos(), expectedItemPos(gridview, i, rowOffsetAfterMove)); + QQuickText *name = findItem(contentItem, "textName", i); QVERIFY(name != 0); QTRY_COMPARE(name->text(), model.name(i)); - number = findItem(contentItem, "textNumber", i); - QVERIFY(number != 0); - QTRY_COMPARE(number->text(), model.number(i)); // current index should have been updated if (item == currentItem) @@ -1167,13 +1327,16 @@ releaseView(canvas); } -void tst_QQuickGridView::moved_data() +void tst_QQuickGridView::moved_defaultLayout_data() { - QTest::addColumn("contentY"); + QTest::addColumn("contentYRowOffset"); QTest::addColumn("from"); QTest::addColumn("to"); QTest::addColumn("count"); - QTest::addColumn("itemsOffsetAfterMove"); + QTest::addColumn("from_ttb"); + QTest::addColumn("to_ttb"); + QTest::addColumn("count_ttb"); + QTest::addColumn("rowOffsetAfterMove"); // model starts with 30 items, each 80x60, in area 240x320 // 18 items should be visible at a time @@ -1185,143 +1348,170 @@ QTest::newRow("move 1 forwards, within visible items") << 0.0 << 1 << 8 << 1 + << 2 << 12 << 1 << 0.0; QTest::newRow("move 1 forwards, from non-visible -> visible") - << 120.0 // show 6-23 - << 1 << 23 << 1 + << 2.0 // show 6-23 + << 1 << 8+6 << 1 + << 2 << 12+10 << 1 << 0.0; QTest::newRow("move 1 forwards, from non-visible -> visible (move first item)") - << 120.0 // // show 6-23 + << 2.0 // // show 6-23 << 0 << 6 << 1 + << 0 << 10 << 1 << 0.0; QTest::newRow("move 1 forwards, from visible -> non-visible") << 0.0 << 1 << 20 << 1 + << 1 << 20 << 1 << 0.0; QTest::newRow("move 1 forwards, from visible -> non-visible (move first item)") << 0.0 << 0 << 20 << 1 + << 0 << 20 << 1 << 0.0; QTest::newRow("move 1 backwards, within visible items") << 0.0 << 10 << 5 << 1 + << 10 << 5 << 1 << 0.0; QTest::newRow("move 1 backwards, within visible items (to first index)") << 0.0 << 10 << 0 << 1 + << 10 << 0 << 1 << 0.0; QTest::newRow("move 1 backwards, from non-visible -> visible") << 0.0 << 28 << 8 << 1 + << 28 << 8 << 1 << 0.0; QTest::newRow("move 1 backwards, from non-visible -> visible (move last item)") << 0.0 << 29 << 14 << 1 + << 29 << 14 << 1 << 0.0; QTest::newRow("move 1 backwards, from visible -> non-visible") - << 120.0 // show 6-23 + << 2.0 // show 6-23 << 7 << 1 << 1 + << 10 << 1 << 1 << 0.0; // only 1 item moved back, so items shift accordingly and first row doesn't move QTest::newRow("move 1 backwards, from visible -> non-visible (move first item)") - << 120.0 // show 6-23 + << 2.0 // show 6-23 << 7 << 0 << 1 + << 10 << 0 << 1 << 0.0; // only 1 item moved back, so items shift accordingly and first row doesn't move QTest::newRow("move multiple forwards, within visible items") << 0.0 << 0 << 5 << 3 + << 0 << 7 << 5 << 0.0; QTest::newRow("move multiple backwards, within visible items (move first item)") << 0.0 << 10 << 0 << 3 + << 12 << 0 << 5 << 0.0; QTest::newRow("move multiple forwards, before visible items") - << 120.0 // show 6-23 + << 2.0 // show 6-23 << 3 << 4 << 3 // 3, 4, 5 move to after 6 - << 60.0; // row of 3,4,5 has moved down + << 5 << 6 << 5 + << 1.0; // row of 3,4,5 has moved down QTest::newRow("move multiple forwards, from non-visible -> visible") - << 120.0 // show 6-23 + << 2.0 // show 6-23 << 1 << 6 << 3 - << 60.0; // 1st row (it's above visible area) disappears, 0 drops down 1 row, first visible item (6) stays where it is + << 1 << 10 << 5 + << 1.0; // 1st row (it's above visible area) disappears, 0 drops down 1 row, first visible item (6) stays where it is QTest::newRow("move multiple forwards, from non-visible -> visible (move first item)") - << 120.0 // show 6-23 + << 2.0 // show 6-23 << 0 << 6 << 3 - << 60.0; // top row moved and shifted to below 3rd row, all items should shift down by 1 row + << 0 << 10 << 5 + << 1.0; // top row moved and shifted to below 3rd row, all items should shift down by 1 row QTest::newRow("move multiple forwards, mix of non-visible/visible") - << 120.0 + << 2.0 << 3 << 16 << 6 - << 60.0; // top two rows removed, third row is now the first visible + << 5 << 18 << 10 + << 1.0; // top two rows removed, third row is now the first visible QTest::newRow("move multiple forwards, to bottom of view") << 0.0 << 5 << 13 << 5 + << 1 << 8 << 6 << 0.0; QTest::newRow("move multiple forwards, to bottom of view, first row -> last") << 0.0 << 0 << 15 << 3 + << 0 << 10 << 5 << 0.0; QTest::newRow("move multiple forwards, to bottom of view, content y not 0") - << 120.0 + << 2.0 << 5+4 << 13+4 << 5 + << 11 << 19 << 6 << 0.0; QTest::newRow("move multiple forwards, from visible -> non-visible") << 0.0 << 1 << 16 << 3 + << 1 << 18 << 5 << 0.0; QTest::newRow("move multiple forwards, from visible -> non-visible (move first item)") << 0.0 << 0 << 16 << 3 + << 1 << 18 << 5 << 0.0; QTest::newRow("move multiple backwards, within visible items") << 0.0 << 4 << 1 << 3 + << 7 << 1 << 5 << 0.0; QTest::newRow("move multiple backwards, from non-visible -> visible") << 0.0 << 20 << 4 << 3 + << 20 << 4 << 5 << 0.0; QTest::newRow("move multiple backwards, from non-visible -> visible (move last item)") << 0.0 << 27 << 10 << 3 + << 25 << 8 << 5 << 0.0; QTest::newRow("move multiple backwards, from visible -> non-visible") - << 120.0 // show 6-23 + << 2.0 // show 6-23 << 16 << 1 << 3 - << -60.0; // to minimize movement, items are added above visible area, all items move up by 1 row + << 17 << 1 << 5 + << -1.0; // to minimize movement, items are added above visible area, all items move up by 1 row QTest::newRow("move multiple backwards, from visible -> non-visible (move first item)") - << 120.0 // show 6-23 + << 2.0 // show 6-23 << 16 << 0 << 3 - << -60.0; // 16,17,18 move to above item 0, all items move up by 1 row + << 17 << 0 << 5 + << -1.0; // 16,17,18 move to above item 0, all items move up by 1 row } -void tst_QQuickGridView::multipleChanges() +void tst_QQuickGridView::multipleChanges(bool condensed) { QFETCH(int, startCount); QFETCH(QList, changes); @@ -1334,11 +1524,7 @@ for (int i = 0; i < startCount; i++) model.addItem("Item" + QString::number(i), ""); - QQmlContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - ctxt->setContextProperty("testRightToLeft", QVariant(false)); - ctxt->setContextProperty("testTopToBottom", QVariant(false)); - + canvas->rootContext()->setContextProperty("testModel", &model); canvas->setSource(testFileUrl("gridview1.qml")); canvas->show(); qApp->processEvents(); @@ -1359,26 +1545,26 @@ } case ListChange::Removed: model.removeItems(changes[i].index, changes[i].count); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); break; case ListChange::Moved: model.moveItems(changes[i].index, changes[i].to, changes[i].count); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); break; case ListChange::SetCurrent: gridview->setCurrentIndex(changes[i].index); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); break; case ListChange::SetContentY: gridview->setContentY(changes[i].pos); - QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); break; } + if (condensed) { + QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + } } + QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); - QTRY_COMPARE(gridview->count(), newCount); + QCOMPARE(gridview->count(), newCount); QCOMPARE(gridview->count(), model.count()); - QTRY_COMPARE(gridview->currentIndex(), newCurrentIndex); + QCOMPARE(gridview->currentIndex(), newCurrentIndex); QQuickText *name; QQuickText *number; @@ -1547,6 +1733,28 @@ << ListChange::remove(0, 5) << ListChange::insert(0, 5) ) << 5 << -1; + + QTest::newRow("remove, scroll") << 30 << (QList() + << ListChange::remove(20, 5) + << ListChange::setContentY(20) + ) << 25 << 0; + + QTest::newRow("insert, scroll") << 10 << (QList() + << ListChange::insert(9, 5) + << ListChange::setContentY(20) + ) << 15 << 0; + + QTest::newRow("move, scroll") << 20 << (QList() + << ListChange::move(15, 8, 3) + << ListChange::setContentY(0) + ) << 20 << 0; + + QTest::newRow("clear, insert, scroll") << 30 << (QList() + << ListChange::setContentY(20) + << ListChange::remove(0, 30) + << ListChange::insert(0, 2) + << ListChange::setContentY(0) + ) << 2 << 0; } @@ -1559,11 +1767,7 @@ for (int i = 0; i < 30; i++) model.addItem("Item" + QString::number(i), ""); - QQmlContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - ctxt->setContextProperty("testRightToLeft", QVariant(false)); - ctxt->setContextProperty("testTopToBottom", QVariant(false)); - + canvas->rootContext()->setContextProperty("testModel", &model); canvas->setSource(testFileUrl("gridview1.qml")); canvas->show(); qApp->processEvents(); @@ -1610,57 +1814,11 @@ QCOMPARE(gridview->currentItem()->y(), gridview->highlightItem()->y()); QCOMPARE(gridview->contentY(), 400.0); - gridview->moveCurrentIndexRight(); - QCOMPARE(gridview->currentIndex(), 36); - gridview->moveCurrentIndexDown(); - QCOMPARE(gridview->currentIndex(), 39); - gridview->moveCurrentIndexUp(); - QCOMPARE(gridview->currentIndex(), 36); - gridview->moveCurrentIndexLeft(); - QCOMPARE(gridview->currentIndex(), 35); - - // wait until motion stops - QTRY_VERIFY(gridview->verticalVelocity() == 0.0); - - // no wrap gridview->setCurrentIndex(0); QCOMPARE(gridview->currentIndex(), 0); // confirm that the velocity is updated QTRY_VERIFY(gridview->verticalVelocity() != 0.0); - gridview->moveCurrentIndexUp(); - QCOMPARE(gridview->currentIndex(), 0); - - gridview->moveCurrentIndexLeft(); - QCOMPARE(gridview->currentIndex(), 0); - - gridview->setCurrentIndex(model.count()-1); - QCOMPARE(gridview->currentIndex(), model.count()-1); - - gridview->moveCurrentIndexRight(); - QCOMPARE(gridview->currentIndex(), model.count()-1); - - gridview->moveCurrentIndexDown(); - QCOMPARE(gridview->currentIndex(), model.count()-1); - - // with wrap - gridview->setWrapEnabled(true); - - gridview->setCurrentIndex(0); - QCOMPARE(gridview->currentIndex(), 0); - - gridview->moveCurrentIndexLeft(); - QCOMPARE(gridview->currentIndex(), model.count()-1); - - qApp->processEvents(); - QTRY_COMPARE(gridview->contentY(), 880.0); - - gridview->moveCurrentIndexRight(); - QCOMPARE(gridview->currentIndex(), 0); - - QTRY_COMPARE(gridview->contentY(), 0.0); - - // footer should become visible if it is out of view, and then current index moves to the first row canvas->rootObject()->setProperty("showFooter", true); QTRY_VERIFY(gridview->footerItem()); @@ -1679,78 +1837,6 @@ QTRY_COMPARE(gridview->contentY(), -gridview->headerItem()->height()); canvas->rootObject()->setProperty("showHeader", false); - - // Test keys - canvas->requestActivateWindow(); - QTest::qWaitForWindowShown(canvas); - QTRY_VERIFY(qGuiApp->focusWindow() == canvas); - - gridview->setCurrentIndex(0); - - QTest::keyClick(canvas, Qt::Key_Down); - QCOMPARE(gridview->currentIndex(), 3); - - QTest::keyClick(canvas, Qt::Key_Up); - QCOMPARE(gridview->currentIndex(), 0); - - // hold down Key_Down - for (int i=0; i<(model.count() / 3) - 1; i++) { - QTest::simulateEvent(canvas, true, Qt::Key_Down, Qt::NoModifier, "", true); - QTRY_COMPARE(gridview->currentIndex(), i*3 + 3); - } - QTest::keyRelease(canvas, Qt::Key_Down); - QTRY_COMPARE(gridview->currentIndex(), 57); - QTRY_COMPARE(gridview->contentY(), 880.0); - - // hold down Key_Up - for (int i=(model.count() / 3) - 1; i > 0; i--) { - QTest::simulateEvent(canvas, true, Qt::Key_Up, Qt::NoModifier, "", true); - QTRY_COMPARE(gridview->currentIndex(), i*3 - 3); - } - QTest::keyRelease(canvas, Qt::Key_Up); - QTRY_COMPARE(gridview->currentIndex(), 0); - QTRY_COMPARE(gridview->contentY(), 0.0); - - - gridview->setFlow(QQuickGridView::TopToBottom); - - canvas->requestActivateWindow(); - QTest::qWaitForWindowShown(canvas); - QVERIFY(qGuiApp->focusWindow() == canvas); - qApp->processEvents(); - - QTest::keyClick(canvas, Qt::Key_Right); - QCOMPARE(gridview->currentIndex(), 5); - - QTest::keyClick(canvas, Qt::Key_Left); - QCOMPARE(gridview->currentIndex(), 0); - - QTest::keyClick(canvas, Qt::Key_Down); - QCOMPARE(gridview->currentIndex(), 1); - - QTest::keyClick(canvas, Qt::Key_Up); - QCOMPARE(gridview->currentIndex(), 0); - - // hold down Key_Right - for (int i=0; i<(model.count() / 5) - 1; i++) { - QTest::simulateEvent(canvas, true, Qt::Key_Right, Qt::NoModifier, "", true); - QTRY_COMPARE(gridview->currentIndex(), i*5 + 5); - } - - QTest::keyRelease(canvas, Qt::Key_Right); - QTRY_COMPARE(gridview->currentIndex(), 55); - QTRY_COMPARE(gridview->contentX(), 720.0); - - // hold down Key_Left - for (int i=(model.count() / 5) - 1; i > 0; i--) { - QTest::simulateEvent(canvas, true, Qt::Key_Left, Qt::NoModifier, "", true); - QTRY_COMPARE(gridview->currentIndex(), i*5 - 5); - } - QTest::keyRelease(canvas, Qt::Key_Left); - QTRY_COMPARE(gridview->currentIndex(), 0); - QTRY_COMPARE(gridview->contentX(), 0.0); - - // turn off auto highlight gridview->setHighlightFollowsCurrentItem(false); QVERIFY(gridview->highlightFollowsCurrentItem() == false); @@ -1774,54 +1860,6 @@ QVERIFY(!gridview->highlightItem()); QVERIFY(!gridview->currentItem()); - gridview->setHighlightFollowsCurrentItem(true); - - gridview->setFlow(QQuickGridView::LeftToRight); - gridview->setLayoutDirection(Qt::RightToLeft); - - canvas->requestActivateWindow(); - QTest::qWaitForWindowShown(canvas); - QTRY_VERIFY(qGuiApp->focusWindow() == canvas); - qApp->processEvents(); - - gridview->setCurrentIndex(35); - - QTest::keyClick(canvas, Qt::Key_Right); - QCOMPARE(gridview->currentIndex(), 34); - - QTest::keyClick(canvas, Qt::Key_Down); - QCOMPARE(gridview->currentIndex(), 37); - - QTest::keyClick(canvas, Qt::Key_Up); - QCOMPARE(gridview->currentIndex(), 34); - - QTest::keyClick(canvas, Qt::Key_Left); - QCOMPARE(gridview->currentIndex(), 35); - - - // turn off auto highlight - gridview->setHighlightFollowsCurrentItem(false); - QVERIFY(gridview->highlightFollowsCurrentItem() == false); - QVERIFY(gridview->highlightItem()); - hlPosX = gridview->highlightItem()->x(); - hlPosY = gridview->highlightItem()->y(); - - gridview->setCurrentIndex(5); - QTRY_COMPARE(gridview->highlightItem()->x(), hlPosX); - QTRY_COMPARE(gridview->highlightItem()->y(), hlPosY); - - // insert item before currentIndex - gridview->setCurrentIndex(28); - model.insertItem(0, "Foo", "1111"); - QTRY_COMPARE(canvas->rootObject()->property("current").toInt(), 29); - - // check removing highlight by setting currentIndex to -1; - gridview->setCurrentIndex(-1); - - QCOMPARE(gridview->currentIndex(), -1); - QVERIFY(!gridview->highlightItem()); - QVERIFY(!gridview->currentItem()); - // moving currentItem out of view should make it invisible gridview->setCurrentIndex(0); QTRY_VERIFY(gridview->currentItem()->isVisible()); @@ -1868,6 +1906,199 @@ delete canvas; } +void tst_QQuickGridView::keyNavigation() +{ + QFETCH(QQuickGridView::Flow, flow); + QFETCH(Qt::LayoutDirection, layoutDirection); + QFETCH(QQuickItemView::VerticalLayoutDirection, verticalLayoutDirection); + QFETCH(Qt::Key, forwardsKey); + QFETCH(Qt::Key, backwardsKey); + QFETCH(QPointF, contentPosAtFirstItem); + QFETCH(QPointF, contentPosAtLastItem); + QFETCH(int, indexRightOf7); + QFETCH(int, indexLeftOf7); + QFETCH(int, indexUpFrom7); + QFETCH(int, indexDownFrom7); + + QmlListModel model; + for (int i = 0; i < 18; i++) + model.addItem("Item" + QString::number(i), ""); + + QQuickView *canvas = getView(); + canvas->rootContext()->setContextProperty("testModel", &model); + canvas->setSource(testFileUrl("gridview1.qml")); + canvas->show(); + qApp->processEvents(); + + QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); + QTRY_VERIFY(gridview != 0); + gridview->setFlow(flow); + gridview->setLayoutDirection(layoutDirection); + gridview->setVerticalLayoutDirection(verticalLayoutDirection); + QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + + canvas->requestActivateWindow(); + QTRY_VERIFY(qGuiApp->focusWindow() == canvas); + QCOMPARE(gridview->currentIndex(), 0); + + QTest::keyClick(canvas, forwardsKey); + QCOMPARE(gridview->currentIndex(), 1); + + QTest::keyClick(canvas, backwardsKey); + QCOMPARE(gridview->currentIndex(), 0); + + gridview->setCurrentIndex(7); + gridview->moveCurrentIndexRight(); + QCOMPARE(gridview->currentIndex(), indexRightOf7); + gridview->moveCurrentIndexLeft(); + QCOMPARE(gridview->currentIndex(), 7); + gridview->moveCurrentIndexLeft(); + QCOMPARE(gridview->currentIndex(), indexLeftOf7); + gridview->moveCurrentIndexRight(); + QCOMPARE(gridview->currentIndex(), 7); + gridview->moveCurrentIndexUp(); + QCOMPARE(gridview->currentIndex(), indexUpFrom7); + gridview->moveCurrentIndexDown(); + QCOMPARE(gridview->currentIndex(), 7); + gridview->moveCurrentIndexDown(); + QCOMPARE(gridview->currentIndex(), indexDownFrom7); + + gridview->setCurrentIndex(7); + QTest::keyClick(canvas, Qt::Key_Right); + QCOMPARE(gridview->currentIndex(), indexRightOf7); + QTest::keyClick(canvas, Qt::Key_Left); + QCOMPARE(gridview->currentIndex(), 7); + QTest::keyClick(canvas, Qt::Key_Left); + QCOMPARE(gridview->currentIndex(), indexLeftOf7); + QTest::keyClick(canvas, Qt::Key_Right); + QCOMPARE(gridview->currentIndex(), 7); + QTest::keyClick(canvas, Qt::Key_Up); + QCOMPARE(gridview->currentIndex(), indexUpFrom7); + QTest::keyClick(canvas, Qt::Key_Down); + QCOMPARE(gridview->currentIndex(), 7); + QTest::keyClick(canvas, Qt::Key_Down); + QCOMPARE(gridview->currentIndex(), indexDownFrom7); + + // hold down a key to go forwards + gridview->setCurrentIndex(0); + for (int i=0; icurrentIndex(), i+1); + } + QTest::keyRelease(canvas, forwardsKey); + QTRY_COMPARE(gridview->currentIndex(), model.count()-1); + QTRY_COMPARE(gridview->contentX(), contentPosAtLastItem.x()); + QTRY_COMPARE(gridview->contentY(), contentPosAtLastItem.y()); + + // hold down a key to go backwards + for (int i=model.count()-1; i > 0; i--) { + QTest::simulateEvent(canvas, true, backwardsKey, Qt::NoModifier, "", true); + QTRY_COMPARE(gridview->currentIndex(), i-1); + } + QTest::keyRelease(canvas, backwardsKey); + QTRY_COMPARE(gridview->currentIndex(), 0); + QTRY_COMPARE(gridview->contentX(), contentPosAtFirstItem.x()); + QTRY_COMPARE(gridview->contentY(), contentPosAtFirstItem.y()); + + // no wrap + QVERIFY(!gridview->isWrapEnabled()); + QTest::keyClick(canvas, forwardsKey); + QCOMPARE(gridview->currentIndex(), 1); + QTest::keyClick(canvas, backwardsKey); + QCOMPARE(gridview->currentIndex(), 0); + + QTest::keyClick(canvas, backwardsKey); + QCOMPARE(gridview->currentIndex(), 0); + + // with wrap + gridview->setWrapEnabled(true); + QVERIFY(gridview->isWrapEnabled()); + + QTest::keyClick(canvas, backwardsKey); + QCOMPARE(gridview->currentIndex(), model.count()-1); + QTRY_COMPARE(gridview->contentX(), contentPosAtLastItem.x()); + QTRY_COMPARE(gridview->contentY(), contentPosAtLastItem.y()); + + QTest::keyClick(canvas, forwardsKey); + QCOMPARE(gridview->currentIndex(), 0); + QTRY_COMPARE(gridview->contentX(), contentPosAtFirstItem.x()); + QTRY_COMPARE(gridview->contentY(), contentPosAtFirstItem.y()); + + releaseView(canvas); +} + +void tst_QQuickGridView::keyNavigation_data() +{ + QTest::addColumn("flow"); + QTest::addColumn("layoutDirection"); + QTest::addColumn("verticalLayoutDirection"); + QTest::addColumn("forwardsKey"); + QTest::addColumn("backwardsKey"); + QTest::addColumn("contentPosAtFirstItem"); + QTest::addColumn("contentPosAtLastItem"); + QTest::addColumn("indexRightOf7"); + QTest::addColumn("indexLeftOf7"); + QTest::addColumn("indexUpFrom7"); + QTest::addColumn("indexDownFrom7"); + + QTest::newRow("LeftToRight, LtR, TtB") + << QQuickGridView::FlowLeftToRight << Qt::LeftToRight << QQuickItemView::TopToBottom + << Qt::Key_Right << Qt::Key_Left + << QPointF(0, 0) + << QPointF(0, 40) + << 8 << 6 << 4 << 10; + + QTest::newRow("LeftToRight, RtL, TtB") + << QQuickGridView::FlowLeftToRight << Qt::RightToLeft << QQuickItemView::TopToBottom + << Qt::Key_Left << Qt::Key_Right + << QPointF(0, 0) + << QPointF(0, 40) + << 6 << 8 << 4 << 10; + + QTest::newRow("LeftToRight, LtR, BtT") + << QQuickGridView::FlowLeftToRight << Qt::LeftToRight << QQuickItemView::BottomToTop + << Qt::Key_Right << Qt::Key_Left + << QPointF(0, -320) + << QPointF(0, -360) + << 8 << 6 << 10 << 4; + + QTest::newRow("LeftToRight, RtL, BtT") + << QQuickGridView::FlowLeftToRight << Qt::RightToLeft << QQuickItemView::BottomToTop + << Qt::Key_Left << Qt::Key_Right + << QPointF(0, -320) + << QPointF(0, -360) + << 6 << 8 << 10 << 4; + + QTest::newRow("TopToBottom, LtR, TtB") + << QQuickGridView::FlowTopToBottom << Qt::LeftToRight << QQuickItemView::TopToBottom + << Qt::Key_Down << Qt::Key_Up + << QPointF(0, 0) + << QPointF(80, 0) + << 12 << 2 << 6 << 8; + + QTest::newRow("TopToBottom, RtL, TtB") + << QQuickGridView::FlowTopToBottom << Qt::RightToLeft << QQuickItemView::TopToBottom + << Qt::Key_Down << Qt::Key_Up + << QPointF(-240, 0) + << QPointF(-320, 0) + << 2 << 12 << 6 << 8; + + QTest::newRow("TopToBottom, LtR, BtT") + << QQuickGridView::FlowTopToBottom << Qt::LeftToRight << QQuickItemView::BottomToTop + << Qt::Key_Up << Qt::Key_Down + << QPointF(0, -320) + << QPointF(80, -320) + << 12 << 2 << 8 << 6; + + QTest::newRow("TopToBottom, RtL, BtT") + << QQuickGridView::FlowTopToBottom << Qt::RightToLeft << QQuickItemView::BottomToTop + << Qt::Key_Up << Qt::Key_Down + << QPointF(-240, -320) + << QPointF(-320, -320) + << 2 << 12 << 8 << 6; +} + void tst_QQuickGridView::changeFlow() { QQuickView *canvas = createView(); @@ -1880,8 +2111,9 @@ ctxt->setContextProperty("testModel", &model); ctxt->setContextProperty("testRightToLeft", QVariant(false)); ctxt->setContextProperty("testTopToBottom", QVariant(false)); + ctxt->setContextProperty("testBottomToTop", QVariant(false)); - canvas->setSource(testFileUrl("gridview1.qml")); + canvas->setSource(testFileUrl("layouts.qml")); qApp->processEvents(); QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); @@ -2027,15 +2259,15 @@ QTRY_COMPARE(gridView->isWrapEnabled(), true); QTRY_COMPARE(gridView->cacheBuffer(), 10); - QTRY_COMPARE(gridView->flow(), QQuickGridView::LeftToRight); + QTRY_COMPARE(gridView->flow(), QQuickGridView::FlowLeftToRight); gridView->setWrapEnabled(false); gridView->setCacheBuffer(3); - gridView->setFlow(QQuickGridView::TopToBottom); + gridView->setFlow(QQuickGridView::FlowTopToBottom); QTRY_COMPARE(gridView->isWrapEnabled(), false); QTRY_COMPARE(gridView->cacheBuffer(), 3); - QTRY_COMPARE(gridView->flow(), QQuickGridView::TopToBottom); + QTRY_COMPARE(gridView->flow(), QQuickGridView::FlowTopToBottom); QTRY_COMPARE(keyNavigationWrapsSpy.count(),1); QTRY_COMPARE(cacheBufferSpy.count(),1); @@ -2043,14 +2275,14 @@ gridView->setWrapEnabled(false); gridView->setCacheBuffer(3); - gridView->setFlow(QQuickGridView::TopToBottom); + gridView->setFlow(QQuickGridView::FlowTopToBottom); QTRY_COMPARE(keyNavigationWrapsSpy.count(),1); QTRY_COMPARE(cacheBufferSpy.count(),1); QTRY_COMPARE(flowSpy.count(),1); - gridView->setFlow(QQuickGridView::LeftToRight); - QTRY_COMPARE(gridView->flow(), QQuickGridView::LeftToRight); + gridView->setFlow(QQuickGridView::FlowLeftToRight); + QTRY_COMPARE(gridView->flow(), QQuickGridView::FlowLeftToRight); gridView->setWrapEnabled(true); gridView->setCacheBuffer(5); @@ -2074,11 +2306,11 @@ QTRY_COMPARE(layoutSpy.count(),1); QTRY_COMPARE(flowSpy.count(),2); - gridView->setFlow(QQuickGridView::TopToBottom); - QTRY_COMPARE(gridView->flow(), QQuickGridView::TopToBottom); + gridView->setFlow(QQuickGridView::FlowTopToBottom); + QTRY_COMPARE(gridView->flow(), QQuickGridView::FlowTopToBottom); QTRY_COMPARE(flowSpy.count(),3); - gridView->setFlow(QQuickGridView::TopToBottom); + gridView->setFlow(QQuickGridView::FlowTopToBottom); QTRY_COMPARE(flowSpy.count(),3); delete canvas; @@ -2179,8 +2411,9 @@ ctxt->setContextProperty("testModel", &model); ctxt->setContextProperty("testRightToLeft", QVariant(false)); ctxt->setContextProperty("testTopToBottom", QVariant(false)); + ctxt->setContextProperty("testBottomToTop", QVariant(false)); - canvas->setSource(testFileUrl("gridview1.qml")); + canvas->setSource(testFileUrl("layouts.qml")); canvas->show(); qApp->processEvents(); @@ -2377,11 +2610,7 @@ for (int i = 0; i < 40; i++) model.addItem("Item" + QString::number(i), ""); - QQmlContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - ctxt->setContextProperty("testTopToBottom", QVariant(false)); - ctxt->setContextProperty("testRightToLeft", QVariant(false)); - + canvas->rootContext()->setContextProperty("testModel", &model); canvas->setSource(testFileUrl("gridview1.qml")); qApp->processEvents(); @@ -2483,8 +2712,9 @@ ctxt->setContextProperty("testModel", &model); ctxt->setContextProperty("testTopToBottom", QVariant(true)); ctxt->setContextProperty("testRightToLeft", QVariant(true)); + ctxt->setContextProperty("testBottomToTop", QVariant(false)); - canvas->setSource(testFileUrl("gridview1.qml")); + canvas->setSource(testFileUrl("layouts.qml")); qApp->processEvents(); QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); @@ -2812,8 +3042,8 @@ QTRY_COMPARE(gridview->highlightItem()->y() - 5, gridview->currentItem()->y()); QTRY_COMPARE(gridview->highlightItem()->x() - 5, gridview->currentItem()->x()); - gridview->setFlow(QQuickGridView::TopToBottom); - QTRY_COMPARE(gridview->flow(), QQuickGridView::TopToBottom); + gridview->setFlow(QQuickGridView::FlowTopToBottom); + QTRY_COMPARE(gridview->flow(), QQuickGridView::FlowTopToBottom); gridview->setCurrentIndex(0); QTRY_COMPARE(gridview->currentIndex(), 0); @@ -2829,10 +3059,10 @@ { QFETCH(QQuickGridView::Flow, flow); QFETCH(Qt::LayoutDirection, layoutDirection); + QFETCH(QQuickItemView::VerticalLayoutDirection, verticalLayoutDirection); QFETCH(QPointF, initialFooterPos); QFETCH(QPointF, changedFooterPos); QFETCH(QPointF, initialContentPos); - QFETCH(QPointF, changedContentPos); QFETCH(QPointF, firstDelegatePos); QFETCH(QPointF, resizeContentPos); @@ -2845,7 +3075,6 @@ QQmlContext *ctxt = canvas->rootContext(); ctxt->setContextProperty("testModel", &model); - canvas->setSource(testFileUrl("footer.qml")); qApp->processEvents(); @@ -2853,13 +3082,14 @@ QTRY_VERIFY(gridview != 0); gridview->setFlow(flow); gridview->setLayoutDirection(layoutDirection); + gridview->setVerticalLayoutDirection(verticalLayoutDirection); + QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); QQuickItem *contentItem = gridview->contentItem(); QTRY_VERIFY(contentItem != 0); QQuickText *footer = findItem(contentItem, "footer"); QVERIFY(footer); - QVERIFY(footer == gridview->footerItem()); QCOMPARE(footer->pos(), initialFooterPos); @@ -2867,7 +3097,7 @@ QCOMPARE(footer->height(), 30.); QCOMPARE(QPointF(gridview->contentX(), gridview->contentY()), initialContentPos); - if (flow == QQuickGridView::LeftToRight) + if (flow == QQuickGridView::FlowLeftToRight) QCOMPARE(gridview->contentHeight(), (model.count()+2) / 3 * 60. + footer->height()); else QCOMPARE(gridview->contentWidth(), (model.count()+3) / 5 * 80. + footer->width()); @@ -2876,10 +3106,13 @@ QVERIFY(item); QCOMPARE(item->pos(), firstDelegatePos); - if (flow == QQuickGridView::LeftToRight) { + if (flow == QQuickGridView::FlowLeftToRight) { // shrink by one row model.removeItem(2); - QTRY_COMPARE(footer->y(), initialFooterPos.y() - gridview->cellHeight()); + if (verticalLayoutDirection == QQuickItemView::TopToBottom) + QTRY_COMPARE(footer->y(), initialFooterPos.y() - gridview->cellHeight()); + else + QTRY_COMPARE(footer->y(), initialFooterPos.y() + gridview->cellHeight()); } else { // shrink by one column model.removeItem(2); @@ -2895,10 +3128,12 @@ QPointF posWhenNoItems(0, 0); if (layoutDirection == Qt::RightToLeft) - posWhenNoItems.setX(flow == QQuickGridView::LeftToRight ? gridview->width() - footer->width() : -footer->width()); + posWhenNoItems.setX(flow == QQuickGridView::FlowLeftToRight ? gridview->width() - footer->width() : -footer->width()); + if (verticalLayoutDirection == QQuickItemView::BottomToTop) + posWhenNoItems.setY(-footer->height()); QTRY_COMPARE(footer->pos(), posWhenNoItems); - // if header is present, it's at a negative pos, so the footer should not move + // if header is toggled, it shouldn't affect the footer position canvas->rootObject()->setProperty("showHeader", true); QVERIFY(findItem(contentItem, "header") != 0); QTRY_COMPARE(footer->pos(), posWhenNoItems); @@ -2917,13 +3152,14 @@ QVERIFY(!footer); footer = findItem(contentItem, "footer2"); QVERIFY(footer); - QVERIFY(footer == gridview->footerItem()); QCOMPARE(footer->pos(), changedFooterPos); QCOMPARE(footer->width(), 50.); QCOMPARE(footer->height(), 20.); - QTRY_COMPARE(QPointF(gridview->contentX(), gridview->contentY()), changedContentPos); + + // changing the footer shouldn't change the content pos + QTRY_COMPARE(QPointF(gridview->contentX(), gridview->contentY()), initialContentPos); item = findItem(contentItem, "wrapper", 0); QVERIFY(item); @@ -2941,10 +3177,10 @@ { QTest::addColumn("flow"); QTest::addColumn("layoutDirection"); + QTest::addColumn("verticalLayoutDirection"); QTest::addColumn("initialFooterPos"); QTest::addColumn("changedFooterPos"); QTest::addColumn("initialContentPos"); - QTest::addColumn("changedContentPos"); QTest::addColumn("firstDelegatePos"); QTest::addColumn("resizeContentPos"); @@ -2955,46 +3191,84 @@ // view height = 320 // footer below items, bottom left - QTest::newRow("flow left to right") << QQuickGridView::LeftToRight << Qt::LeftToRight + QTest::newRow("LeftToRight, LtR, TtB") + << QQuickGridView::FlowLeftToRight << Qt::LeftToRight << QQuickItemView::TopToBottom << QPointF(0, 3 * 60) // 180 = height of 3 rows (cell height is 60) << QPointF(0, 10 * 60) // 30 items = 10 rows << QPointF(0, 0) << QPointF(0, 0) - << QPointF(0, 0) - << QPointF(0, 10 * 60 - 320 + 10); + << QPointF(0, (10 * 60) - 320 + 10); // footer below items, bottom right - QTest::newRow("flow left to right, layout right to left") << QQuickGridView::LeftToRight << Qt::RightToLeft + QTest::newRow("LeftToRight, RtL, TtB") + << QQuickGridView::FlowLeftToRight << Qt::RightToLeft << QQuickItemView::TopToBottom << QPointF(240 - 100, 3 * 60) << QPointF((240 - 100) + 50, 10 * 60) // 50 = width diff between old and new footers << QPointF(0, 0) - << QPointF(0, 0) << QPointF(240 - 80, 0) - << QPointF(0, 10 * 60 - 320 + 10); + << QPointF(0, (10 * 60) - 320 + 10); - // footer to right of items - QTest::newRow("flow top to bottom, layout left to right") << QQuickGridView::TopToBottom << Qt::LeftToRight + // footer above items, top left + QTest::newRow("LeftToRight, LtR, BtT") + << QQuickGridView::FlowLeftToRight << Qt::LeftToRight << QQuickItemView::BottomToTop + << QPointF(0, -(3 * 60) - 30) + << QPointF(0, -(10 * 60) - 20) + << QPointF(0, -320) + << QPointF(0, -60) + << QPointF(0, -(10 * 60) - 10); + + // footer above items, top right + QTest::newRow("LeftToRight, RtL, BtT") + << QQuickGridView::FlowLeftToRight << Qt::RightToLeft << QQuickItemView::BottomToTop + << QPointF(240 - 100, -(3 * 60) - 30) + << QPointF((240 - 100) + 50, -(10 * 60) - 20) + << QPointF(0, -320) + << QPointF(240 - 80, -60) + << QPointF(0, -(10 * 60) - 10); + + + // footer to right of items, bottom right + QTest::newRow("TopToBottom, LtR, TtB") + << QQuickGridView::FlowTopToBottom << Qt::LeftToRight << QQuickItemView::TopToBottom << QPointF(2 * 80, 0) // 2 columns, cell width 80 << QPointF(6 * 80, 0) // 30 items = 6 columns << QPointF(0, 0) << QPointF(0, 0) - << QPointF(0, 0) - << QPointF(6 * 80 - 240 + 40, 0); + << QPointF((6 * 80) - 240 + 40, 0); - // footer to left of items - QTest::newRow("flow top to bottom, layout right to left") << QQuickGridView::TopToBottom << Qt::RightToLeft + // footer to left of items, bottom right + QTest::newRow("TopToBottom, RtL, TtB") + << QQuickGridView::FlowTopToBottom << Qt::RightToLeft << QQuickItemView::TopToBottom << QPointF(-(2 * 80) - 100, 0) << QPointF(-(6 * 80) - 50, 0) // 50 = new footer width << QPointF(-240, 0) - << QPointF(-240, 0) // unchanged, footer change doesn't change content pos << QPointF(-80, 0) << QPointF(-(6 * 80) - 40, 0); + + // footer to right of items, top right + QTest::newRow("TopToBottom, LtR, BtT") + << QQuickGridView::FlowTopToBottom << Qt::LeftToRight << QQuickItemView::BottomToTop + << QPointF(2 * 80, -30) + << QPointF(6 * 80, -20) + << QPointF(0, -320) + << QPointF(0, -60) + << QPointF((6 * 80) - 240 + 40, -320); + + // footer to left of items, top left + QTest::newRow("TopToBottom, RtL, BtT") + << QQuickGridView::FlowTopToBottom << Qt::RightToLeft << QQuickItemView::BottomToTop + << QPointF(-(2 * 80) - 100, -30) + << QPointF(-(6 * 80) - 50, -20) + << QPointF(-240, -320) + << QPointF(-80, -60) + << QPointF(-(6 * 80) - 40, -320); } void tst_QQuickGridView::header() { QFETCH(QQuickGridView::Flow, flow); QFETCH(Qt::LayoutDirection, layoutDirection); + QFETCH(QQuickItemView::VerticalLayoutDirection, verticalLayoutDirection); QFETCH(QPointF, initialHeaderPos); QFETCH(QPointF, changedHeaderPos); QFETCH(QPointF, initialContentPos); @@ -3018,6 +3292,7 @@ QTRY_VERIFY(gridview != 0); gridview->setFlow(flow); gridview->setLayoutDirection(layoutDirection); + gridview->setVerticalLayoutDirection(verticalLayoutDirection); QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); QQuickItem *contentItem = gridview->contentItem(); @@ -3025,7 +3300,6 @@ QQuickText *header = findItem(contentItem, "header"); QVERIFY(header); - QVERIFY(header == gridview->headerItem()); QCOMPARE(header->pos(), initialHeaderPos); @@ -3033,7 +3307,7 @@ QCOMPARE(header->height(), 30.); QCOMPARE(QPointF(gridview->contentX(), gridview->contentY()), initialContentPos); - if (flow == QQuickGridView::LeftToRight) + if (flow == QQuickGridView::FlowLeftToRight) QCOMPARE(gridview->contentHeight(), (model.count()+2) / 3 * 60. + header->height()); else QCOMPARE(gridview->contentWidth(), (model.count()+3) / 5 * 80. + header->width()); @@ -3091,6 +3365,7 @@ QTRY_VERIFY(gridview != 0); gridview->setFlow(flow); gridview->setLayoutDirection(layoutDirection); + gridview->setVerticalLayoutDirection(verticalLayoutDirection); QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); gridview->setWidth(240); @@ -3105,6 +3380,7 @@ { QTest::addColumn("flow"); QTest::addColumn("layoutDirection"); + QTest::addColumn("verticalLayoutDirection"); QTest::addColumn("initialHeaderPos"); QTest::addColumn("changedHeaderPos"); QTest::addColumn("initialContentPos"); @@ -3118,7 +3394,8 @@ // view width = 240 // header above items, top left - QTest::newRow("flow left to right") << QQuickGridView::LeftToRight << Qt::LeftToRight + QTest::newRow("LeftToRight, LtR, TtB") + << QQuickGridView::FlowLeftToRight << Qt::LeftToRight << QQuickItemView::TopToBottom << QPointF(0, -30) << QPointF(0, -20) << QPointF(0, -30) @@ -3127,7 +3404,8 @@ << QPointF(0, -10); // header above items, top right - QTest::newRow("flow left to right, layout right to left") << QQuickGridView::LeftToRight << Qt::RightToLeft + QTest::newRow("LeftToRight, RtL, TtB") + << QQuickGridView::FlowLeftToRight << Qt::RightToLeft << QQuickItemView::TopToBottom << QPointF(240 - 100, -30) << QPointF((240 - 100) + 50, -20) // 50 = width diff between old and new headers << QPointF(0, -30) @@ -3135,8 +3413,30 @@ << QPointF(160, 0) << QPointF(0, -10); - // header to left of items - QTest::newRow("flow top to bottom, layout left to right") << QQuickGridView::TopToBottom << Qt::LeftToRight + // header below items, bottom left + QTest::newRow("LeftToRight, LtR, BtT") + << QQuickGridView::FlowLeftToRight << Qt::LeftToRight << QQuickItemView::BottomToTop + << QPointF(0, 0) + << QPointF(0, 0) + << QPointF(0, -320 + 30) + << QPointF(0, -320 + 20) + << QPointF(0, -60) + << QPointF(0, -320 + 10); + + // header above items, top right + QTest::newRow("LeftToRight, RtL, BtT") + << QQuickGridView::FlowLeftToRight << Qt::RightToLeft << QQuickItemView::BottomToTop + << QPointF(240 - 100, 0) + << QPointF((240 - 100) + 50, 0) + << QPointF(0, -320 + 30) + << QPointF(0, -320 + 20) + << QPointF(160, -60) + << QPointF(0, -320 + 10); + + + // header to left of items, bottom left + QTest::newRow("TopToBottom, LtR, TtB") + << QQuickGridView::FlowTopToBottom << Qt::LeftToRight << QQuickItemView::TopToBottom << QPointF(-100, 0) << QPointF(-50, 0) << QPointF(-100, 0) @@ -3144,14 +3444,35 @@ << QPointF(0, 0) << QPointF(-40, 0); - // header to right of items - QTest::newRow("flow top to bottom, layout right to left") << QQuickGridView::TopToBottom << Qt::RightToLeft + // header to right of items, bottom right + QTest::newRow("TopToBottom, RtL, TtB") + << QQuickGridView::FlowTopToBottom << Qt::RightToLeft << QQuickItemView::TopToBottom << QPointF(0, 0) << QPointF(0, 0) << QPointF(-(240 - 100), 0) << QPointF(-(240 - 50), 0) << QPointF(-80, 0) << QPointF(-(240 - 40), 0); + + // header to left of items, top left + QTest::newRow("TopToBottom, LtR, BtT") + << QQuickGridView::FlowTopToBottom << Qt::LeftToRight << QQuickItemView::BottomToTop + << QPointF(-100, -30) + << QPointF(-50, -20) + << QPointF(-100, -320) + << QPointF(-50, -320) + << QPointF(0, -60) + << QPointF(-40, -320); + + // header to right of items, top right + QTest::newRow("TopToBottom, RtL, BtT") + << QQuickGridView::FlowTopToBottom << Qt::RightToLeft << QQuickItemView::BottomToTop + << QPointF(0, -30) + << QPointF(0, -20) + << QPointF(-(240 - 100), -320) + << QPointF(-(240 - 50), -320) + << QPointF(-80, -60) + << QPointF(-(240 - 40), -320); } class GVAccessor : public QQuickGridView @@ -3165,138 +3486,144 @@ void tst_QQuickGridView::headerFooter() { - { - // Vertical - QQuickView *canvas = createView(); - - QmlListModel model; - QQmlContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - - canvas->setSource(testFileUrl("headerfooter.qml")); - qApp->processEvents(); - - QQuickGridView *gridview = qobject_cast(canvas->rootObject()); - QTRY_VERIFY(gridview != 0); - - QQuickItem *contentItem = gridview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - QQuickItem *header = findItem(contentItem, "header"); - QVERIFY(header); - QCOMPARE(header->y(), -header->height()); - - QQuickItem *footer = findItem(contentItem, "footer"); - QVERIFY(footer); - QCOMPARE(footer->y(), 0.); - - QCOMPARE(static_cast(gridview)->minY(), header->height()); - QCOMPARE(static_cast(gridview)->maxY(), header->height()); + QFETCH(QQuickGridView::Flow, flow); + QFETCH(Qt::LayoutDirection, layoutDirection); + QFETCH(QQuickItemView::VerticalLayoutDirection, verticalLayoutDirection); + QFETCH(QPointF, headerPos); + QFETCH(QPointF, footerPos); + QFETCH(QPointF, minPos); + QFETCH(QPointF, maxPos); - delete canvas; - } - { - // Horizontal - QQuickView *canvas = createView(); + QQuickView *canvas = getView(); - QmlListModel model; - QQmlContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); + QmlListModel model; + QQmlContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + canvas->setSource(testFileUrl("headerfooter.qml")); + canvas->show(); + qApp->processEvents(); - canvas->setSource(testFileUrl("headerfooter.qml")); - canvas->rootObject()->setProperty("horizontal", true); - qApp->processEvents(); + QQuickGridView *gridview = qobject_cast(canvas->rootObject()); + QTRY_VERIFY(gridview != 0); + gridview->setFlow(flow); + gridview->setLayoutDirection(layoutDirection); + gridview->setVerticalLayoutDirection(verticalLayoutDirection); + QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); - QQuickGridView *gridview = qobject_cast(canvas->rootObject()); - QTRY_VERIFY(gridview != 0); + QQuickItem *contentItem = gridview->contentItem(); + QTRY_VERIFY(contentItem != 0); - QQuickItem *contentItem = gridview->contentItem(); - QTRY_VERIFY(contentItem != 0); + QQuickItem *header = findItem(contentItem, "header"); + QVERIFY(header); + QCOMPARE(header->pos(), headerPos); - QQuickItem *header = findItem(contentItem, "header"); - QVERIFY(header); - QCOMPARE(header->x(), -header->width()); - - QQuickItem *footer = findItem(contentItem, "footer"); - QVERIFY(footer); - QCOMPARE(footer->x(), 0.); + QQuickItem *footer = findItem(contentItem, "footer"); + QVERIFY(footer); + QCOMPARE(footer->pos(), footerPos); - QCOMPARE(static_cast(gridview)->minX(), header->width()); - QCOMPARE(static_cast(gridview)->maxX(), header->width()); + QCOMPARE(static_cast(gridview)->minX(), minPos.x()); + QCOMPARE(static_cast(gridview)->minY(), minPos.y()); + QCOMPARE(static_cast(gridview)->maxX(), maxPos.x()); + QCOMPARE(static_cast(gridview)->maxY(), maxPos.y()); - delete canvas; - } - { - // Horizontal RTL - QQuickView *canvas = createView(); + releaseView(canvas); +} - QmlListModel model; - QQmlContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); +void tst_QQuickGridView::headerFooter_data() +{ + QTest::addColumn("flow"); + QTest::addColumn("layoutDirection"); + QTest::addColumn("verticalLayoutDirection"); + QTest::addColumn("headerPos"); + QTest::addColumn("footerPos"); + QTest::addColumn("minPos"); + QTest::addColumn("maxPos"); + + // header is 240x20 (or 20x320 in TopToBottom) + // footer is 240x30 (or 30x320 in TopToBottom) + + QTest::newRow("LeftToRight, LtR, TtB") + << QQuickGridView::FlowLeftToRight << Qt::LeftToRight << QQuickItemView::TopToBottom + << QPointF(0, -20) << QPointF(0, 0) + << QPointF(0, 20) << QPointF(240, 20); + + QTest::newRow("LeftToRight, RtL, TtB") + << QQuickGridView::FlowLeftToRight << Qt::RightToLeft << QQuickItemView::TopToBottom + << QPointF(0, -20) << QPointF(0, 0) + << QPointF(0, 20) << QPointF(240, 20); + + QTest::newRow("LeftToRight, LtR, BtT") + << QQuickGridView::FlowLeftToRight << Qt::LeftToRight << QQuickItemView::BottomToTop + << QPointF(0, 0) << QPointF(0, -30) + << QPointF(0, 320 - 20) << QPointF(240, 320 - 20); // content flow is reversed + + QTest::newRow("LeftToRight, RtL, BtT") + << QQuickGridView::FlowLeftToRight << Qt::RightToLeft << QQuickItemView::BottomToTop + << QPointF(0, 0) << QPointF(0, -30) + << QPointF(0, 320 - 20) << QPointF(240, 320 - 20); // content flow is reversed + + + QTest::newRow("TopToBottom, LtR, TtB") + << QQuickGridView::FlowTopToBottom << Qt::LeftToRight << QQuickItemView::TopToBottom + << QPointF(-20, 0) << QPointF(0, 0) + << QPointF(20, 0) << QPointF(20, 320); + + QTest::newRow("TopToBottom, RtL, TtB") + << QQuickGridView::FlowTopToBottom << Qt::RightToLeft << QQuickItemView::TopToBottom + << QPointF(0, 0) << QPointF(-30, 0) + << QPointF(240 - 20, 0) << QPointF(240 - 20, 320); // content flow is reversed + + QTest::newRow("TopToBottom, LtR, BtT") + << QQuickGridView::FlowTopToBottom << Qt::LeftToRight << QQuickItemView::BottomToTop + << QPointF(-20, -320) << QPointF(0, -320) + << QPointF(20, 0) << QPointF(20, 320); + + QTest::newRow("TopToBottom, RtL, BtT") + << QQuickGridView::FlowTopToBottom << Qt::RightToLeft << QQuickItemView::BottomToTop + << QPointF(0, -320) << QPointF(-30, -320) + << QPointF(240 - 20, 0) << QPointF(240 - 20, 320); // content flow is reversed +} - canvas->setSource(testFileUrl("headerfooter.qml")); - canvas->rootObject()->setProperty("horizontal", true); - canvas->rootObject()->setProperty("rtl", true); - qApp->processEvents(); +void tst_QQuickGridView::resetModel_headerFooter() +{ + // Resetting a model shouldn't crash in views with header/footer - QQuickGridView *gridview = qobject_cast(canvas->rootObject()); - QTRY_VERIFY(gridview != 0); + QQuickView *canvas = createView(); - QQuickItem *contentItem = gridview->contentItem(); - QTRY_VERIFY(contentItem != 0); + QaimModel model; + for (int i = 0; i < 6; i++) + model.addItem("Item" + QString::number(i), ""); + QQmlContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); - QQuickItem *header = findItem(contentItem, "header"); - QVERIFY(header); - QCOMPARE(header->x(), 0.); - - QQuickItem *footer = findItem(contentItem, "footer"); - QVERIFY(footer); - QCOMPARE(footer->x(), -footer->width()); + canvas->setSource(testFileUrl("headerfooter.qml")); + qApp->processEvents(); - QCOMPARE(static_cast(gridview)->minX(), 240. - header->width()); - QCOMPARE(static_cast(gridview)->maxX(), 240. - header->width()); + QQuickGridView *gridview = qobject_cast(canvas->rootObject()); + QTRY_VERIFY(gridview != 0); - delete canvas; - } - { - // Reset model - QQuickView *canvas = createView(); + QQuickItem *contentItem = gridview->contentItem(); + QTRY_VERIFY(contentItem != 0); - QaimModel model; - for (int i = 0; i < 6; i++) - model.addItem("Item" + QString::number(i), ""); - QQmlContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); + QQuickItem *header = findItem(contentItem, "header"); + QVERIFY(header); + QCOMPARE(header->y(), -header->height()); - canvas->setSource(testFileUrl("headerfooter.qml")); - qApp->processEvents(); + QQuickItem *footer = findItem(contentItem, "footer"); + QVERIFY(footer); + QCOMPARE(footer->y(), 80.*2); - QQuickGridView *gridview = qobject_cast(canvas->rootObject()); - QTRY_VERIFY(gridview != 0); + model.reset(); - QQuickItem *contentItem = gridview->contentItem(); - QTRY_VERIFY(contentItem != 0); + header = findItem(contentItem, "header"); + QVERIFY(header); + QCOMPARE(header->y(), -header->height()); - QQuickItem *header = findItem(contentItem, "header"); - QVERIFY(header); - QCOMPARE(header->y(), -header->height()); - - QQuickItem *footer = findItem(contentItem, "footer"); - QVERIFY(footer); - QCOMPARE(footer->y(), 80.*2); - - model.reset(); - - header = findItem(contentItem, "header"); - QVERIFY(header); - QCOMPARE(header->y(), -header->height()); - - footer = findItem(contentItem, "footer"); - QVERIFY(footer); - QCOMPARE(footer->y(), 80.*2); + footer = findItem(contentItem, "footer"); + QVERIFY(footer); + QCOMPARE(footer->y(), 80.*2); - delete canvas; - } + delete canvas; } void tst_QQuickGridView::resizeViewAndRepaint() @@ -3370,6 +3697,147 @@ delete canvas; } +void tst_QQuickGridView::resizeGrid() +{ + QFETCH(QQuickGridView::Flow, flow); + QFETCH(Qt::LayoutDirection, layoutDirection); + QFETCH(QQuickItemView::VerticalLayoutDirection, verticalLayoutDirection); + QFETCH(QPointF, initialContentPos); + QFETCH(QPointF, firstItemPos); + + QaimModel model; + for (int i = 0; i < 30; i++) + model.addItem("Item" + QString::number(i), ""); + + QQuickView *canvas = getView(); + QQmlContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + ctxt->setContextProperty("testTopToBottom", flow == QQuickGridView::FlowTopToBottom); + ctxt->setContextProperty("testRightToLeft", layoutDirection == Qt::RightToLeft); + ctxt->setContextProperty("testBottomToTop", verticalLayoutDirection == QQuickGridView::BottomToTop); + canvas->setSource(testFileUrl("resizegrid.qml")); + canvas->show(); + qApp->processEvents(); + + QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); + QTRY_VERIFY(gridview != 0); + QQuickItem *contentItem = gridview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + // set the width to slightly larger than 3 items across, to test + // items are aligned correctly in right-to-left + canvas->rootObject()->setWidth(260); + canvas->rootObject()->setHeight(320); + QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + + QCOMPARE(gridview->contentX(), initialContentPos.x()); + QCOMPARE(gridview->contentY(), initialContentPos.y()); + + QQuickItem *item0 = findItem(contentItem, "wrapper", 0); + QVERIFY(item0); + QCOMPARE(item0->pos(), firstItemPos); + + // Confirm items positioned correctly and indexes correct + QList items = findItems(contentItem, "wrapper"); + QVERIFY(items.count() >= 18 && items.count() <= 21); + for (int i = 0; i < model.count() && i < items.count(); ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i))); + QCOMPARE(item->pos(), expectedItemPos(gridview, i, 0)); + QQuickText *name = findItem(contentItem, "textName", i); + QVERIFY(name != 0); + QCOMPARE(name->text(), model.name(i)); + } + + // change from 3x5 grid to 4x7 + canvas->rootObject()->setWidth(canvas->rootObject()->width() + 80); + canvas->rootObject()->setHeight(canvas->rootObject()->height() + 60*2); + QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + + // other than in LeftToRight+RightToLeft layout, the first item should not move + // if view is resized + QCOMPARE(findItem(contentItem, "wrapper", 0), item0); + if (flow == QQuickGridView::FlowLeftToRight && layoutDirection == Qt::RightToLeft) + firstItemPos.rx() += 80; + QCOMPARE(item0->pos(), firstItemPos); + + QPointF newContentPos = initialContentPos; + if (flow == QQuickGridView::FlowTopToBottom && layoutDirection == Qt::RightToLeft) + newContentPos.rx() -= 80.0; + if (verticalLayoutDirection == QQuickItemView::BottomToTop) + newContentPos.ry() -= 60.0 * 2; + QCOMPARE(gridview->contentX(), newContentPos.x()); + QCOMPARE(gridview->contentY(), newContentPos.y()); + + // Confirm items positioned correctly and indexes correct + items = findItems(contentItem, "wrapper"); + QVERIFY(items.count() >= 28); + for (int i = 0; i < model.count() && i < items.count(); ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i))); + QCOMPARE(item->pos(), expectedItemPos(gridview, i, 0)); + QQuickText *name = findItem(contentItem, "textName", i); + QVERIFY(name != 0); + QCOMPARE(name->text(), model.name(i)); + } + + releaseView(canvas); +} + +void tst_QQuickGridView::resizeGrid_data() +{ + QTest::addColumn("flow"); + QTest::addColumn("layoutDirection"); + QTest::addColumn("verticalLayoutDirection"); + QTest::addColumn("initialContentPos"); + QTest::addColumn("firstItemPos"); + + // Initial view width is 260, so in LeftToRight + right-to-left mode the + // content x should be -20 + + QTest::newRow("LeftToRight, LtR, TtB") + << QQuickGridView::FlowLeftToRight << Qt::LeftToRight << QQuickItemView::TopToBottom + << QPointF(0, 0) + << QPointF(0, 0); + + QTest::newRow("LeftToRight, RtL, TtB") + << QQuickGridView::FlowLeftToRight << Qt::RightToLeft << QQuickItemView::TopToBottom + << QPointF(-20.0, 0) + << QPointF(80.0 * 2, 0); + + QTest::newRow("LeftToRight, LtR, BtT") + << QQuickGridView::FlowLeftToRight << Qt::LeftToRight << QQuickItemView::BottomToTop + << QPointF(0, -320) + << QPointF(0, -60.0); + + QTest::newRow("LeftToRight, RtL, BtT") + << QQuickGridView::FlowLeftToRight << Qt::RightToLeft << QQuickItemView::BottomToTop + << QPointF(-20.0, -320) + << QPointF(80.0 * 2, -60.0); + + + QTest::newRow("TopToBottom, LtR, TtB") + << QQuickGridView::FlowTopToBottom << Qt::LeftToRight << QQuickItemView::TopToBottom + << QPointF(0, 0) + << QPointF(0, 0); + + QTest::newRow("TopToBottom, RtL, TtB") + << QQuickGridView::FlowTopToBottom << Qt::RightToLeft << QQuickItemView::TopToBottom + << QPointF(-260, 0) + << QPointF(-80.0, 0); + + QTest::newRow("TopToBottom, LtR, BtT") + << QQuickGridView::FlowTopToBottom << Qt::LeftToRight << QQuickItemView::BottomToTop + << QPointF(0, -320) + << QPointF(0, -60.0); + + QTest::newRow("TopToBottom, RtL, BtT") + << QQuickGridView::FlowTopToBottom << Qt::RightToLeft << QQuickItemView::BottomToTop + << QPointF(-260, -320) + << QPointF(-80.0, -60.0); +} + + void tst_QQuickGridView::changeColumnCount() { QmlListModel model; @@ -3458,11 +3926,7 @@ model.addItem("Ben", "04321"); model.addItem("Jim", "0780"); - QQmlContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - ctxt->setContextProperty("testRightToLeft", QVariant(false)); - ctxt->setContextProperty("testTopToBottom", QVariant(false)); - + canvas->rootContext()->setContextProperty("testModel", &model); canvas->setSource(testFileUrl("gridview1.qml")); qApp->processEvents(); @@ -3776,22 +4240,22 @@ QTest::addColumn("endExtent"); QTest::addColumn("startExtent"); - QTest::newRow("vertical, left to right") << QQuickGridView::LeftToRight << Qt::LeftToRight << int(QQuickItemView::NoHighlightRange) + QTest::newRow("vertical, left to right") << QQuickGridView::FlowLeftToRight << Qt::LeftToRight << int(QQuickItemView::NoHighlightRange) << QPoint(20, 200) << QPoint(20, 20) << 60.0 << 800.0 << 0.0; - QTest::newRow("horizontal, left to right") << QQuickGridView::TopToBottom << Qt::LeftToRight << int(QQuickItemView::NoHighlightRange) + QTest::newRow("horizontal, left to right") << QQuickGridView::FlowTopToBottom << Qt::LeftToRight << int(QQuickItemView::NoHighlightRange) << QPoint(200, 20) << QPoint(20, 20) << 60.0 << 800.0 << 0.0; - QTest::newRow("horizontal, right to left") << QQuickGridView::TopToBottom << Qt::RightToLeft << int(QQuickItemView::NoHighlightRange) + QTest::newRow("horizontal, right to left") << QQuickGridView::FlowTopToBottom << Qt::RightToLeft << int(QQuickItemView::NoHighlightRange) << QPoint(20, 20) << QPoint(200, 20) << -60.0 << -800.0 - 240.0 << -240.0; - QTest::newRow("vertical, left to right, enforce range") << QQuickGridView::LeftToRight << Qt::LeftToRight << int(QQuickItemView::StrictlyEnforceRange) + QTest::newRow("vertical, left to right, enforce range") << QQuickGridView::FlowLeftToRight << Qt::LeftToRight << int(QQuickItemView::StrictlyEnforceRange) << QPoint(20, 200) << QPoint(20, 20) << 60.0 << 940.0 << -20.0; - QTest::newRow("horizontal, left to right, enforce range") << QQuickGridView::TopToBottom << Qt::LeftToRight << int(QQuickItemView::StrictlyEnforceRange) + QTest::newRow("horizontal, left to right, enforce range") << QQuickGridView::FlowTopToBottom << Qt::LeftToRight << int(QQuickItemView::StrictlyEnforceRange) << QPoint(200, 20) << QPoint(20, 20) << 60.0 << 940.0 << -20.0; - QTest::newRow("horizontal, right to left, enforce range") << QQuickGridView::TopToBottom << Qt::RightToLeft << int(QQuickItemView::StrictlyEnforceRange) + QTest::newRow("horizontal, right to left, enforce range") << QQuickGridView::FlowTopToBottom << Qt::RightToLeft << int(QQuickItemView::StrictlyEnforceRange) << QPoint(20, 20) << QPoint(200, 20) << -60.0 << -800.0 - 240.0 - 140.0 << -220.0; } @@ -3826,7 +4290,7 @@ // confirm that a flick hits an item boundary flick(canvas, flickStart, flickEnd, 180); QTRY_VERIFY(gridview->isMoving() == false); // wait until it stops - if (flow == QQuickGridView::LeftToRight) + if (flow == QQuickGridView::FlowLeftToRight) QCOMPARE(qreal(fmod(gridview->contentY(),80.0)), snapAlignment); else QCOMPARE(qreal(fmod(gridview->contentX(),80.0)), snapAlignment); @@ -3835,11 +4299,11 @@ do { flick(canvas, flickStart, flickEnd, 180); QTRY_VERIFY(gridview->isMoving() == false); // wait until it stops - } while (flow == QQuickGridView::LeftToRight + } while (flow == QQuickGridView::FlowLeftToRight ? !gridview->isAtYEnd() : layoutDirection == Qt::LeftToRight ? !gridview->isAtXEnd() : !gridview->isAtXBeginning()); - if (flow == QQuickGridView::LeftToRight) + if (flow == QQuickGridView::FlowLeftToRight) QCOMPARE(gridview->contentY(), endExtent); else QCOMPARE(gridview->contentX(), endExtent); @@ -3848,11 +4312,11 @@ do { flick(canvas, flickEnd, flickStart, 180); QTRY_VERIFY(gridview->isMoving() == false); // wait until it stops - } while (flow == QQuickGridView::LeftToRight + } while (flow == QQuickGridView::FlowLeftToRight ? !gridview->isAtYBeginning() : layoutDirection == Qt::LeftToRight ? !gridview->isAtXBeginning() : !gridview->isAtXEnd()); - if (flow == QQuickGridView::LeftToRight) + if (flow == QQuickGridView::FlowLeftToRight) QCOMPARE(gridview->contentY(), startExtent); else QCOMPARE(gridview->contentX(), startExtent); @@ -3871,22 +4335,22 @@ QTest::addColumn("endExtent"); QTest::addColumn("startExtent"); - QTest::newRow("vertical, left to right") << QQuickGridView::LeftToRight << Qt::LeftToRight << int(QQuickItemView::NoHighlightRange) + QTest::newRow("vertical, left to right") << QQuickGridView::FlowLeftToRight << Qt::LeftToRight << int(QQuickItemView::NoHighlightRange) << QPoint(20, 200) << QPoint(20, 20) << 100.0 << 240.0 << 0.0; - QTest::newRow("horizontal, left to right") << QQuickGridView::TopToBottom << Qt::LeftToRight << int(QQuickItemView::NoHighlightRange) + QTest::newRow("horizontal, left to right") << QQuickGridView::FlowTopToBottom << Qt::LeftToRight << int(QQuickItemView::NoHighlightRange) << QPoint(200, 20) << QPoint(20, 20) << 100.0 << 240.0 << 0.0; - QTest::newRow("horizontal, right to left") << QQuickGridView::TopToBottom << Qt::RightToLeft << int(QQuickItemView::NoHighlightRange) + QTest::newRow("horizontal, right to left") << QQuickGridView::FlowTopToBottom << Qt::RightToLeft << int(QQuickItemView::NoHighlightRange) << QPoint(20, 20) << QPoint(200, 20) << -340.0 << -240.0 - 240.0 << -240.0; - QTest::newRow("vertical, left to right, enforce range") << QQuickGridView::LeftToRight << Qt::LeftToRight << int(QQuickItemView::StrictlyEnforceRange) + QTest::newRow("vertical, left to right, enforce range") << QQuickGridView::FlowLeftToRight << Qt::LeftToRight << int(QQuickItemView::StrictlyEnforceRange) << QPoint(20, 200) << QPoint(20, 20) << 100.0 << 340.0 << -20.0; - QTest::newRow("horizontal, left to right, enforce range") << QQuickGridView::TopToBottom << Qt::LeftToRight << int(QQuickItemView::StrictlyEnforceRange) + QTest::newRow("horizontal, left to right, enforce range") << QQuickGridView::FlowTopToBottom << Qt::LeftToRight << int(QQuickItemView::StrictlyEnforceRange) << QPoint(200, 20) << QPoint(20, 20) << 100.0 << 340.0 << -20.0; - QTest::newRow("horizontal, right to left, enforce range") << QQuickGridView::TopToBottom << Qt::RightToLeft << int(QQuickItemView::StrictlyEnforceRange) + QTest::newRow("horizontal, right to left, enforce range") << QQuickGridView::FlowTopToBottom << Qt::RightToLeft << int(QQuickItemView::StrictlyEnforceRange) << QPoint(20, 20) << QPoint(200, 20) << -340.0 << -240.0 - 240.0 - 100.0 << -220.0; } @@ -3923,7 +4387,7 @@ // confirm that a flick hits next row boundary flick(canvas, flickStart, flickEnd, 180); QTRY_VERIFY(gridview->isMoving() == false); // wait until it stops - if (flow == QQuickGridView::LeftToRight) + if (flow == QQuickGridView::FlowLeftToRight) QCOMPARE(gridview->contentY(), snapAlignment); else QCOMPARE(gridview->contentX(), snapAlignment); @@ -3937,7 +4401,7 @@ do { flick(canvas, flickStart, flickEnd, 180); QTRY_VERIFY(gridview->isMoving() == false); // wait until it stops - } while (flow == QQuickGridView::LeftToRight + } while (flow == QQuickGridView::FlowLeftToRight ? !gridview->isAtYEnd() : layoutDirection == Qt::LeftToRight ? !gridview->isAtXEnd() : !gridview->isAtXBeginning()); @@ -3946,7 +4410,7 @@ QCOMPARE(currentIndexSpy.count(), 3); } - if (flow == QQuickGridView::LeftToRight) + if (flow == QQuickGridView::FlowLeftToRight) QCOMPARE(gridview->contentY(), endExtent); else QCOMPARE(gridview->contentX(), endExtent); @@ -3955,11 +4419,11 @@ do { flick(canvas, flickEnd, flickStart, 180); QTRY_VERIFY(gridview->isMoving() == false); // wait until it stops - } while (flow == QQuickGridView::LeftToRight + } while (flow == QQuickGridView::FlowLeftToRight ? !gridview->isAtYBeginning() : layoutDirection == Qt::LeftToRight ? !gridview->isAtXBeginning() : !gridview->isAtXEnd()); - if (flow == QQuickGridView::LeftToRight) + if (flow == QQuickGridView::FlowLeftToRight) QCOMPARE(gridview->contentY(), startExtent); else QCOMPARE(gridview->contentX(), startExtent); @@ -4171,7 +4635,7 @@ { QFETCH(int, initialItemCount); QFETCH(bool, shouldAnimateTargets); - QFETCH(qreal, contentY); + QFETCH(qreal, contentYRowOffset); QFETCH(int, insertionIndex); QFETCH(int, insertionCount); QFETCH(ListRange, expectedDisplacedIndexes); @@ -4204,8 +4668,8 @@ QVERIFY(contentItem != 0); QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); - if (contentY != 0) { - gridview->setContentY(contentY); + if (contentYRowOffset != 0) { + gridview->setContentY(contentYRowOffset * 60.0); QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); } @@ -4220,7 +4684,7 @@ newData << qMakePair(QString("New item %1").arg(i), QString("")); // last visible item is the first item of the row beneath the view - if (i >= (contentY / 60)*3 && i < qCeil((contentY + gridview->height()) / 60.0)*3) { + if (i >= (gridview->contentY() / 60)*3 && i < qCeil((gridview->contentY() + gridview->height()) / 60.0)*3) { expectedTargetData << newData.last(); targetIndexes << i; } @@ -4264,7 +4728,7 @@ QList items = findItems(contentItem, "wrapper"); int firstVisibleIndex = -1; for (int i=0; iy() >= contentY) { + if (items[i]->y() >= gridview->contentY()) { QQmlExpression e(qmlContext(items[i]), items[i], "index"); firstVisibleIndex = e.evaluate().toInt(); break; @@ -4273,8 +4737,7 @@ QVERIFY2(firstVisibleIndex >= 0, QTest::toString(firstVisibleIndex)); // verify all items moved to the correct final positions - int itemCount = findItems(contentItem, "wrapper").count(); - for (int i = firstVisibleIndex; i < model.count() && i < itemCount; ++i) { + for (int i = firstVisibleIndex; i < model.count() && i < items.count(); ++i) { QQuickItem *item = findItem(contentItem, "wrapper", i); QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i))); QCOMPARE(item->x(), (i%3)*80.0); @@ -4290,7 +4753,7 @@ void tst_QQuickGridView::addTransitions_data() { QTest::addColumn("initialItemCount"); - QTest::addColumn("contentY"); + QTest::addColumn("contentYRowOffset"); QTest::addColumn("shouldAnimateTargets"); QTest::addColumn("insertionIndex"); QTest::addColumn("insertionCount"); @@ -4298,19 +4761,19 @@ // if inserting a full row before visible index, items don't appear or animate in, even if there are > 1 new items QTest::newRow("insert 1, just before start") - << 30 << 20.0 << false + << 30 << 1.0 << false << 0 << 1 << ListRange(); QTest::newRow("insert 1, way before start") - << 30 << 20.0 << false + << 30 << 1.0 << false << 0 << 1 << ListRange(); QTest::newRow("insert multiple, just before start") - << 30 << 100.0 << false + << 30 << 1.0 << false << 0 << 3 << ListRange(); QTest::newRow("insert multiple (< 1 row), just before start") - << 30 << 100.0 << false + << 30 << 1.0 << false << 0 << 2 << ListRange(); QTest::newRow("insert multiple, way before start") - << 30 << 100.0 << false + << 30 << 3.0 << false << 0 << 3 << ListRange(); QTest::newRow("insert 1 at start") @@ -4323,13 +4786,13 @@ << 30 << 0.0 << true << 0 << 5 << ListRange(0, 17); QTest::newRow("insert 1 at start, content y not 0") - << 30 << 60.0 << true // first visible is index 3 + << 30 << 1.0 << true // first visible is index 3 << 3 << 1 << ListRange(0 + 3, 17 + 3); QTest::newRow("insert multiple at start, content y not 0") - << 30 << 60.0 << true // first visible is index 3 + << 30 << 1.0 << true // first visible is index 3 << 3 << 3 << ListRange(0 + 3, 17 + 3); QTest::newRow("insert multiple (> 1 row) at start, content y not 0") - << 30 << 60.0 << true // first visible is index 3 + << 30 << 1.0 << true // first visible is index 3 << 3 << 5 << ListRange(0 + 3, 17 + 3); QTest::newRow("insert 1 at start, to empty grid") @@ -4356,10 +4819,10 @@ << 30 << 0.0 << true << 17 << 3 << ListRange(17, 17); QTest::newRow("insert 1 at bottom, content y not 0") - << 30 << 20.0 * 3 << true + << 30 << 1.0 << true << 17 + 3 << 1 << ListRange(17 + 3, 17 + 3); QTest::newRow("insert multiple at bottom, content y not 0") - << 30 << 20.0 * 3 << true + << 30 << 1.0 << true << 17 + 3 << 3 << ListRange(17 + 3, 17 + 3); @@ -4376,8 +4839,8 @@ void tst_QQuickGridView::moveTransitions() { QFETCH(int, initialItemCount); - QFETCH(qreal, contentY); - QFETCH(qreal, itemsOffsetAfterMove); + QFETCH(qreal, contentYRowOffset); + QFETCH(qreal, rowOffsetAfterMove); QFETCH(int, moveFrom); QFETCH(int, moveTo); QFETCH(int, moveCount); @@ -4409,8 +4872,8 @@ QVERIFY(contentItem != 0); QQuickText *name; - if (contentY != 0) { - gridview->setContentY(contentY); + if (contentYRowOffset != 0) { + gridview->setContentY(contentYRowOffset * 60.0); QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); } @@ -4422,8 +4885,8 @@ QList targetIndexes; for (int i=moveFrom; iheight()) / 60.0)*3) - 1; + int firstVisibleIndex = (gridview->contentY() / 60) * 3; + int lastVisibleIndex = (qCeil((gridview->contentY() + gridview->height()) / 60.0)*3) - 1; if ((i >= firstVisibleIndex && i <= lastVisibleIndex) || (toIndex >= firstVisibleIndex && toIndex <= lastVisibleIndex)) { expectedTargetData << qMakePair(model.name(i), model.number(i)); @@ -4461,7 +4924,7 @@ QList items = findItems(contentItem, "wrapper"); int firstVisibleIndex = -1; for (int i=0; iy() >= contentY) { + if (items[i]->y() >= gridview->contentY()) { QQmlExpression e(qmlContext(items[i]), items[i], "index"); firstVisibleIndex = e.evaluate().toInt(); break; @@ -4470,12 +4933,12 @@ QVERIFY2(firstVisibleIndex >= 0, QTest::toString(firstVisibleIndex)); // verify all items moved to the correct final positions - int itemCount = findItems(contentItem, "wrapper").count(); - for (int i=firstVisibleIndex; i < model.count() && i < itemCount; ++i) { + qreal pixelOffset = 60 * rowOffsetAfterMove; + for (int i=firstVisibleIndex; i < model.count() && i < items.count(); ++i) { QQuickItem *item = findItem(contentItem, "wrapper", i); QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i))); QCOMPARE(item->x(), (i%3)*80.0); - QCOMPARE(item->y(), (i/3)*60.0 + itemsOffsetAfterMove); + QCOMPARE(item->y(), (i/3)*60.0 + pixelOffset); name = findItem(contentItem, "textName", i); QVERIFY(name != 0); QTRY_COMPARE(name->text(), model.name(i)); @@ -4487,94 +4950,132 @@ void tst_QQuickGridView::moveTransitions_data() { QTest::addColumn("initialItemCount"); - QTest::addColumn("contentY"); - QTest::addColumn("itemsOffsetAfterMove"); + QTest::addColumn("contentYRowOffset"); + QTest::addColumn("rowOffsetAfterMove"); QTest::addColumn("moveFrom"); QTest::addColumn("moveTo"); QTest::addColumn("moveCount"); QTest::addColumn("expectedDisplacedIndexes"); - QTest::newRow("move from above view, outside visible items, move 1") << 30 << 120.0 << 0.0 + QTest::newRow("move from above view, outside visible items, move 1") + << 30 << 2.0 << 0.0 << 1 << 10 << 1 << ListRange(6, 10); - QTest::newRow("move from above view, outside visible items, move 1 (first item)") << 30 << 120.0 << 0.0 + QTest::newRow("move from above view, outside visible items, move 1 (first item)") + << 30 << 2.0 << 0.0 << 0 << 10 << 1 << ListRange(6, 10); - QTest::newRow("move from above view, outside visible items, move multiple") << 30 << 120.0 << 60.0 + QTest::newRow("move from above view, outside visible items, move multiple") + << 30 << 2.0 << 1.0 << 1 << 10 << 3 << ListRange(13, 23); - QTest::newRow("move from above view, mix of visible/non-visible") << 30 << 120.0 << 60.0 + QTest::newRow("move from above view, mix of visible/non-visible") + << 30 << 2.0 << 1.0 << 1 << 10 << 6 << (ListRange(7, 15) + ListRange(16, 23)); - QTest::newRow("move from above view, mix of visible/non-visible (move first)") << 30 << 120.0 << 120.0 + QTest::newRow("move from above view, mix of visible/non-visible (move first)") + << 30 << 2.0 << 2.0 << 0 << 10 << 6 << ListRange(16, 23); - QTest::newRow("move within view, move 1 down") << 30 << 0.0 << 0.0 + QTest::newRow("move within view, move 1 down") + << 30 << 0.0 << 0.0 << 1 << 10 << 1 << ListRange(2, 10); - QTest::newRow("move within view, move 1 down, move first item") << 30 << 0.0 << 0.0 + QTest::newRow("move within view, move 1 down, move first item") + << 30 << 0.0 << 0.0 << 0 << 10 << 1 << ListRange(1, 10); - QTest::newRow("move within view, move 1 down, move first item, contentY not 0") << 30 << 120.0 << 0.0 + QTest::newRow("move within view, move 1 down, move first item, contentY not 0") + << 30 << 2.0 << 0.0 << 0+6 << 10+6 << 1 << ListRange(1+6, 10+6); - QTest::newRow("move within view, move 1 down, to last item") << 30 << 0.0 << 0.0 + QTest::newRow("move within view, move 1 down, to last item") + << 30 << 0.0 << 0.0 << 10 << 17 << 1 << ListRange(11, 17); - QTest::newRow("move within view, move first->last") << 30 << 0.0 << 0.0 + QTest::newRow("move within view, move first->last") + << 30 << 0.0 << 0.0 << 0 << 17 << 1 << ListRange(1, 17); - QTest::newRow("move within view, move multiple down") << 30 << 0.0 << 0.0 + QTest::newRow("move within view, move multiple down") + << 30 << 0.0 << 0.0 << 1 << 10 << 3 << ListRange(4, 12); - QTest::newRow("move within view, move multiple down, move first item") << 30 << 0.0 << 0.0 + QTest::newRow("move within view, move multiple down, move first item") + << 30 << 0.0 << 0.0 << 0 << 10 << 3 << ListRange(3, 12); - QTest::newRow("move within view, move multiple down, move first item, contentY not 0") << 30 << 60.0 << 0.0 + QTest::newRow("move within view, move multiple down, move first item, contentY not 0") + << 30 << 1.0 << 0.0 << 0+3 << 10+3 << 3 << ListRange(3+3, 12+3); - QTest::newRow("move within view, move multiple down, displace last item") << 30 << 0.0 << 0.0 + QTest::newRow("move within view, move multiple down, displace last item") + << 30 << 0.0 << 0.0 << 5 << 15 << 3 << ListRange(8, 17); - QTest::newRow("move within view, move multiple down, move first->last") << 30 << 0.0 << 0.0 + QTest::newRow("move within view, move multiple down, move first->last") + << 30 << 0.0 << 0.0 << 0 << 15 << 3 << ListRange(3, 17); - QTest::newRow("move within view, move 1 up") << 30 << 0.0 << 0.0 + QTest::newRow("move within view, move 1 up") + << 30 << 0.0 << 0.0 << 10 << 1 << 1 << ListRange(1, 9); - QTest::newRow("move within view, move 1 up, move to first index") << 30 << 0.0 << 0.0 + QTest::newRow("move within view, move 1 up, move to first index") + << 30 << 0.0 << 0.0 << 10 << 0 << 1 << ListRange(0, 9); - QTest::newRow("move within view, move 1 up, move to first index, contentY not 0") << 30 << 120.0 << 0.0 + QTest::newRow("move within view, move 1 up, move to first index, contentY not 0") + << 30 << 2.0 << 0.0 << 10+6 << 0+6 << 1 << ListRange(0+6, 9+6); - QTest::newRow("move within view, move 1 up, move to first index, contentY not on item border") << 30 << 80.0 << 0.0 + QTest::newRow("move within view, move 1 up, move to first index, contentY not on item border") + << 30 << 1.5 << 0.0 << 10+3 << 0+3 << 1 << ListRange(0+3, 9+3); - QTest::newRow("move within view, move 1 up, move last item") << 30 << 0.0 << 0.0 + QTest::newRow("move within view, move 1 up, move last item") + << 30 << 0.0 << 0.0 << 17 << 10 << 1 << ListRange(10, 16); - QTest::newRow("move within view, move 1 up, move last->first") << 30 << 0.0 << 0.0 + QTest::newRow("move within view, move 1 up, move last->first") + << 30 << 0.0 << 0.0 << 17 << 0 << 1 << ListRange(0, 16); - QTest::newRow("move within view, move multiple up") << 30 << 0.0 << 0.0 + QTest::newRow("move within view, move multiple up") + << 30 << 0.0 << 0.0 << 10 << 1 << 3 << ListRange(1, 9); - QTest::newRow("move within view, move multiple (> 1 row) up") << 30 << 0.0 << 0.0 + QTest::newRow("move within view, move multiple (> 1 row) up") + << 30 << 0.0 << 0.0 << 10 << 1 << 5 << ListRange(1, 9); - QTest::newRow("move within view, move multiple up, move to first index") << 30 << 0.0 << 0.0 + QTest::newRow("move within view, move multiple up, move to first index") + << 30 << 0.0 << 0.0 << 10 << 0 << 3 << ListRange(0, 9); - QTest::newRow("move within view, move multiple up, move to first index, contentY not 0") << 30 << 60.0 << 0.0 + QTest::newRow("move within view, move multiple up, move to first index, contentY not 0") + << 30 << 1.0 << 0.0 << 10+3 << 0+3 << 3 << ListRange(0+3, 9+3); - QTest::newRow("move within view, move multiple up (> 1 row), move to first index, contentY not on border") << 30 << 80.0 << 0.0 + QTest::newRow("move within view, move multiple up (> 1 row), move to first index, contentY not on border") + << 30 << 1.5 << 0.0 << 10+3 << 0+3 << 5 << ListRange(0+3, 9+3); - QTest::newRow("move within view, move multiple up, move last item") << 30 << 0.0 << 0.0 + QTest::newRow("move within view, move multiple up, move last item") + << 30 << 0.0 << 0.0 << 15 << 5 << 3 << ListRange(5, 14); - QTest::newRow("move within view, move multiple up, move last->first") << 30 << 0.0 << 0.0 + QTest::newRow("move within view, move multiple up, move last->first") + << 30 << 0.0 << 0.0 << 15 << 0 << 3 << ListRange(0, 14); - QTest::newRow("move from below view, move 1 up") << 30 << 0.0 << 0.0 + QTest::newRow("move from below view, move 1 up") + << 30 << 0.0 << 0.0 << 20 << 5 << 1 << ListRange(5, 17); - QTest::newRow("move from below view, move 1 up, move to top") << 30 << 0.0 << 0.0 + QTest::newRow("move from below view, move 1 up, move to top") + << 30 << 0.0 << 0.0 << 20 << 0 << 1 << ListRange(0, 17); - QTest::newRow("move from below view, move 1 up, move to top, contentY not 0") << 30 << 60.0 << 0.0 + QTest::newRow("move from below view, move 1 up, move to top, contentY not 0") + << 30 << 1.0 << 0.0 << 25 << 3 << 1 << ListRange(0+3, 17+3); - QTest::newRow("move from below view, move multiple (> 1 row) up") << 30 << 0.0 << 0.0 + QTest::newRow("move from below view, move multiple (> 1 row) up") + << 30 << 0.0 << 0.0 << 20 << 5 << 5 << ListRange(5, 17); - QTest::newRow("move from below view, move multiple up, move to top") << 30 << 0.0 << 0.0 + QTest::newRow("move from below view, move multiple up, move to top") + << 30 << 0.0 << 0.0 << 20 << 0 << 3 << ListRange(0, 17); - QTest::newRow("move from below view, move multiple up, move to top, contentY not 0") << 30 << 60.0 << 0.0 + QTest::newRow("move from below view, move multiple up, move to top, contentY not 0") + << 30 << 1.0 << 0.0 << 25 << 3 << 3 << ListRange(0+3, 17+3); - QTest::newRow("move from below view, move 1 up, move to bottom") << 30 << 0.0 << 0.0 + QTest::newRow("move from below view, move 1 up, move to bottom") + << 30 << 0.0 << 0.0 << 20 << 17 << 1 << ListRange(17, 17); - QTest::newRow("move from below view, move 1 up, move to bottom, contentY not 0") << 30 << 60.0 << 0.0 + QTest::newRow("move from below view, move 1 up, move to bottom, contentY not 0") + << 30 << 1.0 << 0.0 << 25 << 17+3 << 1 << ListRange(17+3, 17+3); - QTest::newRow("move from below view, move multiple up, move to to bottom") << 30 << 0.0 << 0.0 + QTest::newRow("move from below view, move multiple up, move to to bottom") + << 30 << 0.0 << 0.0 << 20 << 17 << 3 << ListRange(17, 17); - QTest::newRow("move from below view, move multiple up, move to bottom, contentY not 0") << 30 << 60.0 << 0.0 + QTest::newRow("move from below view, move multiple up, move to bottom, contentY not 0") + << 30 << 1.0 << 0.0 << 25 << 17+3 << 3 << ListRange(17+3, 17+3); } @@ -4582,7 +5083,7 @@ { QFETCH(int, initialItemCount); QFETCH(bool, shouldAnimateTargets); - QFETCH(qreal, contentY); + QFETCH(qreal, contentYRowOffset); QFETCH(int, removalIndex); QFETCH(int, removalCount); QFETCH(ListRange, expectedDisplacedIndexes); @@ -4615,8 +5116,8 @@ QVERIFY(contentItem != 0); QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); - if (contentY != 0) { - gridview->setContentY(contentY); + if (contentYRowOffset != 0) { + gridview->setContentY(contentYRowOffset * 60.0); QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); } @@ -4627,8 +5128,8 @@ QList targetIndexes; if (shouldAnimateTargets) { for (int i=removalIndex; iheight()) / 60.0)*3) - 1; + int firstVisibleIndex = (gridview->contentY() / 60.0)*3; + int lastVisibleIndex = (qCeil((gridview->contentY() + gridview->height()) / 60.0)*3) - 1; if (i >= firstVisibleIndex && i <= lastVisibleIndex) { expectedTargetData << qMakePair(model.name(i), model.number(i)); targetIndexes << i; @@ -4678,7 +5179,7 @@ for (int i=0; iy() >= contentY) + if (firstVisibleIndex < 0 && items[i]->y() >= gridview->contentY()) firstVisibleIndex = index; else if (index < 0) itemCount--; // exclude deleted items @@ -4690,7 +5191,7 @@ QQuickItem *item = findItem(contentItem, "wrapper", i); QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i))); QCOMPARE(item->x(), (i%3)*80.0); - QCOMPARE(item->y(), contentY + ((i-firstVisibleIndex)/3) * 60.0); + QCOMPARE(item->y(), gridview->contentY() + ((i-firstVisibleIndex)/3) * 60.0); QQuickText *name = findItem(contentItem, "textName", i); QVERIFY(name != 0); QTRY_COMPARE(name->text(), model.name(i)); @@ -4702,7 +5203,7 @@ void tst_QQuickGridView::removeTransitions_data() { QTest::addColumn("initialItemCount"); - QTest::addColumn("contentY"); + QTest::addColumn("contentYRowOffset"); QTest::addColumn("shouldAnimateTargets"); QTest::addColumn("removalIndex"); QTest::addColumn("removalCount"); @@ -4714,19 +5215,19 @@ // For a GridView, removing any number of items other than a full row before the start // should displace all items in the view QTest::newRow("remove 1 before start") - << 30 << 120.0 << false + << 30 << 2.0 << false << 2 << 1 << ListRange(6, 24); // 6-24 are displaced QTest::newRow("remove 1 row, before start") - << 30 << 120.0 << false + << 30 << 2.0 << false << 3 << 3 << ListRange(); QTest::newRow("remove between 1-2 rows, before start") - << 30 << 120.0 << false + << 30 << 2.0 << false << 0 << 5 << ListRange(6, 25); QTest::newRow("remove 2 rows, before start") - << 30 << 120.0 << false + << 30 << 2.0 << false << 0 << 6 << ListRange(); QTest::newRow("remove mix of before and after start") - << 30 << 60.0 << true + << 30 << 1.0 << true << 2 << 3 << ListRange(5, 23); // 5-23 are displaced into view @@ -4737,10 +5238,10 @@ << 30 << 0.0 << true << 0 << 3 << ListRange(3, 20); // 3-18 are displaced into view QTest::newRow("remove 1 from start, content y not 0") - << 30 << 60.0 << true + << 30 << 1.0 << true << 3 << 1 << ListRange(1 + 3, 18 + 3); QTest::newRow("remove multiple from start, content y not 0") - << 30 << 60.0 << true + << 30 << 1.0 << true << 3 << 3 << ListRange(3 + 3, 20 + 3); @@ -4762,10 +5263,10 @@ << 30 << 0.0 << true << 15 << 5 << ListRange(20, 22); QTest::newRow("remove 1 from bottom, content y not 0") - << 30 << 60.0 << true + << 30 << 1.0 << true << 17 + 3 << 1 << ListRange(18 + 3, 18 + 3); QTest::newRow("remove multiple (1 row) from bottom, content y not 0") - << 30 << 60.0 << true + << 30 << 1.0 << true << 15 + 3 << 3 << ListRange(18 + 3, 20 + 3); @@ -5246,11 +5747,7 @@ for (int i = 0; i < 90; i++) model.addItem("Item" + QString::number(i), ""); - QQmlContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - ctxt->setContextProperty("testRightToLeft", QVariant(false)); - ctxt->setContextProperty("testTopToBottom", QVariant(false)); - + canvas->rootContext()->setContextProperty("testModel", &model); canvas->setSource(testFileUrl("gridview1.qml")); canvas->show(); qApp->processEvents(); @@ -5554,6 +6051,220 @@ delete canvas; } + +void tst_QQuickGridView::inserted_leftToRight_RtL_TtB() +{ + inserted_defaultLayout(QQuickGridView::FlowLeftToRight, Qt::RightToLeft); +} + +void tst_QQuickGridView::inserted_leftToRight_RtL_TtB_data() +{ + inserted_defaultLayout_data(); +} + +void tst_QQuickGridView::inserted_topToBottom_LtR_TtB() +{ + inserted_defaultLayout(QQuickGridView::FlowTopToBottom); +} + +void tst_QQuickGridView::inserted_topToBottom_LtR_TtB_data() +{ + inserted_defaultLayout_data(); +} + +void tst_QQuickGridView::inserted_topToBottom_RtL_TtB() +{ + inserted_defaultLayout(QQuickGridView::FlowTopToBottom, Qt::RightToLeft); +} + +void tst_QQuickGridView::inserted_topToBottom_RtL_TtB_data() +{ + inserted_defaultLayout_data(); +} + +void tst_QQuickGridView::inserted_leftToRight_LtR_BtT() +{ + inserted_defaultLayout(QQuickGridView::FlowLeftToRight, Qt::LeftToRight, QQuickItemView::BottomToTop); +} + +void tst_QQuickGridView::inserted_leftToRight_LtR_BtT_data() +{ + inserted_defaultLayout_data(); +} + +void tst_QQuickGridView::inserted_leftToRight_RtL_BtT() +{ + inserted_defaultLayout(QQuickGridView::FlowLeftToRight, Qt::RightToLeft, QQuickItemView::BottomToTop); +} + +void tst_QQuickGridView::inserted_leftToRight_RtL_BtT_data() +{ + inserted_defaultLayout_data(); +} + +void tst_QQuickGridView::inserted_topToBottom_LtR_BtT() +{ + inserted_defaultLayout(QQuickGridView::FlowTopToBottom, Qt::LeftToRight, QQuickItemView::BottomToTop); +} + +void tst_QQuickGridView::inserted_topToBottom_LtR_BtT_data() +{ + inserted_defaultLayout_data(); +} + +void tst_QQuickGridView::inserted_topToBottom_RtL_BtT() +{ + inserted_defaultLayout(QQuickGridView::FlowTopToBottom, Qt::RightToLeft, QQuickItemView::BottomToTop); +} + +void tst_QQuickGridView::inserted_topToBottom_RtL_BtT_data() +{ + inserted_defaultLayout_data(); +} + + +void tst_QQuickGridView::removed_leftToRight_RtL_TtB() +{ + removed_defaultLayout(QQuickGridView::FlowLeftToRight, Qt::RightToLeft); +} + +void tst_QQuickGridView::removed_leftToRight_RtL_TtB_data() +{ + removed_defaultLayout_data(); +} + +void tst_QQuickGridView::removed_topToBottom_LtR_TtB() +{ + removed_defaultLayout(QQuickGridView::FlowTopToBottom); +} + +void tst_QQuickGridView::removed_topToBottom_LtR_TtB_data() +{ + removed_defaultLayout_data(); +} + +void tst_QQuickGridView::removed_topToBottom_RtL_TtB() +{ + removed_defaultLayout(QQuickGridView::FlowTopToBottom, Qt::RightToLeft); +} + +void tst_QQuickGridView::removed_topToBottom_RtL_TtB_data() +{ + removed_defaultLayout_data(); +} + +void tst_QQuickGridView::removed_leftToRight_LtR_BtT() +{ + removed_defaultLayout(QQuickGridView::FlowLeftToRight, Qt::LeftToRight, QQuickItemView::BottomToTop); +} + +void tst_QQuickGridView::removed_leftToRight_LtR_BtT_data() +{ + removed_defaultLayout_data(); +} + +void tst_QQuickGridView::removed_leftToRight_RtL_BtT() +{ + removed_defaultLayout(QQuickGridView::FlowLeftToRight, Qt::RightToLeft, QQuickItemView::BottomToTop); +} + +void tst_QQuickGridView::removed_leftToRight_RtL_BtT_data() +{ + removed_defaultLayout_data(); +} + +void tst_QQuickGridView::removed_topToBottom_LtR_BtT() +{ + removed_defaultLayout(QQuickGridView::FlowTopToBottom, Qt::LeftToRight, QQuickItemView::BottomToTop); +} + +void tst_QQuickGridView::removed_topToBottom_LtR_BtT_data() +{ + removed_defaultLayout_data(); +} + +void tst_QQuickGridView::removed_topToBottom_RtL_BtT() +{ + removed_defaultLayout(QQuickGridView::FlowTopToBottom, Qt::RightToLeft, QQuickItemView::BottomToTop); +} + +void tst_QQuickGridView::removed_topToBottom_RtL_BtT_data() +{ + removed_defaultLayout_data(); +} + + +void tst_QQuickGridView::moved_leftToRight_RtL_TtB() +{ + moved_defaultLayout(QQuickGridView::FlowLeftToRight, Qt::RightToLeft); +} + +void tst_QQuickGridView::moved_leftToRight_RtL_TtB_data() +{ + moved_defaultLayout_data(); +} + +void tst_QQuickGridView::moved_topToBottom_LtR_TtB() +{ + moved_defaultLayout(QQuickGridView::FlowTopToBottom); +} + +void tst_QQuickGridView::moved_topToBottom_LtR_TtB_data() +{ + moved_defaultLayout_data(); +} + +void tst_QQuickGridView::moved_topToBottom_RtL_TtB() +{ + moved_defaultLayout(QQuickGridView::FlowTopToBottom, Qt::RightToLeft); +} + +void tst_QQuickGridView::moved_topToBottom_RtL_TtB_data() +{ + moved_defaultLayout_data(); +} + +void tst_QQuickGridView::moved_leftToRight_LtR_BtT() +{ + moved_defaultLayout(QQuickGridView::FlowLeftToRight, Qt::LeftToRight, QQuickItemView::BottomToTop); +} + +void tst_QQuickGridView::moved_leftToRight_LtR_BtT_data() +{ + moved_defaultLayout_data(); +} + +void tst_QQuickGridView::moved_leftToRight_RtL_BtT() +{ + moved_defaultLayout(QQuickGridView::FlowLeftToRight, Qt::RightToLeft, QQuickItemView::BottomToTop); +} + +void tst_QQuickGridView::moved_leftToRight_RtL_BtT_data() +{ + moved_defaultLayout_data(); +} + +void tst_QQuickGridView::moved_topToBottom_LtR_BtT() +{ + moved_defaultLayout(QQuickGridView::FlowTopToBottom, Qt::LeftToRight, QQuickItemView::BottomToTop); +} + +void tst_QQuickGridView::moved_topToBottom_LtR_BtT_data() +{ + moved_defaultLayout_data(); +} + +void tst_QQuickGridView::moved_topToBottom_RtL_BtT() +{ + moved_defaultLayout(QQuickGridView::FlowTopToBottom, Qt::RightToLeft, QQuickItemView::BottomToTop); +} + +void tst_QQuickGridView::moved_topToBottom_RtL_BtT_data() +{ + moved_defaultLayout_data(); +} + + QList tst_QQuickGridView::toIntList(const QVariantList &list) { QList ret; diff -Nru qt5-declarative-0.1~git20120402/tests/auto/quick/qquickitem/tst_qquickitem.cpp qt5-declarative-0.1~git20120423/tests/auto/quick/qquickitem/tst_qquickitem.cpp --- qt5-declarative-0.1~git20120402/tests/auto/quick/qquickitem/tst_qquickitem.cpp 2012-04-02 11:02:55.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/quick/qquickitem/tst_qquickitem.cpp 2012-04-23 11:44:59.000000000 +0000 @@ -141,6 +141,7 @@ void multipleFocusClears(); void focusSubItemInNonFocusScope(); void parentItemWithFocus(); + void reparentFocusedItem(); void constructor(); void setParentItem(); @@ -822,6 +823,34 @@ } } +void tst_qquickitem::reparentFocusedItem() +{ + QQuickCanvas canvas; + ensureFocus(&canvas); + QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas); + + QQuickItem parent(canvas.rootItem()); + QQuickItem child(&parent); + QQuickItem sibling(&parent); + QQuickItem grandchild(&child); + + FocusState focusState; + focusState << &parent << &child << &sibling << &grandchild; + FVERIFY(); + + grandchild.setFocus(true); + focusState[&parent].set(false, false); + focusState[&child].set(false, false); + focusState[&sibling].set(false, false); + focusState[&grandchild].set(true, true); + focusState.active(&grandchild); + FVERIFY(); + + // Parenting the item to another item within the same focus scope shouldn't change it's focus. + child.setParentItem(&sibling); + FVERIFY(); +} + void tst_qquickitem::constructor() { QQuickItem *root = new QQuickItem; diff -Nru qt5-declarative-0.1~git20120402/tests/auto/quick/qquicklistview/data/headerfooter.qml qt5-declarative-0.1~git20120423/tests/auto/quick/qquicklistview/data/headerfooter.qml --- qt5-declarative-0.1~git20120402/tests/auto/quick/qquicklistview/data/headerfooter.qml 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/quick/qquicklistview/data/headerfooter.qml 2012-04-23 11:32:40.000000000 +0000 @@ -2,27 +2,24 @@ ListView { id: view - property bool horizontal: false - property bool rtl: false + width: 240 height: 320 model: testModel - - orientation: horizontal ? ListView.Horizontal : ListView.Vertical + header: Rectangle { objectName: "header" - width: horizontal ? 20 : view.width - height: horizontal ? view.height : 20 + width: orientation == ListView.Horizontal ? 20 : view.width + height: orientation == ListView.Horizontal ? view.height : 20 color: "red" } footer: Rectangle { objectName: "footer" - width: horizontal ? 30 : view.width - height: horizontal ? view.height : 30 + width: orientation == ListView.Horizontal ? 30 : view.width + height: orientation == ListView.Horizontal ? view.height : 30 color: "blue" } delegate: Text { width: 30; height: 30; text: index + "(" + x + ")" } - layoutDirection: rtl ? Qt.RightToLeft : Qt.LeftToRight } diff -Nru qt5-declarative-0.1~git20120402/tests/auto/quick/qquicklistview/data/header.qml qt5-declarative-0.1~git20120423/tests/auto/quick/qquicklistview/data/header.qml --- qt5-declarative-0.1~git20120402/tests/auto/quick/qquicklistview/data/header.qml 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/quick/qquicklistview/data/header.qml 2012-04-23 11:32:40.000000000 +0000 @@ -15,7 +15,7 @@ height: 30 width: 240 Text { - text: index + " " + x + "," + y + text: index + " " + parent.x + "," + parent.y } color: ListView.isCurrentItem ? "lightsteelblue" : "white" } diff -Nru qt5-declarative-0.1~git20120402/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp qt5-declarative-0.1~git20120423/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp --- qt5-declarative-0.1~git20120402/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp 2012-04-23 11:44:59.000000000 +0000 @@ -58,7 +58,9 @@ #include Q_DECLARE_METATYPE(Qt::LayoutDirection) +Q_DECLARE_METATYPE(QQuickItemView::VerticalLayoutDirection) Q_DECLARE_METATYPE(QQuickListView::Orientation) +Q_DECLARE_METATYPE(Qt::Key) using namespace QQuickViewTestUtil; using namespace QQuickVisualTestUtil; @@ -89,6 +91,8 @@ void qAbstractItemModel_inserted(); void qAbstractItemModel_inserted_more(); void qAbstractItemModel_inserted_more_data(); + void qAbstractItemModel_inserted_more_bottomToTop(); + void qAbstractItemModel_inserted_more_bottomToTop_data(); void qListModelInterface_removed(); void qListModelInterface_removed_more(); @@ -97,6 +101,8 @@ void qAbstractItemModel_removed(); void qAbstractItemModel_removed_more(); void qAbstractItemModel_removed_more_data(); + void qAbstractItemModel_removed_more_bottomToTop(); + void qAbstractItemModel_removed_more_bottomToTop_data(); void qListModelInterface_moved(); void qListModelInterface_moved_data(); @@ -104,13 +110,18 @@ void qListModelInterface_package_moved_data(); void qAbstractItemModel_moved(); void qAbstractItemModel_moved_data(); + void qAbstractItemModel_moved_bottomToTop(); + void qAbstractItemModel_moved_bottomToTop_data(); - void multipleChanges(); - void multipleChanges_data(); + void multipleChanges_condensed() { multipleChanges(true); } + void multipleChanges_condensed_data() { multipleChanges_data(); } + void multipleChanges_uncondensed() { multipleChanges(false); } + void multipleChanges_uncondensed_data() { multipleChanges_data(); } void qListModelInterface_clear(); void qListModelInterface_package_clear(); void qAbstractItemModel_clear(); + void qAbstractItemModel_clear_bottomToTop(); void insertBeforeVisible(); void insertBeforeVisible_data(); @@ -120,6 +131,8 @@ void currentIndex_delayedItemCreation_data(); void currentIndex(); void noCurrentIndex(); + void keyNavigation(); + void keyNavigation_data(); void enforceRange(); void enforceRange_withoutHighlight(); void spacing(); @@ -142,6 +155,8 @@ void footer(); void footer_data(); void headerFooter(); + void headerFooter_data(); + void resetModel_headerFooter(); void resizeView(); void resizeViewAndRepaint(); void sizeLessThan1(); @@ -195,13 +210,16 @@ template void items(const QUrl &source, bool forceLayout); template void changed(const QUrl &source, bool forceLayout); template void inserted(const QUrl &source); - template void inserted_more(); + template void inserted_more(QQuickItemView::VerticalLayoutDirection verticalLayoutDirection = QQuickItemView::TopToBottom); template void removed(const QUrl &source, bool animated); - template void removed_more(const QUrl &source); - template void moved(const QUrl &source); - template void clear(const QUrl &source); + template void removed_more(const QUrl &source, QQuickItemView::VerticalLayoutDirection verticalLayoutDirection = QQuickItemView::TopToBottom); + template void moved(const QUrl &source, QQuickItemView::VerticalLayoutDirection verticalLayoutDirection = QQuickItemView::TopToBottom); + template void clear(const QUrl &source, QQuickItemView::VerticalLayoutDirection verticalLayoutDirection = QQuickItemView::TopToBottom); template void sections(const QUrl &source); + void multipleChanges(bool condensed); + void multipleChanges_data(); + QList toIntList(const QVariantList &list); void matchIndexLists(const QVariantList &indexLists, const QList &expectedIndexes); void matchItemsAndIndexes(const QVariantMap &items, const QaimModel &model, const QList &expectedIndexes); @@ -522,7 +540,7 @@ } template -void tst_QQuickListView::inserted_more() +void tst_QQuickListView::inserted_more(QQuickItemView::VerticalLayoutDirection verticalLayoutDirection) { QFETCH(qreal, contentY); QFETCH(int, insertIndex); @@ -550,8 +568,15 @@ QQuickItem *contentItem = listview->contentItem(); QTRY_VERIFY(contentItem != 0); + bool waitForPolish = (contentY != 0); + if (verticalLayoutDirection == QQuickItemView::BottomToTop) { + listview->setVerticalLayoutDirection(verticalLayoutDirection); + QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + contentY = -listview->height() - contentY; + } listview->setContentY(contentY); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + if (waitForPolish) + QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); QList > newData; for (int i=0; i(contentItem, "wrapper", 0); QVERIFY(item0); - QCOMPARE(item0->y(), itemsOffsetAfterMove); + if (verticalLayoutDirection == QQuickItemView::BottomToTop) + QCOMPARE(item0->y(), -item0->height() - itemsOffsetAfterMove); + else + QCOMPARE(item0->y(), itemsOffsetAfterMove); QList items = findItems(contentItem, "wrapper"); int firstVisibleIndex = -1; for (int i=0; iy() >= contentY) { - QQmlExpression e(qmlContext(items[i]), items[i], "index"); - firstVisibleIndex = e.evaluate().toInt(); + QQuickItem *item = findItem(contentItem, "wrapper", i); + if (item && item->isVisible()) { + firstVisibleIndex = i; break; } } QVERIFY2(firstVisibleIndex >= 0, QTest::toString(firstVisibleIndex)); // Confirm items positioned correctly and indexes correct - int itemCount = findItems(contentItem, "wrapper").count(); QQuickText *name; QQuickText *number; - for (int i = firstVisibleIndex; i < model.count() && i < itemCount; ++i) { + for (int i = firstVisibleIndex; i < model.count() && i < items.count(); ++i) { QQuickItem *item = findItem(contentItem, "wrapper", i); QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i))); - QTRY_COMPARE(item->y(), i*20.0 + itemsOffsetAfterMove); + qreal pos = i*20.0 + itemsOffsetAfterMove; + if (verticalLayoutDirection == QQuickItemView::BottomToTop) + pos = -item0->height() - pos; + QTRY_COMPARE(item->y(), pos); name = findItem(contentItem, "textName", i); QVERIFY(name != 0); QTRY_COMPARE(name->text(), model.name(i)); @@ -952,15 +982,13 @@ } template -void tst_QQuickListView::removed_more(const QUrl &source) +void tst_QQuickListView::removed_more(const QUrl &source, QQuickItemView::VerticalLayoutDirection verticalLayoutDirection) { QFETCH(qreal, contentY); QFETCH(int, removeIndex); QFETCH(int, removeCount); QFETCH(qreal, itemsOffsetAfterMove); - QQuickText *name; - QQuickText *number; QQuickView *canvas = getView(); T model; @@ -983,13 +1011,15 @@ QQuickItem *contentItem = listview->contentItem(); QTRY_VERIFY(contentItem != 0); + bool waitForPolish = (contentY != 0); + if (verticalLayoutDirection == QQuickItemView::BottomToTop) { + listview->setVerticalLayoutDirection(verticalLayoutDirection); + QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + contentY = -listview->height() - contentY; + } listview->setContentY(contentY); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); - - // wait for refill (after refill, items above the firstVisibleIndex-1 should not be rendered) - int firstVisibleIndex = contentY / 20; - if (firstVisibleIndex - 2 >= 0) - QTRY_VERIFY(!findItem(contentItem, "textName", firstVisibleIndex - 2)); + if (waitForPolish) + QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); model.removeItems(removeIndex, removeCount); QTRY_COMPARE(listview->property("count").toInt(), model.count()); @@ -997,24 +1027,33 @@ // check visibleItems.first() is in correct position QQuickItem *item0 = findItem(contentItem, "wrapper", 0); QVERIFY(item0); - QCOMPARE(item0->y(), itemsOffsetAfterMove); + QVERIFY(item0); + if (verticalLayoutDirection == QQuickItemView::BottomToTop) + QCOMPARE(item0->y(), -item0->height() - itemsOffsetAfterMove); + else + QCOMPARE(item0->y(), itemsOffsetAfterMove); QList items = findItems(contentItem, "wrapper"); + int firstVisibleIndex = -1; for (int i=0; iy() >= contentY) { - QQmlExpression e(qmlContext(items[i]), items[i], "index"); - firstVisibleIndex = e.evaluate().toInt(); + QQuickItem *item = findItem(contentItem, "wrapper", i); + if (item && item->isVisible()) { + firstVisibleIndex = i; break; } } QVERIFY2(firstVisibleIndex >= 0, QTest::toString(firstVisibleIndex)); // Confirm items positioned correctly and indexes correct - int itemCount = findItems(contentItem, "wrapper").count(); - for (int i = firstVisibleIndex; i < model.count() && i < itemCount; ++i) { + QQuickText *name; + QQuickText *number; + for (int i = firstVisibleIndex; i < model.count() && i < items.count(); ++i) { QQuickItem *item = findItem(contentItem, "wrapper", i); QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i))); - QTRY_COMPARE(item->y(), i*20.0 + itemsOffsetAfterMove); + qreal pos = i*20.0 + itemsOffsetAfterMove; + if (verticalLayoutDirection == QQuickItemView::BottomToTop) + pos = -item0->height() - pos; + QTRY_COMPARE(item->y(), pos); name = findItem(contentItem, "textName", i); QVERIFY(name != 0); QTRY_COMPARE(name->text(), model.name(i)); @@ -1131,7 +1170,7 @@ } template -void tst_QQuickListView::clear(const QUrl &source) +void tst_QQuickListView::clear(const QUrl &source, QQuickItemView::VerticalLayoutDirection verticalLayoutDirection) { QQuickView *canvas = createView(); @@ -1153,13 +1192,19 @@ QTRY_VERIFY(listview != 0); QQuickItem *contentItem = listview->contentItem(); QTRY_VERIFY(contentItem != 0); + + listview->setVerticalLayoutDirection(verticalLayoutDirection); QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); model.clear(); + QTRY_COMPARE(findItems(contentItem, "wrapper").count(), 0); QTRY_VERIFY(listview->count() == 0); QTRY_VERIFY(listview->currentItem() == 0); - QTRY_VERIFY(listview->contentY() == 0); + if (verticalLayoutDirection == QQuickItemView::TopToBottom) + QTRY_COMPARE(listview->contentY(), 0.0); + else + QTRY_COMPARE(listview->contentY(), -listview->height()); QVERIFY(listview->currentIndex() == -1); // confirm sanity when adding an item to cleared list @@ -1173,7 +1218,7 @@ } template -void tst_QQuickListView::moved(const QUrl &source) +void tst_QQuickListView::moved(const QUrl &source, QQuickItemView::VerticalLayoutDirection verticalLayoutDirection) { QFETCH(qreal, contentY); QFETCH(int, from); @@ -1204,15 +1249,19 @@ QTRY_VERIFY(listview != 0); QQuickItem *contentItem = listview->contentItem(); QTRY_VERIFY(contentItem != 0); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); - QQuickItem *currentItem = listview->currentItem(); - QTRY_VERIFY(currentItem != 0); + // always need to wait for view to be painted before the first move() + QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); - if (contentY != 0) { - listview->setContentY(contentY); + bool waitForPolish = (contentY != 0); + if (verticalLayoutDirection == QQuickItemView::BottomToTop) { + listview->setVerticalLayoutDirection(verticalLayoutDirection); QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + contentY = -listview->height() - contentY; } + listview->setContentY(contentY); + if (waitForPolish) + QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); model.moveItems(from, to, count); QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); @@ -1220,22 +1269,22 @@ QList items = findItems(contentItem, "wrapper"); int firstVisibleIndex = -1; for (int i=0; iy() >= contentY) { - QQmlExpression e(qmlContext(items[i]), items[i], "index"); - firstVisibleIndex = e.evaluate().toInt(); + QQuickItem *item = findItem(contentItem, "wrapper", i); + if (item && item->isVisible()) { + firstVisibleIndex = i; break; } } QVERIFY2(firstVisibleIndex >= 0, QTest::toString(firstVisibleIndex)); // Confirm items positioned correctly and indexes correct - int itemCount = findItems(contentItem, "wrapper").count(); - for (int i = firstVisibleIndex; i < model.count() && i < itemCount; ++i) { - if (i >= firstVisibleIndex + 16) // index has moved out of view - continue; + for (int i = firstVisibleIndex; i < model.count() && i < items.count(); ++i) { QQuickItem *item = findItem(contentItem, "wrapper", i); QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i))); - QTRY_COMPARE(item->y(), i*20.0 + itemsOffsetAfterMove); + qreal pos = i*20.0 + itemsOffsetAfterMove; + if (verticalLayoutDirection == QQuickItemView::BottomToTop) + pos = -item->height() - pos; + QTRY_COMPARE(item->y(), pos); name = findItem(contentItem, "textName", i); QVERIFY(name != 0); QTRY_COMPARE(name->text(), model.name(i)); @@ -1244,7 +1293,7 @@ QTRY_COMPARE(number->text(), model.number(i)); // current index should have been updated - if (item == currentItem) + if (item == listview->currentItem()) QTRY_COMPARE(listview->currentIndex(), i); } @@ -1403,7 +1452,7 @@ << -20.0 * 3; // to minimize movement, 16,17,18 move to above item 0, and other items do not move } -void tst_QQuickListView::multipleChanges() +void tst_QQuickListView::multipleChanges(bool condensed) { QFETCH(int, startCount); QFETCH(QList, changes); @@ -1439,31 +1488,32 @@ for (int j=changes[i].index; jpolishScheduled, false); break; } case ListChange::Removed: model.removeItems(changes[i].index, changes[i].count); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); break; case ListChange::Moved: model.moveItems(changes[i].index, changes[i].to, changes[i].count); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); break; case ListChange::SetCurrent: listview->setCurrentIndex(changes[i].index); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); break; case ListChange::SetContentY: listview->setContentY(changes[i].pos); - QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); break; + default: + continue; + } + if (!condensed) { + QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); } } + QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); - QTRY_COMPARE(listview->count(), newCount); + QCOMPARE(listview->count(), newCount); QCOMPARE(listview->count(), model.count()); - QTRY_COMPARE(listview->currentIndex(), newCurrentIndex); + QCOMPARE(listview->currentIndex(), newCurrentIndex); QQuickText *name; QQuickText *number; @@ -1626,13 +1676,34 @@ << ListChange::insert(3, 5) ) << 15 << 8; - QTest::newRow("clear current") << 0 << (QList() << ListChange::insert(0, 5) << ListChange::setCurrent(-1) << ListChange::remove(0, 5) << ListChange::insert(0, 5) ) << 5 << -1; + + QTest::newRow("remove, scroll") << 30 << (QList() + << ListChange::remove(20, 5) + << ListChange::setContentY(20) + ) << 25 << 0; + + QTest::newRow("insert, scroll") << 10 << (QList() + << ListChange::insert(9, 5) + << ListChange::setContentY(20) + ) << 15 << 0; + + QTest::newRow("move, scroll") << 20 << (QList() + << ListChange::move(15, 8, 3) + << ListChange::setContentY(0) + ) << 20 << 0; + + QTest::newRow("clear, insert, scroll") << 30 << (QList() + << ListChange::setContentY(20) + << ListChange::remove(0, 30) + << ListChange::insert(0, 2) + << ListChange::setContentY(0) + ) << 2 << 0; } void tst_QQuickListView::swapWithFirstItem() @@ -2313,35 +2384,11 @@ QCOMPARE(listview->currentItem(), findItem(contentItem, "wrapper", 20)); QCOMPARE(listview->highlightItem()->y(), listview->currentItem()->y()); - // no wrap listview->setCurrentIndex(0); QCOMPARE(listview->currentIndex(), 0); // confirm that the velocity is updated QTRY_VERIFY(listview->verticalVelocity() != 0.0); - listview->incrementCurrentIndex(); - QCOMPARE(listview->currentIndex(), 1); - listview->decrementCurrentIndex(); - QCOMPARE(listview->currentIndex(), 0); - - listview->decrementCurrentIndex(); - QCOMPARE(listview->currentIndex(), 0); - - // with wrap - ctxt->setContextProperty("testWrap", QVariant(true)); - QVERIFY(listview->isWrapEnabled()); - - listview->decrementCurrentIndex(); - QCOMPARE(listview->currentIndex(), model.count()-1); - - QTRY_COMPARE(listview->contentY(), 280.0); - - listview->incrementCurrentIndex(); - QCOMPARE(listview->currentIndex(), 0); - - QTRY_COMPARE(listview->contentY(), 0.0); - - // footer should become visible if it is out of view, and then current index is set to count-1 canvas->rootObject()->setProperty("showFooter", true); QTRY_VERIFY(listview->footerItem()); @@ -2360,40 +2407,6 @@ QTRY_COMPARE(listview->contentY(), -listview->headerItem()->height()); canvas->rootObject()->setProperty("showHeader", false); - - // Test keys - canvas->show(); - canvas->requestActivateWindow(); - QTest::qWaitForWindowShown(canvas); - QTRY_VERIFY(qGuiApp->focusWindow() == canvas); - - listview->setCurrentIndex(0); - - QTest::keyClick(canvas, Qt::Key_Down); - QCOMPARE(listview->currentIndex(), 1); - - QTest::keyClick(canvas, Qt::Key_Up); - QCOMPARE(listview->currentIndex(), 0); - - // hold down Key_Down - for (int i=0; icurrentIndex(), i+1); - } - QTest::keyRelease(canvas, Qt::Key_Down); - QTRY_COMPARE(listview->currentIndex(), model.count()-1); - QTRY_COMPARE(listview->contentY(), 280.0); - - // hold down Key_Up - for (int i=model.count()-1; i > 0; i--) { - QTest::simulateEvent(canvas, true, Qt::Key_Up, Qt::NoModifier, "", true); - QTRY_COMPARE(listview->currentIndex(), i-1); - } - QTest::keyRelease(canvas, Qt::Key_Up); - QTRY_COMPARE(listview->currentIndex(), 0); - QTRY_COMPARE(listview->contentY(), 0.0); - - // turn off auto highlight listview->setHighlightFollowsCurrentItem(false); QVERIFY(listview->highlightFollowsCurrentItem() == false); @@ -2416,6 +2429,7 @@ QVERIFY(!listview->highlightItem()); QVERIFY(!listview->currentItem()); + // moving currentItem out of view should make it invisible listview->setCurrentIndex(0); QTRY_VERIFY(listview->currentItem()->isVisible()); listview->setContentY(200); @@ -2462,6 +2476,129 @@ delete canvas; } +void tst_QQuickListView::keyNavigation() +{ + QFETCH(QQuickListView::Orientation, orientation); + QFETCH(Qt::LayoutDirection, layoutDirection); + QFETCH(QQuickItemView::VerticalLayoutDirection, verticalLayoutDirection); + QFETCH(Qt::Key, forwardsKey); + QFETCH(Qt::Key, backwardsKey); + QFETCH(QPointF, contentPosAtFirstItem); + QFETCH(QPointF, contentPosAtLastItem); + + QmlListModel model; + for (int i = 0; i < 30; i++) + model.addItem("Item" + QString::number(i), ""); + + QQuickView *canvas = getView(); + TestObject *testObject = new TestObject; + canvas->rootContext()->setContextProperty("testModel", &model); + canvas->rootContext()->setContextProperty("testObject", testObject); + canvas->setSource(testFileUrl("listviewtest.qml")); + canvas->show(); + qApp->processEvents(); + + QQuickListView *listview = findItem(canvas->rootObject(), "list"); + QTRY_VERIFY(listview != 0); + + listview->setOrientation(orientation); + listview->setLayoutDirection(layoutDirection); + listview->setVerticalLayoutDirection(verticalLayoutDirection); + QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + + canvas->requestActivateWindow(); + QTRY_VERIFY(qGuiApp->focusWindow() == canvas); + QCOMPARE(listview->currentIndex(), 0); + + QTest::keyClick(canvas, forwardsKey); + QCOMPARE(listview->currentIndex(), 1); + + QTest::keyClick(canvas, backwardsKey); + QCOMPARE(listview->currentIndex(), 0); + + // hold down a key to go forwards + for (int i=0; icurrentIndex(), i+1); + } + QTest::keyRelease(canvas, forwardsKey); + QTRY_COMPARE(listview->currentIndex(), model.count()-1); + QTRY_COMPARE(listview->contentX(), contentPosAtLastItem.x()); + QTRY_COMPARE(listview->contentY(), contentPosAtLastItem.y()); + + // hold down a key to go backwards + for (int i=model.count()-1; i > 0; i--) { + QTest::simulateEvent(canvas, true, backwardsKey, Qt::NoModifier, "", true); + QTRY_COMPARE(listview->currentIndex(), i-1); + } + QTest::keyRelease(canvas, backwardsKey); + QTRY_COMPARE(listview->currentIndex(), 0); + QTRY_COMPARE(listview->contentX(), contentPosAtFirstItem.x()); + QTRY_COMPARE(listview->contentY(), contentPosAtFirstItem.y()); + + // no wrap + QVERIFY(!listview->isWrapEnabled()); + listview->incrementCurrentIndex(); + QCOMPARE(listview->currentIndex(), 1); + listview->decrementCurrentIndex(); + QCOMPARE(listview->currentIndex(), 0); + + listview->decrementCurrentIndex(); + QCOMPARE(listview->currentIndex(), 0); + + // with wrap + listview->setWrapEnabled(true); + QVERIFY(listview->isWrapEnabled()); + + listview->decrementCurrentIndex(); + QCOMPARE(listview->currentIndex(), model.count()-1); + QTRY_COMPARE(listview->contentX(), contentPosAtLastItem.x()); + QTRY_COMPARE(listview->contentY(), contentPosAtLastItem.y()); + + listview->incrementCurrentIndex(); + QCOMPARE(listview->currentIndex(), 0); + QTRY_COMPARE(listview->contentX(), contentPosAtFirstItem.x()); + QTRY_COMPARE(listview->contentY(), contentPosAtFirstItem.y()); + + releaseView(canvas); + delete testObject; +} + +void tst_QQuickListView::keyNavigation_data() +{ + QTest::addColumn("orientation"); + QTest::addColumn("layoutDirection"); + QTest::addColumn("verticalLayoutDirection"); + QTest::addColumn("forwardsKey"); + QTest::addColumn("backwardsKey"); + QTest::addColumn("contentPosAtFirstItem"); + QTest::addColumn("contentPosAtLastItem"); + + QTest::newRow("Vertical, TopToBottom") + << QQuickListView::Vertical << Qt::LeftToRight << QQuickItemView::TopToBottom + << Qt::Key_Down << Qt::Key_Up + << QPointF(0, 0) + << QPointF(0, 30*20 - 320); + + QTest::newRow("Vertical, BottomToTop") + << QQuickListView::Vertical << Qt::LeftToRight << QQuickItemView::BottomToTop + << Qt::Key_Up << Qt::Key_Down + << QPointF(0, -320) + << QPointF(0, -(30 * 20)); + + QTest::newRow("Horizontal, LeftToRight") + << QQuickListView::Horizontal << Qt::LeftToRight << QQuickItemView::TopToBottom + << Qt::Key_Right << Qt::Key_Left + << QPointF(0, 0) + << QPointF(30*240 - 240, 0); + + QTest::newRow("Horizontal, RightToLeft") + << QQuickListView::Horizontal << Qt::RightToLeft << QQuickItemView::TopToBottom + << Qt::Key_Left << Qt::Key_Right + << QPointF(-240, 0) + << QPointF(-(30 * 240), 0); +} + void tst_QQuickListView::itemList() { QQuickView *canvas = createView(); @@ -3083,11 +3220,12 @@ { QFETCH(QQuickListView::Orientation, orientation); QFETCH(Qt::LayoutDirection, layoutDirection); + QFETCH(QQuickItemView::VerticalLayoutDirection, verticalLayoutDirection); QFETCH(QPointF, initialHeaderPos); - QFETCH(QPointF, firstDelegatePos); - QFETCH(QPointF, initialContentPos); QFETCH(QPointF, changedHeaderPos); + QFETCH(QPointF, initialContentPos); QFETCH(QPointF, changedContentPos); + QFETCH(QPointF, firstDelegatePos); QFETCH(QPointF, resizeContentPos); QmlListModel model; @@ -3106,6 +3244,8 @@ QTRY_VERIFY(listview != 0); listview->setOrientation(orientation); listview->setLayoutDirection(layoutDirection); + listview->setVerticalLayoutDirection(verticalLayoutDirection); + QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); QQuickItem *contentItem = listview->contentItem(); QTRY_VERIFY(contentItem != 0); @@ -3156,6 +3296,11 @@ QVERIFY(item); QCOMPARE(item->pos(), firstDelegatePos); + listview->positionViewAtBeginning(); + header->setHeight(10); + header->setWidth(40); + QTRY_COMPARE(QPointF(listview->contentX(), listview->contentY()), resizeContentPos); + releaseView(canvas); @@ -3173,6 +3318,7 @@ QTRY_VERIFY(listview != 0); listview->setOrientation(orientation); listview->setLayoutDirection(layoutDirection); + listview->setVerticalLayoutDirection(verticalLayoutDirection); QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); listview->setWidth(240); @@ -3187,6 +3333,7 @@ { QTest::addColumn("orientation"); QTest::addColumn("layoutDirection"); + QTest::addColumn("verticalLayoutDirection"); QTest::addColumn("initialHeaderPos"); QTest::addColumn("changedHeaderPos"); QTest::addColumn("initialContentPos"); @@ -3196,11 +3343,11 @@ // header1 = 100 x 30 // header2 = 50 x 20 - // delegates = 240 x 20 + // delegates = 240 x 30 // view width = 240 // header above items, top left - QTest::newRow("vertical, left to right") << QQuickListView::Vertical << Qt::LeftToRight + QTest::newRow("vertical, left to right") << QQuickListView::Vertical << Qt::LeftToRight << QQuickItemView::TopToBottom << QPointF(0, -30) << QPointF(0, -20) << QPointF(0, -30) @@ -3209,7 +3356,7 @@ << QPointF(0, -10); // header above items, top right - QTest::newRow("vertical, layout right to left") << QQuickListView::Vertical << Qt::RightToLeft + QTest::newRow("vertical, layout right to left") << QQuickListView::Vertical << Qt::RightToLeft << QQuickItemView::TopToBottom << QPointF(0, -30) << QPointF(0, -20) << QPointF(0, -30) @@ -3218,7 +3365,7 @@ << QPointF(0, -10); // header to left of items - QTest::newRow("horizontal, layout left to right") << QQuickListView::Horizontal << Qt::LeftToRight + QTest::newRow("horizontal, layout left to right") << QQuickListView::Horizontal << Qt::LeftToRight << QQuickItemView::TopToBottom << QPointF(-100, 0) << QPointF(-50, 0) << QPointF(-100, 0) @@ -3227,13 +3374,22 @@ << QPointF(-40, 0); // header to right of items - QTest::newRow("horizontal, layout right to left") << QQuickListView::Horizontal << Qt::RightToLeft + QTest::newRow("horizontal, layout right to left") << QQuickListView::Horizontal << Qt::RightToLeft << QQuickItemView::TopToBottom << QPointF(0, 0) << QPointF(0, 0) << QPointF(-240 + 100, 0) << QPointF(-240 + 50, 0) << QPointF(-240, 0) << QPointF(-240 + 40, 0); + + // header below items + QTest::newRow("vertical, bottom to top") << QQuickListView::Vertical << Qt::LeftToRight << QQuickItemView::BottomToTop + << QPointF(0, 0) + << QPointF(0, 0) + << QPointF(0, -320 + 30) + << QPointF(0, -320 + 20) + << QPointF(0, -30) + << QPointF(0, -320 + 10); } void tst_QQuickListView::header_delayItemCreation() @@ -3268,6 +3424,7 @@ { QFETCH(QQuickListView::Orientation, orientation); QFETCH(Qt::LayoutDirection, layoutDirection); + QFETCH(QQuickItemView::VerticalLayoutDirection, verticalLayoutDirection); QFETCH(QPointF, initialFooterPos); QFETCH(QPointF, firstDelegatePos); QFETCH(QPointF, initialContentPos); @@ -3292,6 +3449,7 @@ QTRY_VERIFY(listview != 0); listview->setOrientation(orientation); listview->setLayoutDirection(layoutDirection); + listview->setVerticalLayoutDirection(verticalLayoutDirection); QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); QQuickItem *contentItem = listview->contentItem(); @@ -3320,7 +3478,8 @@ model.removeItem(1); if (orientation == QQuickListView::Vertical) { - QTRY_COMPARE(footer->y(), initialFooterPos.y() - 20); // delegate height = 20 + QTRY_COMPARE(footer->y(), verticalLayoutDirection == QQuickItemView::TopToBottom ? + initialFooterPos.y() - 20 : initialFooterPos.y() + 20); // delegate width = 40 } else { QTRY_COMPARE(footer->x(), layoutDirection == Qt::LeftToRight ? initialFooterPos.x() - 40 : initialFooterPos.x() + 40); // delegate width = 40 @@ -3332,6 +3491,8 @@ QPointF posWhenNoItems(0, 0); if (orientation == QQuickListView::Horizontal && layoutDirection == Qt::RightToLeft) posWhenNoItems.setX(-100); + else if (orientation == QQuickListView::Vertical && verticalLayoutDirection == QQuickItemView::BottomToTop) + posWhenNoItems.setY(-30); QTRY_COMPARE(footer->pos(), posWhenNoItems); // if header is present, it's at a negative pos, so the footer should not move @@ -3376,6 +3537,7 @@ { QTest::addColumn("orientation"); QTest::addColumn("layoutDirection"); + QTest::addColumn("verticalLayoutDirection"); QTest::addColumn("initialFooterPos"); QTest::addColumn("changedFooterPos"); QTest::addColumn("initialContentPos"); @@ -3390,7 +3552,7 @@ // view height = 320 // footer below items, bottom left - QTest::newRow("vertical, layout left to right") << QQuickListView::Vertical << Qt::LeftToRight + QTest::newRow("vertical, layout left to right") << QQuickListView::Vertical << Qt::LeftToRight << QQuickItemView::TopToBottom << QPointF(0, 3 * 20) << QPointF(0, 30 * 20) // added 30 items << QPointF(0, 0) @@ -3399,7 +3561,7 @@ << QPointF(0, 30 * 20 - 320 + 10); // footer below items, bottom right - QTest::newRow("vertical, layout right to left") << QQuickListView::Vertical << Qt::RightToLeft + QTest::newRow("vertical, layout right to left") << QQuickListView::Vertical << Qt::RightToLeft << QQuickItemView::TopToBottom << QPointF(0, 3 * 20) << QPointF(0, 30 * 20) << QPointF(0, 0) @@ -3408,7 +3570,7 @@ << QPointF(0, 30 * 20 - 320 + 10); // footer to right of items - QTest::newRow("horizontal, layout left to right") << QQuickListView::Horizontal << Qt::LeftToRight + QTest::newRow("horizontal, layout left to right") << QQuickListView::Horizontal << Qt::LeftToRight << QQuickItemView::TopToBottom << QPointF(40 * 3, 0) << QPointF(40 * 30, 0) << QPointF(0, 0) @@ -3417,13 +3579,22 @@ << QPointF(40 * 30 - 240 + 40, 0); // footer to left of items - QTest::newRow("horizontal, layout right to left") << QQuickListView::Horizontal << Qt::RightToLeft + QTest::newRow("horizontal, layout right to left") << QQuickListView::Horizontal << Qt::RightToLeft << QQuickItemView::TopToBottom << QPointF(-(40 * 3) - 100, 0) << QPointF(-(40 * 30) - 50, 0) // 50 = new footer width << QPointF(-240, 0) << QPointF(-240, 0) << QPointF(-40, 0) << QPointF(-(40 * 30) - 40, 0); + + // footer above items + QTest::newRow("vertical, layout left to right") << QQuickListView::Vertical << Qt::LeftToRight << QQuickItemView::BottomToTop + << QPointF(0, -(3 * 20) - 30) + << QPointF(0, -(30 * 20) - 20) + << QPointF(0, -320) + << QPointF(0, -320) + << QPointF(0, -20) + << QPointF(0, -(30 * 20) - 10); } class LVAccessor : public QQuickListView @@ -3435,140 +3606,127 @@ qreal maxX() const { return maxXExtent(); } }; + void tst_QQuickListView::headerFooter() { - { - // Vertical - QQuickView *canvas = createView(); - - QmlListModel model; - QQmlContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - - canvas->setSource(testFileUrl("headerfooter.qml")); - qApp->processEvents(); - - QQuickListView *listview = qobject_cast(canvas->rootObject()); - QTRY_VERIFY(listview != 0); - - QQuickItem *contentItem = listview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - QQuickItem *header = findItem(contentItem, "header"); - QVERIFY(header); - QCOMPARE(header->y(), -header->height()); - - QQuickItem *footer = findItem(contentItem, "footer"); - QVERIFY(footer); - QCOMPARE(footer->y(), 0.); - - QCOMPARE(static_cast(listview)->minY(), header->height()); - QCOMPARE(static_cast(listview)->maxY(), header->height()); + QFETCH(QQuickListView::Orientation, orientation); + QFETCH(Qt::LayoutDirection, layoutDirection); + QFETCH(QQuickItemView::VerticalLayoutDirection, verticalLayoutDirection); + QFETCH(QPointF, headerPos); + QFETCH(QPointF, footerPos); + QFETCH(QPointF, minPos); + QFETCH(QPointF, maxPos); - delete canvas; - } - { - // Horizontal - QQuickView *canvas = createView(); + QQuickView *canvas = getView(); - QmlListModel model; - QQmlContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); + QmlListModel model; + QQmlContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + canvas->setSource(testFileUrl("headerfooter.qml")); + canvas->show(); + qApp->processEvents(); - canvas->setSource(testFileUrl("headerfooter.qml")); - canvas->rootObject()->setProperty("horizontal", true); - qApp->processEvents(); + QQuickListView *listview = qobject_cast(canvas->rootObject()); + QTRY_VERIFY(listview != 0); + listview->setOrientation(orientation); + listview->setLayoutDirection(layoutDirection); + listview->setVerticalLayoutDirection(verticalLayoutDirection); + QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); - QQuickListView *listview = qobject_cast(canvas->rootObject()); - QTRY_VERIFY(listview != 0); + QQuickItem *contentItem = listview->contentItem(); + QTRY_VERIFY(contentItem != 0); - QQuickItem *contentItem = listview->contentItem(); - QTRY_VERIFY(contentItem != 0); + QQuickItem *header = findItem(contentItem, "header"); + QVERIFY(header); + QCOMPARE(header->pos(), headerPos); - QQuickItem *header = findItem(contentItem, "header"); - QVERIFY(header); - QCOMPARE(header->x(), -header->width()); + QQuickItem *footer = findItem(contentItem, "footer"); + QVERIFY(footer); + QCOMPARE(footer->pos(), footerPos); - QQuickItem *footer = findItem(contentItem, "footer"); - QVERIFY(footer); - QCOMPARE(footer->x(), 0.); + QCOMPARE(static_cast(listview)->minX(), minPos.x()); + QCOMPARE(static_cast(listview)->minY(), minPos.y()); + QCOMPARE(static_cast(listview)->maxX(), maxPos.x()); + QCOMPARE(static_cast(listview)->maxY(), maxPos.y()); - QCOMPARE(static_cast(listview)->minX(), header->width()); - QCOMPARE(static_cast(listview)->maxX(), header->width()); + releaseView(canvas); +} - delete canvas; - } - { - // Horizontal RTL - QQuickView *canvas = createView(); +void tst_QQuickListView::headerFooter_data() +{ + QTest::addColumn("orientation"); + QTest::addColumn("layoutDirection"); + QTest::addColumn("verticalLayoutDirection"); + QTest::addColumn("headerPos"); + QTest::addColumn("footerPos"); + QTest::addColumn("minPos"); + QTest::addColumn("maxPos"); - QmlListModel model; - QQmlContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); + // header is 240x20 (or 20x320 in Horizontal orientation) + // footer is 240x30 (or 30x320 in Horizontal orientation) - canvas->setSource(testFileUrl("headerfooter.qml")); - canvas->rootObject()->setProperty("horizontal", true); - canvas->rootObject()->setProperty("rtl", true); - qApp->processEvents(); + QTest::newRow("Vertical, TopToBottom") + << QQuickListView::Vertical << Qt::LeftToRight << QQuickItemView::TopToBottom + << QPointF(0, -20) << QPointF(0, 0) + << QPointF(0, 20) << QPointF(240, 20); - QQuickListView *listview = qobject_cast(canvas->rootObject()); - QTRY_VERIFY(listview != 0); + QTest::newRow("Vertical, BottomToTop") + << QQuickListView::Vertical << Qt::LeftToRight << QQuickItemView::BottomToTop + << QPointF(0, 0) << QPointF(0, -30) + << QPointF(0, 320 - 20) << QPointF(240, 320 - 20); // content flow is reversed - QQuickItem *contentItem = listview->contentItem(); - QTRY_VERIFY(contentItem != 0); - QQuickItem *header = findItem(contentItem, "header"); - QVERIFY(header); - QCOMPARE(header->x(), 0.); + QTest::newRow("Horizontal, LeftToRight") + << QQuickListView::Horizontal << Qt::LeftToRight << QQuickItemView::TopToBottom + << QPointF(-20, 0) << QPointF(0, 0) + << QPointF(20, 0) << QPointF(20, 320); - QQuickItem *footer = findItem(contentItem, "footer"); - QVERIFY(footer); - QCOMPARE(footer->x(), -footer->width()); + QTest::newRow("Horizontal, RightToLeft") + << QQuickListView::Horizontal << Qt::RightToLeft << QQuickItemView::TopToBottom + << QPointF(0, 0) << QPointF(-30, 0) + << QPointF(240 - 20, 0) << QPointF(240 - 20, 320); // content flow is reversed +} - QCOMPARE(static_cast(listview)->minX(), 240. - header->width()); - QCOMPARE(static_cast(listview)->maxX(), 240. - header->width()); +void tst_QQuickListView::resetModel_headerFooter() +{ + // Resetting a model shouldn't crash in views with header/footer - delete canvas; - } - { - // Reset model - QQuickView *canvas = createView(); + QQuickView *canvas = createView(); - QaimModel model; - for (int i = 0; i < 4; i++) - model.addItem("Item" + QString::number(i), ""); - QQmlContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); + QaimModel model; + for (int i = 0; i < 4; i++) + model.addItem("Item" + QString::number(i), ""); + QQmlContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); - canvas->setSource(testFileUrl("headerfooter.qml")); - qApp->processEvents(); + canvas->setSource(testFileUrl("headerfooter.qml")); + qApp->processEvents(); - QQuickListView *listview = qobject_cast(canvas->rootObject()); - QTRY_VERIFY(listview != 0); + QQuickListView *listview = qobject_cast(canvas->rootObject()); + QTRY_VERIFY(listview != 0); - QQuickItem *contentItem = listview->contentItem(); - QTRY_VERIFY(contentItem != 0); + QQuickItem *contentItem = listview->contentItem(); + QTRY_VERIFY(contentItem != 0); - QQuickItem *header = findItem(contentItem, "header"); - QVERIFY(header); - QCOMPARE(header->y(), -header->height()); + QQuickItem *header = findItem(contentItem, "header"); + QVERIFY(header); + QCOMPARE(header->y(), -header->height()); - QQuickItem *footer = findItem(contentItem, "footer"); - QVERIFY(footer); - QCOMPARE(footer->y(), 30.*4); + QQuickItem *footer = findItem(contentItem, "footer"); + QVERIFY(footer); + QCOMPARE(footer->y(), 30.*4); - model.reset(); + model.reset(); - header = findItem(contentItem, "header"); - QVERIFY(header); - QCOMPARE(header->y(), -header->height()); + header = findItem(contentItem, "header"); + QVERIFY(header); + QCOMPARE(header->y(), -header->height()); - footer = findItem(contentItem, "footer"); - QVERIFY(footer); - QCOMPARE(footer->y(), 30.*4); + footer = findItem(contentItem, "footer"); + QVERIFY(footer); + QCOMPARE(footer->y(), 30.*4); - delete canvas; - } + delete canvas; } void tst_QQuickListView::resizeView() @@ -4288,13 +4446,14 @@ { QFETCH(QQuickListView::Orientation, orientation); QFETCH(Qt::LayoutDirection, layoutDirection); + QFETCH(QQuickItemView::VerticalLayoutDirection, verticalLayoutDirection); QFETCH(qreal, start); QFETCH(qreal, end); QPoint flickStart(20, 20); QPoint flickEnd(20, 20); if (orientation == QQuickListView::Vertical) - flickStart.ry() += 180; + flickStart.ry() += (verticalLayoutDirection == QQuickItemView::TopToBottom) ? 180 : -180; else flickStart.rx() += (layoutDirection == Qt::LeftToRight) ? 180 : -180; @@ -4309,6 +4468,7 @@ listview->setOrientation(orientation); listview->setLayoutDirection(layoutDirection); + listview->setVerticalLayoutDirection(verticalLayoutDirection); QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); // view is resized after componentCompleted - top margin should still be visible @@ -4354,20 +4514,34 @@ { QTest::addColumn("orientation"); QTest::addColumn("layoutDirection"); + QTest::addColumn("verticalLayoutDirection"); QTest::addColumn("start"); QTest::addColumn("end"); // in Right to Left mode, leftMargin still means leftMargin - it doesn't reverse to mean rightMargin - QTest::newRow("vertical") << QQuickListView::Vertical << Qt::LeftToRight << -40.0 << 1020.0; - QTest::newRow("horizontal") << QQuickListView::Horizontal << Qt::LeftToRight << -40.0 << 1020.0; - QTest::newRow("horizontal, rtl") << QQuickListView::Horizontal << Qt::RightToLeft << -180.0 << -1240.0; + QTest::newRow("vertical") + << QQuickListView::Vertical << Qt::LeftToRight << QQuickItemView::TopToBottom + << -40.0 << 1020.0; + + QTest::newRow("vertical, BottomToTop") + << QQuickListView::Vertical << Qt::LeftToRight << QQuickItemView::BottomToTop + << -180.0 << -1240.0; + + QTest::newRow("horizontal") + << QQuickListView::Horizontal<< Qt::LeftToRight << QQuickItemView::TopToBottom + << -40.0 << 1020.0; + + QTest::newRow("horizontal, rtl") + << QQuickListView::Horizontal << Qt::RightToLeft << QQuickItemView::TopToBottom + << -180.0 << -1240.0; } void tst_QQuickListView::snapToItem_data() { QTest::addColumn("orientation"); QTest::addColumn("layoutDirection"); + QTest::addColumn("verticalLayoutDirection"); QTest::addColumn("highlightRangeMode"); QTest::addColumn("flickStart"); QTest::addColumn("flickEnd"); @@ -4375,22 +4549,36 @@ QTest::addColumn("endExtent"); QTest::addColumn("startExtent"); - QTest::newRow("vertical, left to right") << QQuickListView::Vertical << Qt::LeftToRight << int(QQuickItemView::NoHighlightRange) + QTest::newRow("vertical, top to bottom") + << QQuickListView::Vertical << Qt::LeftToRight << QQuickItemView::TopToBottom << int(QQuickItemView::NoHighlightRange) << QPoint(20, 200) << QPoint(20, 20) << 60.0 << 560.0 << 0.0; - QTest::newRow("horizontal, left to right") << QQuickListView::Horizontal << Qt::LeftToRight << int(QQuickItemView::NoHighlightRange) + QTest::newRow("vertical, bottom to top") + << QQuickListView::Vertical << Qt::LeftToRight << QQuickItemView::BottomToTop << int(QQuickItemView::NoHighlightRange) + << QPoint(20, 20) << QPoint(20, 200) << -60.0 << -560.0 - 240.0 << -240.0; + + QTest::newRow("horizontal, left to right") + << QQuickListView::Horizontal << Qt::LeftToRight << QQuickItemView::TopToBottom << int(QQuickItemView::NoHighlightRange) << QPoint(200, 20) << QPoint(20, 20) << 60.0 << 560.0 << 0.0; - QTest::newRow("horizontal, right to left") << QQuickListView::Horizontal << Qt::RightToLeft << int(QQuickItemView::NoHighlightRange) + QTest::newRow("horizontal, right to left") + << QQuickListView::Horizontal << Qt::RightToLeft << QQuickItemView::TopToBottom << int(QQuickItemView::NoHighlightRange) << QPoint(20, 20) << QPoint(200, 20) << -60.0 << -560.0 - 240.0 << -240.0; - QTest::newRow("vertical, left to right, enforce range") << QQuickListView::Vertical << Qt::LeftToRight << int(QQuickItemView::StrictlyEnforceRange) + QTest::newRow("vertical, top to bottom, enforce range") + << QQuickListView::Vertical << Qt::LeftToRight << QQuickItemView::TopToBottom << int(QQuickItemView::StrictlyEnforceRange) << QPoint(20, 200) << QPoint(20, 20) << 60.0 << 700.0 << -20.0; - QTest::newRow("horizontal, left to right, enforce range") << QQuickListView::Horizontal << Qt::LeftToRight << int(QQuickItemView::StrictlyEnforceRange) + QTest::newRow("vertical, bottom to top, enforce range") + << QQuickListView::Vertical << Qt::LeftToRight << QQuickItemView::BottomToTop << int(QQuickItemView::StrictlyEnforceRange) + << QPoint(20, 20) << QPoint(20, 200) << -60.0 << -560.0 - 240.0 - 140.0 << -220.0; + + QTest::newRow("horizontal, left to right, enforce range") + << QQuickListView::Horizontal << Qt::LeftToRight << QQuickItemView::TopToBottom << int(QQuickItemView::StrictlyEnforceRange) << QPoint(200, 20) << QPoint(20, 20) << 60.0 << 700.0 << -20.0; - QTest::newRow("horizontal, right to left, enforce range") << QQuickListView::Horizontal << Qt::RightToLeft << int(QQuickItemView::StrictlyEnforceRange) + QTest::newRow("horizontal, right to left, enforce range") + << QQuickListView::Horizontal << Qt::RightToLeft << QQuickItemView::TopToBottom << int(QQuickItemView::StrictlyEnforceRange) << QPoint(20, 20) << QPoint(200, 20) << -60.0 << -560.0 - 240.0 - 140.0 << -220.0; } @@ -4398,6 +4586,7 @@ { QFETCH(QQuickListView::Orientation, orientation); QFETCH(Qt::LayoutDirection, layoutDirection); + QFETCH(QQuickItemView::VerticalLayoutDirection, verticalLayoutDirection); QFETCH(int, highlightRangeMode); QFETCH(QPoint, flickStart); QFETCH(QPoint, flickEnd); @@ -4416,6 +4605,7 @@ listview->setOrientation(orientation); listview->setLayoutDirection(layoutDirection); + listview->setVerticalLayoutDirection(verticalLayoutDirection); listview->setHighlightRangeMode(QQuickItemView::HighlightRangeMode(highlightRangeMode)); QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); @@ -4435,7 +4625,7 @@ flick(canvas, flickStart, flickEnd, 180); QTRY_VERIFY(listview->isMoving() == false); // wait until it stops } while (orientation == QQuickListView::Vertical - ? !listview->isAtYEnd() + ? verticalLayoutDirection == QQuickItemView::TopToBottom ? !listview->isAtYEnd() : !listview->isAtYBeginning() : layoutDirection == Qt::LeftToRight ? !listview->isAtXEnd() : !listview->isAtXBeginning()); if (orientation == QQuickListView::Vertical) @@ -4448,7 +4638,7 @@ flick(canvas, flickEnd, flickStart, 180); QTRY_VERIFY(listview->isMoving() == false); // wait until it stops } while (orientation == QQuickListView::Vertical - ? !listview->isAtYBeginning() + ? verticalLayoutDirection == QQuickItemView::TopToBottom ? !listview->isAtYBeginning() : !listview->isAtYEnd() : layoutDirection == Qt::LeftToRight ? !listview->isAtXBeginning() : !listview->isAtXEnd()); if (orientation == QQuickListView::Vertical) @@ -4524,6 +4714,16 @@ inserted_more_data(); } +void tst_QQuickListView::qAbstractItemModel_inserted_more_bottomToTop() +{ + inserted_more(QQuickItemView::BottomToTop); +} + +void tst_QQuickListView::qAbstractItemModel_inserted_more_bottomToTop_data() +{ + inserted_more_data(); +} + void tst_QQuickListView::qListModelInterface_removed() { removed(testFileUrl("listviewtest.qml"), false); @@ -4562,6 +4762,16 @@ removed_more_data(); } +void tst_QQuickListView::qAbstractItemModel_removed_more_bottomToTop() +{ + removed_more(testFileUrl("listviewtest.qml"), QQuickItemView::BottomToTop); +} + +void tst_QQuickListView::qAbstractItemModel_removed_more_bottomToTop_data() +{ + removed_more_data(); +} + void tst_QQuickListView::qListModelInterface_moved() { moved(testFileUrl("listviewtest.qml")); @@ -4592,6 +4802,16 @@ moved_data(); } +void tst_QQuickListView::qAbstractItemModel_moved_bottomToTop() +{ + moved(testFileUrl("listviewtest-package.qml"), QQuickItemView::BottomToTop); +} + +void tst_QQuickListView::qAbstractItemModel_moved_bottomToTop_data() +{ + moved_data(); +} + void tst_QQuickListView::qListModelInterface_clear() { clear(testFileUrl("listviewtest.qml")); @@ -4607,6 +4827,11 @@ clear(testFileUrl("listviewtest.qml")); } +void tst_QQuickListView::qAbstractItemModel_clear_bottomToTop() +{ + clear(testFileUrl("listviewtest.qml"), QQuickItemView::BottomToTop); +} + void tst_QQuickListView::qListModelInterface_sections() { sections(testFileUrl("listview-sections.qml")); @@ -4705,6 +4930,7 @@ { QTest::addColumn("orientation"); QTest::addColumn("layoutDirection"); + QTest::addColumn("verticalLayoutDirection"); QTest::addColumn("highlightRangeMode"); QTest::addColumn("flickStart"); QTest::addColumn("flickEnd"); @@ -4712,22 +4938,36 @@ QTest::addColumn("endExtent"); QTest::addColumn("startExtent"); - QTest::newRow("vertical, left to right") << QQuickListView::Vertical << Qt::LeftToRight << int(QQuickItemView::NoHighlightRange) + QTest::newRow("vertical, top to bottom") + << QQuickListView::Vertical << Qt::LeftToRight << QQuickItemView::TopToBottom << int(QQuickItemView::NoHighlightRange) << QPoint(20, 200) << QPoint(20, 20) << 180.0 << 560.0 << 0.0; - QTest::newRow("horizontal, left to right") << QQuickListView::Horizontal << Qt::LeftToRight << int(QQuickItemView::NoHighlightRange) + QTest::newRow("vertical, bottom to top") + << QQuickListView::Vertical << Qt::LeftToRight << QQuickItemView::BottomToTop << int(QQuickItemView::NoHighlightRange) + << QPoint(20, 20) << QPoint(20, 200) << -420.0 << -560.0 - 240.0 << -240.0; + + QTest::newRow("horizontal, left to right") + << QQuickListView::Horizontal << Qt::LeftToRight << QQuickItemView::TopToBottom << int(QQuickItemView::NoHighlightRange) << QPoint(200, 20) << QPoint(20, 20) << 180.0 << 560.0 << 0.0; - QTest::newRow("horizontal, right to left") << QQuickListView::Horizontal << Qt::RightToLeft << int(QQuickItemView::NoHighlightRange) + QTest::newRow("horizontal, right to left") + << QQuickListView::Horizontal << Qt::RightToLeft << QQuickItemView::TopToBottom << int(QQuickItemView::NoHighlightRange) << QPoint(20, 20) << QPoint(200, 20) << -420.0 << -560.0 - 240.0 << -240.0; - QTest::newRow("vertical, left to right, enforce range") << QQuickListView::Vertical << Qt::LeftToRight << int(QQuickItemView::StrictlyEnforceRange) + QTest::newRow("vertical, top to bottom, enforce range") + << QQuickListView::Vertical << Qt::LeftToRight << QQuickItemView::TopToBottom << int(QQuickItemView::StrictlyEnforceRange) << QPoint(20, 200) << QPoint(20, 20) << 180.0 << 580.0 << -20.0; - QTest::newRow("horizontal, left to right, enforce range") << QQuickListView::Horizontal << Qt::LeftToRight << int(QQuickItemView::StrictlyEnforceRange) + QTest::newRow("vertical, bottom to top, enforce range") + << QQuickListView::Vertical << Qt::LeftToRight << QQuickItemView::BottomToTop << int(QQuickItemView::StrictlyEnforceRange) + << QPoint(20, 20) << QPoint(20, 200) << -420.0 << -580.0 - 240.0 << -220.0; + + QTest::newRow("horizontal, left to right, enforce range") + << QQuickListView::Horizontal << Qt::LeftToRight << QQuickItemView::TopToBottom << int(QQuickItemView::StrictlyEnforceRange) << QPoint(200, 20) << QPoint(20, 20) << 180.0 << 580.0 << -20.0; - QTest::newRow("horizontal, right to left, enforce range") << QQuickListView::Horizontal << Qt::RightToLeft << int(QQuickItemView::StrictlyEnforceRange) + QTest::newRow("horizontal, right to left, enforce range") + << QQuickListView::Horizontal << Qt::RightToLeft << QQuickItemView::TopToBottom << int(QQuickItemView::StrictlyEnforceRange) << QPoint(20, 20) << QPoint(200, 20) << -420.0 << -580.0 - 240.0 << -220.0; } @@ -4735,6 +4975,7 @@ { QFETCH(QQuickListView::Orientation, orientation); QFETCH(Qt::LayoutDirection, layoutDirection); + QFETCH(QQuickItemView::VerticalLayoutDirection, verticalLayoutDirection); QFETCH(int, highlightRangeMode); QFETCH(QPoint, flickStart); QFETCH(QPoint, flickEnd); @@ -4758,6 +4999,7 @@ listview->setOrientation(orientation); listview->setLayoutDirection(layoutDirection); + listview->setVerticalLayoutDirection(verticalLayoutDirection); listview->setHighlightRangeMode(QQuickItemView::HighlightRangeMode(highlightRangeMode)); QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); @@ -4784,7 +5026,7 @@ flick(canvas, flickStart, flickEnd, 180); QTRY_VERIFY(listview->isMoving() == false); // wait until it stops } while (orientation == QQuickListView::Vertical - ? !listview->isAtYEnd() + ? verticalLayoutDirection == QQuickItemView::TopToBottom ? !listview->isAtYEnd() : !listview->isAtYBeginning() : layoutDirection == Qt::LeftToRight ? !listview->isAtXEnd() : !listview->isAtXBeginning()); if (orientation == QQuickListView::Vertical) @@ -4802,7 +5044,7 @@ flick(canvas, flickEnd, flickStart, 180); QTRY_VERIFY(listview->isMoving() == false); // wait until it stops } while (orientation == QQuickListView::Vertical - ? !listview->isAtYBeginning() + ? verticalLayoutDirection == QQuickItemView::TopToBottom ? !listview->isAtYBeginning() : !listview->isAtYEnd() : layoutDirection == Qt::LeftToRight ? !listview->isAtXBeginning() : !listview->isAtXEnd()); if (orientation == QQuickListView::Vertical) @@ -6277,3 +6519,4 @@ #include "tst_qquicklistview.moc" + diff -Nru qt5-declarative-0.1~git20120402/tests/auto/quick/qquickloader/data/loadedSignal.2.qml qt5-declarative-0.1~git20120423/tests/auto/quick/qquickloader/data/loadedSignal.2.qml --- qt5-declarative-0.1~git20120402/tests/auto/quick/qquickloader/data/loadedSignal.2.qml 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/quick/qquickloader/data/loadedSignal.2.qml 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,31 @@ +import QtQuick 2.0 + +Item { + id: root + + width: 200 + height: 200 + + property bool success: true + property int loadCount: 0 + + Loader { + id: loader + anchors.fill: parent + asynchronous: true + active: false + source: "TestComponent.qml" + onLoaded: { + if (status !== Loader.Ready) { + root.success = false; + } + root.loadCount++; + } + } + + function triggerLoading() { + // we set source to a valid path (but which is an invalid / erroneous component) + // we should not get onLoaded, since the status should not be Ready. + loader.source = "GreenRect.qml" // causes reference error. + } +} diff -Nru qt5-declarative-0.1~git20120402/tests/auto/quick/qquickloader/data/loadedSignal.qml qt5-declarative-0.1~git20120423/tests/auto/quick/qquickloader/data/loadedSignal.qml --- qt5-declarative-0.1~git20120402/tests/auto/quick/qquickloader/data/loadedSignal.qml 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/quick/qquickloader/data/loadedSignal.qml 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,48 @@ +import QtQuick 2.0 + +Item { + id: root + + width: 200 + height: 200 + + property bool success: true + property int loadCount: 0 + + Loader { + id: loader + anchors.fill: parent + asynchronous: true + active: false + source: "TestComponent.qml" + onLoaded: { + if (status !== Loader.Ready) { + root.success = false; + } + root.loadCount++; + } + } + + function triggerLoading() { + // we set active to true, which triggers loading. + // we then immediately set active to false. + // this should clear the incubator and stop loading. + loader.active = true; + loader.active = false; + } + + function activate() { + loader.active = true; + } + + function deactivate() { + loader.active = false; + } + + function triggerMultipleLoad() { + loader.active = false; // deactivate as a precondition. + loader.source = "BlueRect.qml" + loader.active = true; // should trigger loading to begin + loader.source = "RedRect.qml"; // should clear the incubator and restart loading + } +} diff -Nru qt5-declarative-0.1~git20120402/tests/auto/quick/qquickloader/data/RedRect.qml qt5-declarative-0.1~git20120423/tests/auto/quick/qquickloader/data/RedRect.qml --- qt5-declarative-0.1~git20120402/tests/auto/quick/qquickloader/data/RedRect.qml 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/quick/qquickloader/data/RedRect.qml 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,8 @@ +import QtQuick 2.0 + +Rectangle { + objectName: "red" + width: 100 + height: 100 + color: "red" +} diff -Nru qt5-declarative-0.1~git20120402/tests/auto/quick/qquickloader/tst_qquickloader.cpp qt5-declarative-0.1~git20120423/tests/auto/quick/qquickloader/tst_qquickloader.cpp --- qt5-declarative-0.1~git20120402/tests/auto/quick/qquickloader/tst_qquickloader.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/quick/qquickloader/tst_qquickloader.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -92,7 +92,7 @@ void noResize(); void networkRequestUrl(); void failNetworkRequest(); -// void networkComponent(); + void networkComponent(); void active(); void initialPropertyValues_data(); void initialPropertyValues(); @@ -111,6 +111,7 @@ void asynchronous(); void asynchronous_clear(); void simultaneousSyncAsync(); + void loadedSignal(); void parented(); void sizeBound(); @@ -442,21 +443,21 @@ delete loader; } -/* XXX Component waits until all dependencies are loaded. Is this actually possible? +/* XXX Component waits until all dependencies are loaded. Is this actually possible? */ void tst_QQuickLoader::networkComponent() { TestHTTPServer server(SERVER_PORT); QVERIFY(server.isValid()); - server.serveDirectory("slowdata", TestHTTPServer::Delay); + server.serveDirectory(dataDirectory(), TestHTTPServer::Delay); QQmlComponent component(&engine); component.setData(QByteArray( "import QtQuick 2.0\n" "import \"http://127.0.0.1:14450/\" as NW\n" "Item {\n" - " Component { id: comp; NW.SlowRect {} }\n" + " Component { id: comp; NW.Rect120x60 {} }\n" " Loader { sourceComponent: comp } }") - , dataDirectoryUrl()); + , dataDirectory()); QQuickItem *item = qobject_cast(component.create()); QVERIFY(item); @@ -472,7 +473,6 @@ delete loader; } -*/ void tst_QQuickLoader::failNetworkRequest() { @@ -1000,6 +1000,47 @@ delete root; } +void tst_QQuickLoader::loadedSignal() +{ + { + // ensure that triggering loading (by setting active = true) + // and then immediately setting active to false, causes the + // loader to be deactivated, including disabling the incubator. + QQmlComponent component(&engine, testFileUrl("loadedSignal.qml")); + QObject *obj = component.create(); + + QMetaObject::invokeMethod(obj, "triggerLoading"); + QTest::qWait(100); // ensure that loading would have finished if it wasn't deactivated + QCOMPARE(obj->property("loadCount").toInt(), 0); + QVERIFY(obj->property("success").toBool()); + + QMetaObject::invokeMethod(obj, "triggerLoading"); + QTest::qWait(100); + QCOMPARE(obj->property("loadCount").toInt(), 0); + QVERIFY(obj->property("success").toBool()); + + QMetaObject::invokeMethod(obj, "triggerMultipleLoad"); + QTest::qWait(100); + QCOMPARE(obj->property("loadCount").toInt(), 1); // only one loaded signal should be emitted. + QVERIFY(obj->property("success").toBool()); + + delete obj; + } + + { + // ensure that an error doesn't result in the onLoaded signal being emitted. + QQmlComponent component(&engine, testFileUrl("loadedSignal.2.qml")); + QObject *obj = component.create(); + + QMetaObject::invokeMethod(obj, "triggerLoading"); + QTest::qWait(100); + QCOMPARE(obj->property("loadCount").toInt(), 0); + QVERIFY(obj->property("success").toBool()); + + delete obj; + } +} + void tst_QQuickLoader::parented() { QQmlComponent component(&engine, testFileUrl("parented.qml")); diff -Nru qt5-declarative-0.1~git20120402/tests/auto/quick/qquickpathview/data/panels.qml qt5-declarative-0.1~git20120423/tests/auto/quick/qquickpathview/data/panels.qml --- qt5-declarative-0.1~git20120402/tests/auto/quick/qquickpathview/data/panels.qml 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/quick/qquickpathview/data/panels.qml 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,44 @@ +import QtQuick 2.0 + +Item { + id: root + property bool snapOne: false + property bool enforceRange: false + width: 320; height: 480 + + VisualItemModel { + id: itemModel + + Rectangle { + width: root.width + height: root.height + color: "blue" + } + Rectangle { + width: root.width + height: root.height + color: "yellow" + } + Rectangle { + width: root.width + height: root.height + color: "green" + } + } + + PathView { + id: view + objectName: "view" + anchors.fill: parent + model: itemModel + preferredHighlightBegin: 0.5 + preferredHighlightEnd: 0.5 + flickDeceleration: 30 + highlightRangeMode: enforceRange ? PathView.StrictlyEnforceRange : PathView.NoHighlightRange + snapMode: root.snapOne ? PathView.SnapOneItem : PathView.SnapToItem + path: Path { + startX: -root.width; startY: root.height/2 + PathLine { x: root.width*2; y: root.height/2 } + } + } +} diff -Nru qt5-declarative-0.1~git20120402/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp qt5-declarative-0.1~git20120423/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp --- qt5-declarative-0.1~git20120402/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -125,6 +125,10 @@ void asynchronous(); void cancelDrag(); void maximumFlickVelocity(); + void snapToItem(); + void snapToItem_data(); + void snapOneItem(); + void snapOneItem_data(); }; class TestObject : public QObject @@ -1541,6 +1545,89 @@ delete canvas; } +void tst_QQuickPathView::snapToItem() +{ + QFETCH(bool, enforceRange); + + QQuickView *canvas = createView(); + canvas->setSource(testFileUrl("panels.qml")); + QQuickPathView *pathview = canvas->rootObject()->findChild("view"); + QVERIFY(pathview != 0); + + canvas->rootObject()->setProperty("enforceRange", enforceRange); + QTRY_VERIFY(!pathview->isMoving()); // ensure stable + + int currentIndex = pathview->currentIndex(); + + QSignalSpy snapModeSpy(pathview, SIGNAL(snapModeChanged())); + + flick(canvas, QPoint(200,10), QPoint(10,10), 180); + + QVERIFY(pathview->isMoving()); + QTRY_VERIFY(!pathview->isMoving()); + + QVERIFY(pathview->offset() == qFloor(pathview->offset())); + + if (enforceRange) + QVERIFY(pathview->currentIndex() != currentIndex); + else + QVERIFY(pathview->currentIndex() == currentIndex); +} + +void tst_QQuickPathView::snapToItem_data() +{ + QTest::addColumn("enforceRange"); + + QTest::newRow("no enforce range") << false; + QTest::newRow("enforce range") << true; +} + +void tst_QQuickPathView::snapOneItem() +{ + QFETCH(bool, enforceRange); + + QQuickView *canvas = createView(); + canvas->setSource(testFileUrl("panels.qml")); + canvas->show(); + canvas->requestActivateWindow(); + QTest::qWaitForWindowShown(canvas); + QTRY_COMPARE(canvas, qGuiApp->focusWindow()); + + QQuickPathView *pathview = canvas->rootObject()->findChild("view"); + QVERIFY(pathview != 0); + + canvas->rootObject()->setProperty("enforceRange", enforceRange); + + QSignalSpy snapModeSpy(pathview, SIGNAL(snapModeChanged())); + + canvas->rootObject()->setProperty("snapOne", true); + QVERIFY(snapModeSpy.count() == 1); + QTRY_VERIFY(!pathview->isMoving()); // ensure stable + + int currentIndex = pathview->currentIndex(); + + double startOffset = pathview->offset(); + flick(canvas, QPoint(200,10), QPoint(10,10), 180); + + QVERIFY(pathview->isMoving()); + QTRY_VERIFY(!pathview->isMoving()); + + // must have moved only one item + QCOMPARE(pathview->offset(), fmodf(3.0 + startOffset - 1.0, 3.0)); + + if (enforceRange) + QVERIFY(pathview->currentIndex() == currentIndex+1); + else + QVERIFY(pathview->currentIndex() == currentIndex); +} + +void tst_QQuickPathView::snapOneItem_data() +{ + QTest::addColumn("enforceRange"); + + QTest::newRow("no enforce range") << false; + QTest::newRow("enforce range") << true; +} QTEST_MAIN(tst_QQuickPathView) diff -Nru qt5-declarative-0.1~git20120402/tests/auto/quick/qquickpixmapcache/qquickpixmapcache.pro qt5-declarative-0.1~git20120423/tests/auto/quick/qquickpixmapcache/qquickpixmapcache.pro --- qt5-declarative-0.1~git20120402/tests/auto/quick/qquickpixmapcache/qquickpixmapcache.pro 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/quick/qquickpixmapcache/qquickpixmapcache.pro 2012-04-23 11:44:59.000000000 +0000 @@ -15,6 +15,6 @@ # LIBS += -lgcov CONFIG += parallel_test -CONFIG += insignificant_test +CONFIG += insignificant_test # QTBUG-25307 QT += core-private gui-private qml-private quick-private network testlib concurrent diff -Nru qt5-declarative-0.1~git20120402/tests/auto/quick/qquickshadereffect/data/deleteShaderEffectSource.qml qt5-declarative-0.1~git20120423/tests/auto/quick/qquickshadereffect/data/deleteShaderEffectSource.qml --- qt5-declarative-0.1~git20120402/tests/auto/quick/qquickshadereffect/data/deleteShaderEffectSource.qml 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/quick/qquickshadereffect/data/deleteShaderEffectSource.qml 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 +import QtQuick.Particles 2.0 + +Rectangle { + color: "black" + width: 320 + height: 320 + + ShaderEffect { + id: sei + property variant source + } + + ShaderEffectSource { + id: doomed + hideSource: true + sourceItem: Image { + source: "star.png" + } + } + + function setDeletedShaderEffectSource() { + sei.source = doomed; + doomed.destroy(); + // now set a fragment shader to trigger source texture detection. + sei.fragmentShader = "varying highp vec2 qt_TexCoord0;\ + uniform sampler2D source;\ + uniform lowp float qt_Opacity;\ + void main() {\ + gl_FragColor = texture2D(source, qt_TexCoord0) * qt_Opacity;\ + }"; + } +} diff -Nru qt5-declarative-0.1~git20120402/tests/auto/quick/qquickshadereffect/data/deleteSourceItem.qml qt5-declarative-0.1~git20120423/tests/auto/quick/qquickshadereffect/data/deleteSourceItem.qml --- qt5-declarative-0.1~git20120402/tests/auto/quick/qquickshadereffect/data/deleteSourceItem.qml 1970-01-01 00:00:00.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/quick/qquickshadereffect/data/deleteSourceItem.qml 2012-04-23 11:32:40.000000000 +0000 @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 +import QtQuick.Particles 2.0 + +Rectangle { + color: "black" + width: 320 + height: 320 + + ShaderEffect { + id: sei + property variant source + } + + ShaderEffectSource { + id: doomedses + hideSource: true + sourceItem: Image { + id: doomed + source: "star.png" + } + } + + function setDeletedSourceItem() { + doomed.destroy(); + sei.source = doomedses; + // now set a fragment shader to trigger source texture detection. + sei.fragmentShader = "varying highp vec2 qt_TexCoord0;\ + uniform sampler2D source;\ + uniform lowp float qt_Opacity;\ + void main() {\ + gl_FragColor = texture2D(source, qt_TexCoord0) * qt_Opacity;\ + }"; + } +} Binary files /tmp/39TcBOrOwX/qt5-declarative-0.1~git20120402/tests/auto/quick/qquickshadereffect/data/star.png and /tmp/4OL5ZoauBZ/qt5-declarative-0.1~git20120423/tests/auto/quick/qquickshadereffect/data/star.png differ diff -Nru qt5-declarative-0.1~git20120402/tests/auto/quick/qquickshadereffect/qquickshadereffect.pro qt5-declarative-0.1~git20120423/tests/auto/quick/qquickshadereffect/qquickshadereffect.pro --- qt5-declarative-0.1~git20120402/tests/auto/quick/qquickshadereffect/qquickshadereffect.pro 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/quick/qquickshadereffect/qquickshadereffect.pro 2012-04-23 11:32:40.000000000 +0000 @@ -2,6 +2,7 @@ TARGET = tst_qquickshadereffect SOURCES += tst_qquickshadereffect.cpp +include (../../shared/util.pri) macx:CONFIG -= app_bundle CONFIG += parallel_test diff -Nru qt5-declarative-0.1~git20120402/tests/auto/quick/qquickshadereffect/tst_qquickshadereffect.cpp qt5-declarative-0.1~git20120423/tests/auto/quick/qquickshadereffect/tst_qquickshadereffect.cpp --- qt5-declarative-0.1~git20120402/tests/auto/quick/qquickshadereffect/tst_qquickshadereffect.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/quick/qquickshadereffect/tst_qquickshadereffect.cpp 2012-04-23 11:32:40.000000000 +0000 @@ -45,6 +45,10 @@ #include #include +#include +#include "../../shared/util.h" + + class TestShaderEffect : public QQuickShaderEffect { Q_OBJECT @@ -68,7 +72,7 @@ QList m_signals; }; -class tst_qquickshadereffect : public QObject +class tst_qquickshadereffect : public QQmlDataTest { Q_OBJECT public: @@ -81,6 +85,9 @@ void lookThroughShaderCode_data(); void lookThroughShaderCode(); + void deleteSourceItem(); + void deleteShaderEffectSource(); + private: enum PresenceFlags { VertexPresent = 0x01, @@ -97,6 +104,7 @@ void tst_qquickshadereffect::initTestCase() { + QQmlDataTest::initTestCase(); } void tst_qquickshadereffect::cleanupTestCase() @@ -257,19 +265,48 @@ if ((presenceFlags & TexCoordPresent) == 0) expected += "Warning: Missing reference to \'qt_MultiTexCoord0\'.\n"; if ((presenceFlags & MatrixPresent) == 0) - expected += "Warning: Missing reference to \'qt_Matrix\'.\n"; + expected += "Warning: Vertex shader is missing reference to \'qt_Matrix\'.\n"; if ((presenceFlags & OpacityPresent) == 0) - expected += "Warning: Missing reference to \'qt_Opacity\'.\n"; + expected += "Warning: Shaders are missing reference to \'qt_Opacity\'.\n"; item.setVertexShader(vertexShader); item.setFragmentShader(fragmentShader); - item.ensureCompleted(); QCOMPARE(item.parseLog(), expected); // If the uniform was successfully parsed, the notify signal has been connected to an update slot. QCOMPARE(item.isConnected(SIGNAL(dummyChanged())), (presenceFlags & PropertyPresent) != 0); } +void tst_qquickshadereffect::deleteSourceItem() +{ + // purely to ensure that deleting the sourceItem of a shader doesn't cause a crash + QQuickView *view = new QQuickView(0); + view->setSource(QUrl::fromLocalFile(testFile("deleteSourceItem.qml"))); + view->show(); + QTest::qWaitForWindowShown(view); + QVERIFY(view); + QObject *obj = view->rootObject(); + QVERIFY(obj); + QMetaObject::invokeMethod(obj, "setDeletedSourceItem"); + QTest::qWait(50); + delete view; +} + +void tst_qquickshadereffect::deleteShaderEffectSource() +{ + // purely to ensure that deleting the sourceItem of a shader doesn't cause a crash + QQuickView *view = new QQuickView(0); + view->setSource(QUrl::fromLocalFile(testFile("deleteShaderEffectSource.qml"))); + view->show(); + QTest::qWaitForWindowShown(view); + QVERIFY(view); + QObject *obj = view->rootObject(); + QVERIFY(obj); + QMetaObject::invokeMethod(obj, "setDeletedShaderEffectSource"); + QTest::qWait(50); + delete view; +} + QTEST_MAIN(tst_qquickshadereffect) #include "tst_qquickshadereffect.moc" diff -Nru qt5-declarative-0.1~git20120402/tests/auto/quick/qquicktext/tst_qquicktext.cpp qt5-declarative-0.1~git20120423/tests/auto/quick/qquicktext/tst_qquicktext.cpp --- qt5-declarative-0.1~git20120402/tests/auto/quick/qquicktext/tst_qquicktext.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/quick/qquicktext/tst_qquicktext.cpp 2012-04-23 11:44:59.000000000 +0000 @@ -131,6 +131,9 @@ void fontFormatSizes_data(); void fontFormatSizes(); + void baselineOffset_data(); + void baselineOffset(); + private: QStringList standard; QStringList richText; @@ -1692,7 +1695,7 @@ QCOMPARE(text->boundingRect().x(), qreal(0)); QCOMPARE(text->boundingRect().y(), qreal(0)); QCOMPARE(text->boundingRect().width(), qreal(0)); - QCOMPARE(text->boundingRect().height(), QFontMetricsF(text->font()).height()); + QCOMPARE(text->boundingRect().height(), qreal(qCeil(QFontMetricsF(text->font()).height()))); text->setText("Hello World"); @@ -2592,6 +2595,251 @@ delete view; } +typedef qreal (*ExpectedBaseline)(QQuickText *item); +Q_DECLARE_METATYPE(ExpectedBaseline) + +static qreal expectedBaselineTop(QQuickText *item) +{ + QFontMetricsF fm(item->font()); + return fm.ascent(); +} + +static qreal expectedBaselineBottom(QQuickText *item) +{ + QFontMetricsF fm(item->font()); + return item->height() - item->contentHeight() + fm.ascent(); +} + +static qreal expectedBaselineCenter(QQuickText *item) +{ + QFontMetricsF fm(item->font()); + return ((item->height() - item->contentHeight()) / 2) + fm.ascent(); +} + +static qreal expectedBaselineBold(QQuickText *item) +{ + QFont font = item->font(); + font.setBold(true); + QFontMetricsF fm(font); + return fm.ascent(); +} + +static qreal expectedBaselineImage(QQuickText *item) +{ + QFontMetricsF fm(item->font()); + // The line is positioned so the bottom of the line is aligned with the bottom of the image, + // or image height - line height and the baseline is line position + ascent. Because + // QTextLine's height is rounded up this can give slightly different results to image height + // - descent. + return 181 - qCeil(fm.height()) + fm.ascent(); +} + +static qreal expectedBaselineCustom(QQuickText *item) +{ + QFontMetricsF fm(item->font()); + return 16 + fm.ascent(); +} + +static qreal expectedBaselineScaled(QQuickText *item) +{ + QFont font = item->font(); + QTextLayout layout(item->text().replace(QLatin1Char('\n'), QChar::LineSeparator)); + do { + layout.setFont(font); + qreal width = 0; + layout.beginLayout(); + for (QTextLine line = layout.createLine(); line.isValid(); line = layout.createLine()) { + line.setLineWidth(FLT_MAX); + width = qMax(line.naturalTextWidth(), width); + } + layout.endLayout(); + + if (width < item->width()) { + QFontMetricsF fm(layout.font()); + return fm.ascent(); + } + font.setPointSize(font.pointSize() - 1); + } while (font.pointSize() > 0); + return 0; +} + +static qreal expectedBaselineFixedBottom(QQuickText *item) +{ + QFontMetricsF fm(item->font()); + qreal dy = item->text().contains(QLatin1Char('\n')) + ? 160 + : 180; + return dy + fm.ascent(); +} + +static qreal expectedBaselineProportionalBottom(QQuickText *item) +{ + QFontMetricsF fm(item->font()); + qreal dy = item->text().contains(QLatin1Char('\n')) + ? 200 - (qCeil(fm.height()) * 3) + : 200 - (qCeil(fm.height()) * 1.5); + return dy + fm.ascent(); +} + +void tst_qquicktext::baselineOffset_data() +{ + qRegisterMetaType(); + QTest::addColumn("text"); + QTest::addColumn("wrappedText"); + QTest::addColumn("bindings"); + QTest::addColumn("expectedBaseline"); + QTest::addColumn("expectedBaselineEmpty"); + + QTest::newRow("top align") + << "hello world" + << "hello\nworld" + << QByteArray("height: 200; verticalAlignment: Text.AlignTop") + << &expectedBaselineTop + << &expectedBaselineTop; + QTest::newRow("bottom align") + << "hello world" + << "hello\nworld" + << QByteArray("height: 200; verticalAlignment: Text.AlignBottom") + << &expectedBaselineBottom + << &expectedBaselineBottom; + QTest::newRow("center align") + << "hello world" + << "hello\nworld" + << QByteArray("height: 200; verticalAlignment: Text.AlignVCenter") + << &expectedBaselineCenter + << &expectedBaselineCenter; + + QTest::newRow("bold") + << "hello world" + << "hello
world
" + << QByteArray("height: 200") + << &expectedBaselineTop + << &expectedBaselineBold; + + QTest::newRow("richText") + << "hello world" + << "hello
world
" + << QByteArray("height: 200; textFormat: Text.RichText") + << &expectedBaselineTop + << &expectedBaselineTop; + + QTest::newRow("elided") + << "hello world" + << "hello\nworld" + << QByteArray("width: 20; height: 8; elide: Text.ElideRight") + << &expectedBaselineTop + << &expectedBaselineTop; + + QTest::newRow("elided bottom align") + << "hello world" + << "hello\nworld!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + << QByteArray("width: 200; height: 200; elide: Text.ElideRight; verticalAlignment: Text.AlignBottom") + << &expectedBaselineBottom + << &expectedBaselineBottom; + + QTest::newRow("image") + << "hello world" + << "hello
world" + << QByteArray("height: 200\n; baseUrl: \"") + testFileUrl("reference").toEncoded() + QByteArray("\"") + << &expectedBaselineImage + << &expectedBaselineTop; + + QTest::newRow("customLine") + << "hello world" + << "hello\nworld" + << QByteArray("height: 200; onLineLaidOut: line.y += 16") + << &expectedBaselineCustom + << &expectedBaselineCustom; + + QTest::newRow("scaled font") + << "hello world" + << "hello\nworld" + << QByteArray("width: 200; minimumPointSize: 1; font.pointSize: 64; fontSizeMode: Text.HorizontalFit") + << &expectedBaselineScaled + << &expectedBaselineTop; + + QTest::newRow("fixed line height top align") + << "hello world" + << "hello\nworld" + << QByteArray("height: 200; lineHeightMode: Text.FixedHeight; lineHeight: 20; verticalAlignment: Text.AlignTop") + << &expectedBaselineTop + << &expectedBaselineTop; + + QTest::newRow("fixed line height bottom align") + << "hello world" + << "hello\nworld" + << QByteArray("height: 200; lineHeightMode: Text.FixedHeight; lineHeight: 20; verticalAlignment: Text.AlignBottom") + << &expectedBaselineFixedBottom + << &expectedBaselineFixedBottom; + + QTest::newRow("proportional line height top align") + << "hello world" + << "hello\nworld" + << QByteArray("height: 200; lineHeightMode: Text.ProportionalHeight; lineHeight: 1.5; verticalAlignment: Text.AlignTop") + << &expectedBaselineTop + << &expectedBaselineTop; + + QTest::newRow("proportional line height bottom align") + << "hello world" + << "hello\nworld" + << QByteArray("height: 200; lineHeightMode: Text.ProportionalHeight; lineHeight: 1.5; verticalAlignment: Text.AlignBottom") + << &expectedBaselineProportionalBottom + << &expectedBaselineProportionalBottom; +} + +void tst_qquicktext::baselineOffset() +{ + QFETCH(QString, text); + QFETCH(QString, wrappedText); + QFETCH(QByteArray, bindings); + QFETCH(ExpectedBaseline, expectedBaseline); + QFETCH(ExpectedBaseline, expectedBaselineEmpty); + + QQmlComponent component(&engine); + component.setData( + "import QtQuick 2.0\n" + "Text {\n" + + bindings + "\n" + "}", QUrl()); + + QScopedPointer object(component.create()); + + QQuickText *item = qobject_cast(object.data()); + QVERIFY(item); + + { + qreal baseline = expectedBaselineEmpty(item); + + QCOMPARE(item->baselineOffset(), baseline); + + item->setText(text); + if (expectedBaseline != expectedBaselineEmpty) + baseline = expectedBaseline(item); + + QCOMPARE(item->baselineOffset(), baseline); + + item->setText(wrappedText); + QCOMPARE(item->baselineOffset(), expectedBaseline(item)); + } + + QFont font = item->font(); + font.setPointSize(font.pointSize() + 8); + + { + QCOMPARE(item->baselineOffset(), expectedBaseline(item)); + + item->setText(text); + qreal baseline = expectedBaseline(item); + QCOMPARE(item->baselineOffset(), baseline); + + item->setText(QString()); + if (expectedBaselineEmpty != expectedBaseline) + baseline = expectedBaselineEmpty(item); + + QCOMPARE(item->baselineOffset(), baseline); + } +} + QTEST_MAIN(tst_qquicktext) #include "tst_qquicktext.moc" diff -Nru qt5-declarative-0.1~git20120402/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp qt5-declarative-0.1~git20120423/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp --- qt5-declarative-0.1~git20120402/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp 2012-04-02 11:02:55.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp 2012-04-23 11:44:59.000000000 +0000 @@ -1999,15 +1999,16 @@ void tst_qquicktextedit::cursorVisible() { + QQuickTextEdit edit; + edit.componentComplete(); + QSignalSpy spy(&edit, SIGNAL(cursorVisibleChanged(bool))); + QQuickView view(testFileUrl("cursorVisible.qml")); view.show(); view.requestActivateWindow(); QTest::qWaitForWindowShown(&view); QTRY_COMPARE(&view, qGuiApp->focusWindow()); - QQuickTextEdit edit; - QSignalSpy spy(&edit, SIGNAL(cursorVisibleChanged(bool))); - QCOMPARE(edit.isCursorVisible(), false); edit.setCursorVisible(true); @@ -2034,7 +2035,7 @@ QCOMPARE(edit.isCursorVisible(), true); QCOMPARE(spy.count(), 5); - QQuickView alternateView; + QWindow alternateView; alternateView.show(); alternateView.requestActivateWindow(); QTest::qWaitForWindowShown(&alternateView); @@ -2046,6 +2047,47 @@ QTest::qWaitForWindowShown(&view); QCOMPARE(edit.isCursorVisible(), true); QCOMPARE(spy.count(), 7); + + { // Cursor attribute with 0 length hides cursor. + QInputMethodEvent ev(QString(), QList() + << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, 0, 0, QVariant())); + QCoreApplication::sendEvent(&edit, &ev); + } + QCOMPARE(edit.isCursorVisible(), false); + QCOMPARE(spy.count(), 8); + + { // Cursor attribute with non zero length shows cursor. + QInputMethodEvent ev(QString(), QList() + << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, 0, 1, QVariant())); + QCoreApplication::sendEvent(&edit, &ev); + } + QCOMPARE(edit.isCursorVisible(), true); + QCOMPARE(spy.count(), 9); + + + { // If the cursor is hidden by the input method and the text is changed it should be visible again. + QInputMethodEvent ev(QString(), QList() + << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, 0, 0, QVariant())); + QCoreApplication::sendEvent(&edit, &ev); + } + QCOMPARE(edit.isCursorVisible(), false); + QCOMPARE(spy.count(), 10); + + edit.setText("something"); + QCOMPARE(edit.isCursorVisible(), true); + QCOMPARE(spy.count(), 11); + + { // If the cursor is hidden by the input method and the cursor position is changed it should be visible again. + QInputMethodEvent ev(QString(), QList() + << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, 0, 0, QVariant())); + QCoreApplication::sendEvent(&edit, &ev); + } + QCOMPARE(edit.isCursorVisible(), false); + QCOMPARE(spy.count(), 12); + + edit.setCursorPosition(5); + QCOMPARE(edit.isCursorVisible(), true); + QCOMPARE(spy.count(), 13); } void tst_qquicktextedit::delegateLoading_data() @@ -2337,6 +2379,11 @@ QVERIFY(edit->selectionStart() != edit->selectionEnd()); QVERIFY(platformInputContext.m_updateCallCount > 0); + // programmatical selections trigger update + platformInputContext.clear(); + edit->selectAll(); + QCOMPARE(platformInputContext.m_updateCallCount, 1); + // font changes platformInputContext.clear(); QFont font = edit->font(); @@ -2682,6 +2729,74 @@ } QCOMPARE(edit->isInputMethodComposing(), false); QCOMPARE(spy.count(), 2); + + // Changing the text while not composing doesn't alter the composing state. + edit->setText(text.mid(0, 16)); + QCOMPARE(edit->isInputMethodComposing(), false); + QCOMPARE(spy.count(), 2); + + { + QInputMethodEvent event(text.mid(16), QList()); + QGuiApplication::sendEvent(edit, &event); + } + QCOMPARE(edit->isInputMethodComposing(), true); + QCOMPARE(spy.count(), 3); + + // Changing the text while composing cancels composition. + edit->setText(text.mid(0, 12)); + QCOMPARE(edit->isInputMethodComposing(), false); + QCOMPARE(spy.count(), 4); + + { // Preedit cursor positioned outside (empty) preedit; composing. + QInputMethodEvent event(QString(), QList() + << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, -2, 1, QVariant())); + QGuiApplication::sendEvent(edit, &event); + } + QCOMPARE(edit->isInputMethodComposing(), true); + QCOMPARE(spy.count(), 5); + + { // Cursor hidden; composing + QInputMethodEvent event(QString(), QList() + << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, 0, 0, QVariant())); + QGuiApplication::sendEvent(edit, &event); + } + QCOMPARE(edit->isInputMethodComposing(), true); + QCOMPARE(spy.count(), 5); + + { // Default cursor attributes; composing. + QInputMethodEvent event(QString(), QList() + << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, 0, 1, QVariant())); + QGuiApplication::sendEvent(edit, &event); + } + QCOMPARE(edit->isInputMethodComposing(), true); + QCOMPARE(spy.count(), 5); + + { // Selections are persisted: not composing + QInputMethodEvent event(QString(), QList() + << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, 2, 4, QVariant())); + QGuiApplication::sendEvent(edit, &event); + } + QCOMPARE(edit->isInputMethodComposing(), false); + QCOMPARE(spy.count(), 6); + + edit->setCursorPosition(0); + + { // Formatting applied; composing. + QTextCharFormat format; + format.setUnderlineStyle(QTextCharFormat::SingleUnderline); + QInputMethodEvent event(QString(), QList() + << QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, 2, 4, format)); + QGuiApplication::sendEvent(edit, &event); + } + QCOMPARE(edit->isInputMethodComposing(), true); + QCOMPARE(spy.count(), 7); + + { + QInputMethodEvent event; + QGuiApplication::sendEvent(edit, &event); + } + QCOMPARE(edit->isInputMethodComposing(), false); + QCOMPARE(spy.count(), 8); } void tst_qquicktextedit::cursorRectangleSize() diff -Nru qt5-declarative-0.1~git20120402/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp qt5-declarative-0.1~git20120423/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp --- qt5-declarative-0.1~git20120402/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp 2012-04-02 11:02:55.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp 2012-04-23 11:44:59.000000000 +0000 @@ -2366,16 +2366,16 @@ void tst_qquicktextinput::cursorVisible() { + QQuickTextInput input; + input.componentComplete(); + QSignalSpy spy(&input, SIGNAL(cursorVisibleChanged(bool))); + QQuickView view(testFileUrl("cursorVisible.qml")); view.show(); view.requestActivateWindow(); QTest::qWaitForWindowShown(&view); QTRY_COMPARE(&view, qGuiApp->focusWindow()); - QQuickTextInput input; - input.componentComplete(); - QSignalSpy spy(&input, SIGNAL(cursorVisibleChanged(bool))); - QCOMPARE(input.isCursorVisible(), false); input.setCursorVisible(true); @@ -2402,7 +2402,7 @@ QCOMPARE(input.isCursorVisible(), true); QCOMPARE(spy.count(), 5); - QQuickView alternateView; + QWindow alternateView; alternateView.show(); alternateView.requestActivateWindow(); QTest::qWaitForWindowShown(&alternateView); @@ -2414,6 +2414,46 @@ QTest::qWaitForWindowShown(&view); QCOMPARE(input.isCursorVisible(), true); QCOMPARE(spy.count(), 7); + + { // Cursor attribute with 0 length hides cursor. + QInputMethodEvent ev(QString(), QList() + << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, 0, 0, QVariant())); + QCoreApplication::sendEvent(&input, &ev); + } + QCOMPARE(input.isCursorVisible(), false); + QCOMPARE(spy.count(), 8); + + { // Cursor attribute with non zero length shows cursor. + QInputMethodEvent ev(QString(), QList() + << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, 0, 1, QVariant())); + QCoreApplication::sendEvent(&input, &ev); + } + QCOMPARE(input.isCursorVisible(), true); + QCOMPARE(spy.count(), 9); + + { // If the cursor is hidden by the input method and the text is changed it should be visible again. + QInputMethodEvent ev(QString(), QList() + << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, 0, 0, QVariant())); + QCoreApplication::sendEvent(&input, &ev); + } + QCOMPARE(input.isCursorVisible(), false); + QCOMPARE(spy.count(), 10); + + input.setText("something"); + QCOMPARE(input.isCursorVisible(), true); + QCOMPARE(spy.count(), 11); + + { // If the cursor is hidden by the input method and the cursor position is changed it should be visible again. + QInputMethodEvent ev(QString(), QList() + << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, 0, 0, QVariant())); + QCoreApplication::sendEvent(&input, &ev); + } + QCOMPARE(input.isCursorVisible(), false); + QCOMPARE(spy.count(), 12); + + input.setCursorPosition(5); + QCOMPARE(input.isCursorVisible(), true); + QCOMPARE(spy.count(), 13); } void tst_qquicktextinput::cursorRectangle_data() @@ -3280,6 +3320,75 @@ } QCOMPARE(input->isInputMethodComposing(), false); QCOMPARE(spy.count(), 2); + + // Changing the text while not composing doesn't alter the composing state. + input->setText(text.mid(0, 16)); + QCOMPARE(input->isInputMethodComposing(), false); + QCOMPARE(spy.count(), 2); + + { + QInputMethodEvent event(text.mid(16), QList()); + QGuiApplication::sendEvent(input, &event); + } + QCOMPARE(input->isInputMethodComposing(), true); + QCOMPARE(spy.count(), 3); + + // Changing the text while composing cancels composition. + input->setText(text.mid(0, 12)); + QCOMPARE(input->isInputMethodComposing(), false); + QCOMPARE(spy.count(), 4); + + { // Preedit cursor positioned outside (empty) preedit; composing. + QInputMethodEvent event(QString(), QList() + << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, -2, 1, QVariant())); + QGuiApplication::sendEvent(input, &event); + } + QCOMPARE(input->isInputMethodComposing(), true); + QCOMPARE(spy.count(), 5); + + + { // Cursor hidden; composing + QInputMethodEvent event(QString(), QList() + << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, 0, 0, QVariant())); + QGuiApplication::sendEvent(input, &event); + } + QCOMPARE(input->isInputMethodComposing(), true); + QCOMPARE(spy.count(), 5); + + { // Default cursor attributes; composing. + QInputMethodEvent event(QString(), QList() + << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, 0, 1, QVariant())); + QGuiApplication::sendEvent(input, &event); + } + QCOMPARE(input->isInputMethodComposing(), true); + QCOMPARE(spy.count(), 5); + + { // Selections are persisted: not composing + QInputMethodEvent event(QString(), QList() + << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, -5, 4, QVariant())); + QGuiApplication::sendEvent(input, &event); + } + QCOMPARE(input->isInputMethodComposing(), false); + QCOMPARE(spy.count(), 6); + + input->setCursorPosition(12); + + { // Formatting applied; composing. + QTextCharFormat format; + format.setUnderlineStyle(QTextCharFormat::SingleUnderline); + QInputMethodEvent event(QString(), QList() + << QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, -5, 4, format)); + QGuiApplication::sendEvent(input, &event); + } + QCOMPARE(input->isInputMethodComposing(), true); + QCOMPARE(spy.count(), 7); + + { + QInputMethodEvent event; + QGuiApplication::sendEvent(input, &event); + } + QCOMPARE(input->isInputMethodComposing(), false); + QCOMPARE(spy.count(), 8); } void tst_qquicktextinput::inputMethodUpdate() diff -Nru qt5-declarative-0.1~git20120402/tests/auto/quick/shared/viewtestutil.cpp qt5-declarative-0.1~git20120423/tests/auto/quick/shared/viewtestutil.cpp --- qt5-declarative-0.1~git20120402/tests/auto/quick/shared/viewtestutil.cpp 2012-04-02 10:45:07.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tests/auto/quick/shared/viewtestutil.cpp 2012-04-23 11:32:41.000000000 +0000 @@ -88,12 +88,8 @@ // send press, five equally spaced moves, and release. QTest::mousePress(canvas, Qt::LeftButton, 0, from); - for (int i = 0; i < pointCount; ++i) { - QMouseEvent mv(QEvent::MouseMove, from + (i+1)*diff/pointCount, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); - QGuiApplication::sendEvent(canvas, &mv); - QTest::qWait(duration/pointCount); - QCoreApplication::processEvents(); - } + for (int i = 0; i < pointCount; ++i) + QTest::mouseMove(canvas, from + (i+1)*diff/pointCount, duration / pointCount); QTest::mouseRelease(canvas, Qt::LeftButton, 0, to); QTest::qWait(50); diff -Nru qt5-declarative-0.1~git20120402/tools/easingcurveeditor/mainwindow.cpp qt5-declarative-0.1~git20120423/tools/easingcurveeditor/mainwindow.cpp --- qt5-declarative-0.1~git20120402/tools/easingcurveeditor/mainwindow.cpp 2012-04-02 10:45:08.000000000 +0000 +++ qt5-declarative-0.1~git20120423/tools/easingcurveeditor/mainwindow.cpp 2012-04-23 11:32:41.000000000 +0000 @@ -104,7 +104,7 @@ void MainWindow::showQuickView() { const int margin = 16; - quickView.move(pos() + QPoint(0, frameGeometry().height() + margin)); + quickView.setPos(pos() + QPoint(0, frameGeometry().height() + margin)); quickView.raise(); quickView.show();