aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--examples/qml/referenceexamples/adding/main.cpp2
-rw-r--r--examples/qml/referenceexamples/adding/person.h2
-rw-r--r--examples/qml/referenceexamples/attached/birthdayparty.cpp2
-rw-r--r--examples/qml/referenceexamples/attached/birthdayparty.h2
-rw-r--r--examples/qml/referenceexamples/attached/main.cpp2
-rw-r--r--examples/qml/referenceexamples/attached/person.h6
-rw-r--r--examples/qml/referenceexamples/binding/birthdayparty.h2
-rw-r--r--examples/qml/referenceexamples/binding/happybirthdaysong.cpp2
-rw-r--r--examples/qml/referenceexamples/binding/happybirthdaysong.h4
-rw-r--r--examples/qml/referenceexamples/binding/main.cpp2
-rw-r--r--examples/qml/referenceexamples/binding/person.h8
-rw-r--r--examples/qml/referenceexamples/coercion/birthdayparty.cpp2
-rw-r--r--examples/qml/referenceexamples/coercion/birthdayparty.h2
-rw-r--r--examples/qml/referenceexamples/coercion/main.cpp2
-rw-r--r--examples/qml/referenceexamples/coercion/person.h6
-rw-r--r--examples/qml/referenceexamples/default/birthdayparty.cpp2
-rw-r--r--examples/qml/referenceexamples/default/birthdayparty.h2
-rw-r--r--examples/qml/referenceexamples/default/main.cpp2
-rw-r--r--examples/qml/referenceexamples/default/person.h6
-rw-r--r--examples/qml/referenceexamples/extended/lineedit.cpp2
-rw-r--r--examples/qml/referenceexamples/extended/main.cpp2
-rw-r--r--examples/qml/referenceexamples/grouped/birthdayparty.cpp2
-rw-r--r--examples/qml/referenceexamples/grouped/birthdayparty.h2
-rw-r--r--examples/qml/referenceexamples/grouped/main.cpp2
-rw-r--r--examples/qml/referenceexamples/grouped/person.h8
-rw-r--r--examples/qml/referenceexamples/methods/birthdayparty.cpp4
-rw-r--r--examples/qml/referenceexamples/methods/birthdayparty.h2
-rw-r--r--examples/qml/referenceexamples/methods/main.cpp2
-rw-r--r--examples/qml/referenceexamples/methods/person.h2
-rw-r--r--examples/qml/referenceexamples/properties/birthdayparty.cpp4
-rw-r--r--examples/qml/referenceexamples/properties/birthdayparty.h2
-rw-r--r--examples/qml/referenceexamples/properties/main.cpp2
-rw-r--r--examples/qml/referenceexamples/properties/person.h2
-rw-r--r--examples/qml/referenceexamples/signal/birthdayparty.cpp2
-rw-r--r--examples/qml/referenceexamples/signal/birthdayparty.h2
-rw-r--r--examples/qml/referenceexamples/signal/main.cpp2
-rw-r--r--examples/qml/referenceexamples/signal/person.h8
-rw-r--r--examples/qml/referenceexamples/valuesource/birthdayparty.cpp2
-rw-r--r--examples/qml/referenceexamples/valuesource/birthdayparty.h2
-rw-r--r--examples/qml/referenceexamples/valuesource/happybirthdaysong.cpp2
-rw-r--r--examples/qml/referenceexamples/valuesource/happybirthdaysong.h4
-rw-r--r--examples/qml/referenceexamples/valuesource/main.cpp2
-rw-r--r--examples/qml/referenceexamples/valuesource/person.h8
-rw-r--r--examples/quick/imageelements/content/multi.icobin0 -> 27110 bytes
-rw-r--r--examples/quick/imageelements/framestepping.qml82
-rw-r--r--examples/quick/imageelements/imageelements.qml2
-rw-r--r--examples/quick/imageelements/imageelements.qrc3
-rw-r--r--examples/quick/imageelements/multiframeborderimage.qml83
-rw-r--r--examples/quick/scenegraph/d3d11underqml/doc/images/d3d11underqml-example.jpgbin0 -> 79343 bytes
-rw-r--r--examples/quick/scenegraph/d3d11underqml/doc/src/d3d11underqml.qdoc58
-rw-r--r--examples/quick/scenegraph/metalunderqml/doc/images/metalunderqml-example.jpgbin0 -> 55194 bytes
-rw-r--r--examples/quick/scenegraph/metalunderqml/doc/src/metalunderqml.qdoc68
-rw-r--r--examples/quick/scenegraph/openglunderqml/doc/src/openglunderqml.qdoc5
-rw-r--r--examples/quick/scenegraph/rendernode/customrenderitem.cpp48
-rw-r--r--examples/quick/scenegraph/rendernode/d3d12renderer.cpp6
-rw-r--r--examples/quick/scenegraph/rendernode/doc/images/rendernode-example.jpgbin0 -> 77210 bytes
-rw-r--r--examples/quick/scenegraph/rendernode/doc/src/rendernode.qdoc165
-rw-r--r--examples/quick/scenegraph/rendernode/main.cpp2
-rw-r--r--examples/quick/scenegraph/rendernode/main.qml90
-rw-r--r--examples/quick/scenegraph/rendernode/metalrenderer.h100
-rw-r--r--examples/quick/scenegraph/rendernode/metalrenderer.mm326
-rw-r--r--examples/quick/scenegraph/rendernode/metalshader.frag28
-rw-r--r--examples/quick/scenegraph/rendernode/metalshader.vert31
-rw-r--r--examples/quick/scenegraph/rendernode/openglrenderer.cpp31
-rw-r--r--examples/quick/scenegraph/rendernode/openglrenderer.h2
-rw-r--r--examples/quick/scenegraph/rendernode/rendernode.pro6
-rw-r--r--examples/quick/scenegraph/rendernode/rendernode.qrc2
-rw-r--r--examples/quick/shared/CheckBox.qml2
-rw-r--r--examples/quick/shared/LauncherList.qml11
-rw-r--r--examples/quick/shared/Slider.qml2
-rw-r--r--src/imports/builtins/builtins.qmltypes13
-rw-r--r--src/imports/folderlistmodel/plugins.qmltypes2
-rw-r--r--src/imports/labsmodels/plugins.qmltypes373
-rw-r--r--src/imports/layouts/plugins.qmltypes2
-rw-r--r--src/imports/localstorage/plugins.qmltypes2
-rw-r--r--src/imports/models/plugins.qmltypes75
-rw-r--r--src/imports/particles/plugins.qmltypes10
-rw-r--r--src/imports/qtqml/dependencies.json2
-rw-r--r--src/imports/qtqml/plugins.qmltypes34
-rw-r--r--src/imports/qtquick2/plugins.qmltypes247
-rw-r--r--src/imports/shapes/plugins.qmltypes10
-rw-r--r--src/imports/statemachine/plugins.qmltypes2
-rw-r--r--src/imports/testlib/main.cpp2
-rw-r--r--src/imports/testlib/plugins.qmltypes8
-rw-r--r--src/imports/wavefrontmesh/plugins.qmltypes2
-rw-r--r--src/imports/window/plugins.qmltypes22
-rw-r--r--src/imports/workerscript/plugins.qmltypes26
-rw-r--r--src/particles/particles.qrc11
-rw-r--r--src/particles/qquickimageparticle.cpp735
-rw-r--r--src/particles/qquickimageparticle_p.h29
-rw-r--r--src/particles/qquickparticlepainter.cpp2
-rw-r--r--src/particles/qquickparticlepainter_p.h1
-rwxr-xr-xsrc/particles/shaders_ng/compile.bat53
-rw-r--r--src/particles/shaders_ng/imageparticle.frag55
-rw-r--r--src/particles/shaders_ng/imageparticle.vert145
-rw-r--r--src/particles/shaders_ng/imageparticle_colored.frag.qsbbin0 -> 1990 bytes
-rw-r--r--src/particles/shaders_ng/imageparticle_colored.vert.qsbbin0 -> 3677 bytes
-rw-r--r--src/particles/shaders_ng/imageparticle_deformed.frag.qsbbin0 -> 2028 bytes
-rw-r--r--src/particles/shaders_ng/imageparticle_deformed.vert.qsbbin0 -> 5044 bytes
-rw-r--r--src/particles/shaders_ng/imageparticle_simple.frag.qsbbin0 -> 2000 bytes
-rw-r--r--src/particles/shaders_ng/imageparticle_simple.vert.qsbbin0 -> 3639 bytes
-rw-r--r--src/particles/shaders_ng/imageparticle_sprite.frag.qsbbin0 -> 2369 bytes
-rw-r--r--src/particles/shaders_ng/imageparticle_sprite.vert.qsbbin0 -> 5964 bytes
-rw-r--r--src/particles/shaders_ng/imageparticle_tabled.frag.qsbbin0 -> 2240 bytes
-rw-r--r--src/particles/shaders_ng/imageparticle_tabled.vert.qsbbin0 -> 5462 bytes
-rw-r--r--src/plugins/scenegraph/d3d12/qsgd3d12threadedrenderloop.cpp12
-rw-r--r--src/qml/doc/src/qmlfunctions.qdoc10
-rw-r--r--src/qml/qml/qqml.h10
-rw-r--r--src/qml/qml/qqmlapplicationengine.cpp18
-rw-r--r--src/qml/qml/qqmlapplicationengine.h1
-rw-r--r--src/qml/qml/qqmlapplicationengine_p.h1
-rw-r--r--src/qml/qml/qqmlcomponent.cpp74
-rw-r--r--src/qml/qml/qqmlcomponent.h2
-rw-r--r--src/qml/qml/qqmlcomponent_p.h3
-rw-r--r--src/qml/qml/qqmlengine.cpp8
-rw-r--r--src/qml/qml/qqmlloggingcategory_p.h2
-rw-r--r--src/qml/types/qqmlconnections.cpp2
-rw-r--r--src/qml/types/qqmlconnections_p.h4
-rw-r--r--src/qmlmodels/configure.json2
-rw-r--r--src/qmlmodels/qqmlmodelsmodule.cpp6
-rw-r--r--src/qmltest/quicktestevent.cpp3
-rw-r--r--src/quick/doc/images/declarative-qtlogo.pngbin3436 -> 1214 bytes
-rw-r--r--src/quick/doc/snippets/qml/transitions-list.qml135
-rw-r--r--src/quick/doc/src/concepts/positioning/righttoleft.qdoc2
-rw-r--r--src/quick/items/qquickanimatedimage.cpp6
-rw-r--r--src/quick/items/qquickanimatedimage_p.h6
-rw-r--r--src/quick/items/qquickborderimage.cpp18
-rw-r--r--src/quick/items/qquickevents.cpp2
-rw-r--r--src/quick/items/qquickflickable.cpp5
-rw-r--r--src/quick/items/qquickimage.cpp12
-rw-r--r--src/quick/items/qquickimage_p.h8
-rw-r--r--src/quick/items/qquickimagebase.cpp42
-rw-r--r--src/quick/items/qquickimagebase_p.h9
-rw-r--r--src/quick/items/qquickimagebase_p_p.h6
-rw-r--r--src/quick/items/qquickitem.h2
-rw-r--r--src/quick/items/qquickitemsmodule.cpp69
-rw-r--r--src/quick/items/qquickitemview_p.h4
-rw-r--r--src/quick/items/qquicklistview_p.h8
-rw-r--r--src/quick/items/qquickmousearea.cpp2
-rw-r--r--src/quick/items/qquickmousearea_p.h8
-rw-r--r--src/quick/items/qquickpincharea_p.h4
-rw-r--r--src/quick/items/qquickscreen_p.h8
-rw-r--r--src/quick/items/qquickshadereffect_p.h2
-rw-r--r--src/quick/items/qquickshadereffectsource_p.h4
-rw-r--r--src/quick/items/qquicktextinput_p.h8
-rw-r--r--src/quick/items/qquicktextnodeengine.cpp2
-rw-r--r--src/quick/items/qquickview.cpp18
-rw-r--r--src/quick/items/qquickview.h1
-rw-r--r--src/quick/items/qquickview_p.h2
-rw-r--r--src/quick/items/qquickwindow.cpp10
-rw-r--r--src/quick/items/qquickwindowmodule.cpp8
-rw-r--r--src/quick/items/qquickwindowmodule_p.h4
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp11
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp111
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h2
-rw-r--r--src/quick/scenegraph/coreapi/qsgrendernode.cpp103
-rw-r--r--src/quick/scenegraph/qsgthreadedrenderloop.cpp11
-rw-r--r--src/quick/util/qquickpath_p.h4
-rw-r--r--src/quick/util/qquickpixmapcache.cpp81
-rw-r--r--src/quick/util/qquickpixmapcache_p.h5
-rw-r--r--src/quick/util/qquickshortcut_p.h4
-rw-r--r--src/quick/util/qquicktransition.cpp20
-rw-r--r--src/quick/util/qquickutilmodule.cpp6
-rw-r--r--src/quickshapes/qquickshape.cpp2
-rw-r--r--tests/auto/qml/bindingdependencyapi/dummy_imports.qml8
-rw-r--r--tests/auto/qml/qjsengine/dummy_imports.qml8
-rw-r--r--tests/auto/qml/qjsengine/tst_qjsengine.cpp7
-rw-r--r--tests/auto/qml/qjsvalue/tst_qjsvalue.cpp59
-rw-r--r--tests/auto/qml/qmldiskcache/dummy_imports.qml8
-rw-r--r--tests/auto/qml/qmllint/qmllint.pro13
-rw-r--r--tests/auto/qml/qmllint/tst_qmllint.cpp (renamed from tests/auto/qml/qmllint/main.cpp)21
-rw-r--r--tests/auto/qml/qqmlapplicationengine/tst_qqmlapplicationengine.cpp18
-rw-r--r--tests/auto/qml/qqmlcomponent/data/allJSONTypes.qml9
-rw-r--r--tests/auto/qml/qqmlcomponent/data/variantBasedInitialization.qml21
-rw-r--r--tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp96
-rw-r--r--tests/auto/qml/qv4mm/tst_qv4mm.cpp2
-rw-r--r--tests/auto/quick/qquickborderimage/data/multi.icobin0 -> 27110 bytes
-rw-r--r--tests/auto/quick/qquickborderimage/data/multiframe.qml8
-rw-r--r--tests/auto/quick/qquickborderimage/data/multiframeAsync.qml9
-rw-r--r--tests/auto/quick/qquickborderimage/tst_qquickborderimage.cpp65
-rw-r--r--tests/auto/quick/qquickflickable/tst_qquickflickable.cpp15
-rw-r--r--tests/auto/quick/qquickimage/data/multi.icobin0 -> 27110 bytes
-rw-r--r--tests/auto/quick/qquickimage/data/multiframe.qml5
-rw-r--r--tests/auto/quick/qquickimage/data/multiframeAsync.qml6
-rw-r--r--tests/auto/quick/qquickimage/tst_qquickimage.cpp58
-rw-r--r--tests/auto/quick/qquickitem/tst_qquickitem.cpp7
-rw-r--r--tests/auto/quick/qquicklistview/data/addoncompleted.qml3
-rw-r--r--tests/auto/quick/qquicklistview/tst_qquicklistview.cpp1
-rw-r--r--tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp2
-rw-r--r--tests/auto/quick/qquicktext/data/verticallyAlignedImageInTable.qml14
-rw-r--r--tests/auto/quick/qquicktext/tst_qquicktext.cpp14
-rw-r--r--tests/auto/quick/qquickview/tst_qquickview.cpp12
-rw-r--r--tests/benchmarks/qml/js/qjsengine/tst_qjsengine.cpp4
-rw-r--r--tests/benchmarks/qml/painting/paintbenchmark.cpp10
-rw-r--r--tests/manual/scenegraph_lancelot/data/text/text_table_vertically_aligned_image.qml14
-rw-r--r--tools/qmlcachegen/generateloader.cpp6
-rw-r--r--tools/qmlcachegen/qmlcachegen.cpp6
-rw-r--r--tools/qmlcachegen/qtquickcompiler.prf10
-rw-r--r--tools/qmlplugindump/main.cpp133
199 files changed, 4029 insertions, 722 deletions
diff --git a/examples/qml/referenceexamples/adding/main.cpp b/examples/qml/referenceexamples/adding/main.cpp
index 5c3c891130..e312149da1 100644
--- a/examples/qml/referenceexamples/adding/main.cpp
+++ b/examples/qml/referenceexamples/adding/main.cpp
@@ -62,7 +62,7 @@ int main(int argc, char ** argv)
QQmlEngine engine;
QQmlComponent component(&engine, QUrl("qrc:example.qml"));
- Person *person = qobject_cast<Person *>(component.create());
+ auto *person = qobject_cast<Person *>(component.create());
if (person) {
qWarning() << "The person's name is" << person->name();
qWarning() << "They wear a" << person->shoeSize() << "sized shoe";
diff --git a/examples/qml/referenceexamples/adding/person.h b/examples/qml/referenceexamples/adding/person.h
index 44e2ac3b1b..f40c8d8086 100644
--- a/examples/qml/referenceexamples/adding/person.h
+++ b/examples/qml/referenceexamples/adding/person.h
@@ -58,7 +58,7 @@ class Person : public QObject
Q_PROPERTY(QString name READ name WRITE setName)
Q_PROPERTY(int shoeSize READ shoeSize WRITE setShoeSize)
public:
- Person(QObject *parent = 0);
+ Person(QObject *parent = nullptr);
QString name() const;
void setName(const QString &);
diff --git a/examples/qml/referenceexamples/attached/birthdayparty.cpp b/examples/qml/referenceexamples/attached/birthdayparty.cpp
index 26aa56e86c..da0cb800fc 100644
--- a/examples/qml/referenceexamples/attached/birthdayparty.cpp
+++ b/examples/qml/referenceexamples/attached/birthdayparty.cpp
@@ -81,7 +81,7 @@ void BirthdayParty::setHost(Person *c)
QQmlListProperty<Person> BirthdayParty::guests()
{
- return QQmlListProperty<Person>(this, m_guests);
+ return {this, m_guests};
}
int BirthdayParty::guestCount() const
diff --git a/examples/qml/referenceexamples/attached/birthdayparty.h b/examples/qml/referenceexamples/attached/birthdayparty.h
index 0684f16255..15375f14d9 100644
--- a/examples/qml/referenceexamples/attached/birthdayparty.h
+++ b/examples/qml/referenceexamples/attached/birthdayparty.h
@@ -76,7 +76,7 @@ class BirthdayParty : public QObject
Q_PROPERTY(QQmlListProperty<Person> guests READ guests)
Q_CLASSINFO("DefaultProperty", "guests")
public:
- BirthdayParty(QObject *parent = 0);
+ BirthdayParty(QObject *parent = nullptr);
Person *host() const;
void setHost(Person *);
diff --git a/examples/qml/referenceexamples/attached/main.cpp b/examples/qml/referenceexamples/attached/main.cpp
index f07f16ae0f..581b033dfc 100644
--- a/examples/qml/referenceexamples/attached/main.cpp
+++ b/examples/qml/referenceexamples/attached/main.cpp
@@ -67,7 +67,7 @@ int main(int argc, char ** argv)
QQmlEngine engine;
QQmlComponent component(&engine, QUrl("qrc:example.qml"));
- BirthdayParty *party = qobject_cast<BirthdayParty *>(component.create());
+ auto *party = qobject_cast<BirthdayParty *>(component.create());
if (party && party->host()) {
qWarning() << party->host()->name() << "is having a birthday!";
diff --git a/examples/qml/referenceexamples/attached/person.h b/examples/qml/referenceexamples/attached/person.h
index 9b63773d49..2398da38bf 100644
--- a/examples/qml/referenceexamples/attached/person.h
+++ b/examples/qml/referenceexamples/attached/person.h
@@ -87,7 +87,7 @@ class Person : public QObject
Q_PROPERTY(QString name READ name WRITE setName)
Q_PROPERTY(ShoeDescription *shoe READ shoe)
public:
- Person(QObject *parent = 0);
+ Person(QObject *parent = nullptr);
QString name() const;
void setName(const QString &);
@@ -102,14 +102,14 @@ class Boy : public Person
{
Q_OBJECT
public:
- Boy(QObject * parent = 0);
+ Boy(QObject * parent = nullptr);
};
class Girl : public Person
{
Q_OBJECT
public:
- Girl(QObject * parent = 0);
+ Girl(QObject * parent = nullptr);
};
#endif // PERSON_H
diff --git a/examples/qml/referenceexamples/binding/birthdayparty.h b/examples/qml/referenceexamples/binding/birthdayparty.h
index 93dad927d7..15e1908ece 100644
--- a/examples/qml/referenceexamples/binding/birthdayparty.h
+++ b/examples/qml/referenceexamples/binding/birthdayparty.h
@@ -83,7 +83,7 @@ class BirthdayParty : public QObject
Q_PROPERTY(QString announcement READ announcement WRITE setAnnouncement)
Q_CLASSINFO("DefaultProperty", "guests")
public:
- BirthdayParty(QObject *parent = 0);
+ BirthdayParty(QObject *parent = nullptr);
Person *host() const;
void setHost(Person *);
diff --git a/examples/qml/referenceexamples/binding/happybirthdaysong.cpp b/examples/qml/referenceexamples/binding/happybirthdaysong.cpp
index fae016091b..5f8e6d696e 100644
--- a/examples/qml/referenceexamples/binding/happybirthdaysong.cpp
+++ b/examples/qml/referenceexamples/binding/happybirthdaysong.cpp
@@ -54,7 +54,7 @@ HappyBirthdaySong::HappyBirthdaySong(QObject *parent)
: QObject(parent), m_line(-1)
{
setName(QString());
- QTimer *timer = new QTimer(this);
+ auto *timer = new QTimer(this);
QObject::connect(timer, &QTimer::timeout, this, &HappyBirthdaySong::advance);
timer->start(1000);
}
diff --git a/examples/qml/referenceexamples/binding/happybirthdaysong.h b/examples/qml/referenceexamples/binding/happybirthdaysong.h
index ab264b80c7..dcfebc06ba 100644
--- a/examples/qml/referenceexamples/binding/happybirthdaysong.h
+++ b/examples/qml/referenceexamples/binding/happybirthdaysong.h
@@ -61,9 +61,9 @@ class HappyBirthdaySong : public QObject, public QQmlPropertyValueSource
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
Q_INTERFACES(QQmlPropertyValueSource)
public:
- HappyBirthdaySong(QObject *parent = 0);
+ HappyBirthdaySong(QObject *parent = nullptr);
- virtual void setTarget(const QQmlProperty &);
+ void setTarget(const QQmlProperty &) override;
QString name() const;
void setName(const QString &);
diff --git a/examples/qml/referenceexamples/binding/main.cpp b/examples/qml/referenceexamples/binding/main.cpp
index cc9ce8f373..99187eba3e 100644
--- a/examples/qml/referenceexamples/binding/main.cpp
+++ b/examples/qml/referenceexamples/binding/main.cpp
@@ -68,7 +68,7 @@ int main(int argc, char ** argv)
QQmlEngine engine;
QQmlComponent component(&engine, QUrl("qrc:example.qml"));
- BirthdayParty *party = qobject_cast<BirthdayParty *>(component.create());
+ auto *party = qobject_cast<BirthdayParty *>(component.create());
if (party && party->host()) {
qWarning() << party->host()->name() << "is having a birthday!";
diff --git a/examples/qml/referenceexamples/binding/person.h b/examples/qml/referenceexamples/binding/person.h
index 2cff97a6cd..543b24f971 100644
--- a/examples/qml/referenceexamples/binding/person.h
+++ b/examples/qml/referenceexamples/binding/person.h
@@ -61,7 +61,7 @@ class ShoeDescription : public QObject
Q_PROPERTY(QString brand READ brand WRITE setBrand NOTIFY shoeChanged)
Q_PROPERTY(qreal price READ price WRITE setPrice NOTIFY shoeChanged)
public:
- ShoeDescription(QObject *parent = 0);
+ ShoeDescription(QObject *parent = nullptr);
int size() const;
void setSize(int);
@@ -92,7 +92,7 @@ class Person : public QObject
Q_PROPERTY(ShoeDescription *shoe READ shoe CONSTANT)
// ![0]
public:
- Person(QObject *parent = 0);
+ Person(QObject *parent = nullptr);
QString name() const;
void setName(const QString &);
@@ -110,14 +110,14 @@ class Boy : public Person
{
Q_OBJECT
public:
- Boy(QObject * parent = 0);
+ Boy(QObject * parent = nullptr);
};
class Girl : public Person
{
Q_OBJECT
public:
- Girl(QObject * parent = 0);
+ Girl(QObject * parent = nullptr);
};
#endif // PERSON_H
diff --git a/examples/qml/referenceexamples/coercion/birthdayparty.cpp b/examples/qml/referenceexamples/coercion/birthdayparty.cpp
index e729c42bb5..1bae55076c 100644
--- a/examples/qml/referenceexamples/coercion/birthdayparty.cpp
+++ b/examples/qml/referenceexamples/coercion/birthdayparty.cpp
@@ -66,7 +66,7 @@ void BirthdayParty::setHost(Person *c)
QQmlListProperty<Person> BirthdayParty::guests()
{
- return QQmlListProperty<Person>(this, m_guests);
+ return {this, m_guests};
}
int BirthdayParty::guestCount() const
diff --git a/examples/qml/referenceexamples/coercion/birthdayparty.h b/examples/qml/referenceexamples/coercion/birthdayparty.h
index bb20212ac9..554e7ab0da 100644
--- a/examples/qml/referenceexamples/coercion/birthdayparty.h
+++ b/examples/qml/referenceexamples/coercion/birthdayparty.h
@@ -62,7 +62,7 @@ class BirthdayParty : public QObject
Q_PROPERTY(QQmlListProperty<Person> guests READ guests)
// ![0]
public:
- BirthdayParty(QObject *parent = 0);
+ BirthdayParty(QObject *parent = nullptr);
Person *host() const;
void setHost(Person *);
diff --git a/examples/qml/referenceexamples/coercion/main.cpp b/examples/qml/referenceexamples/coercion/main.cpp
index 04a78b05f7..262cdf6320 100644
--- a/examples/qml/referenceexamples/coercion/main.cpp
+++ b/examples/qml/referenceexamples/coercion/main.cpp
@@ -70,7 +70,7 @@ int main(int argc, char ** argv)
QQmlEngine engine;
QQmlComponent component(&engine, QUrl("qrc:example.qml"));
- BirthdayParty *party = qobject_cast<BirthdayParty *>(component.create());
+ auto *party = qobject_cast<BirthdayParty *>(component.create());
if (party && party->host()) {
qWarning() << party->host()->name() << "is having a birthday!";
diff --git a/examples/qml/referenceexamples/coercion/person.h b/examples/qml/referenceexamples/coercion/person.h
index 7169859cce..692cf4eb19 100644
--- a/examples/qml/referenceexamples/coercion/person.h
+++ b/examples/qml/referenceexamples/coercion/person.h
@@ -58,7 +58,7 @@ class Person : public QObject
Q_PROPERTY(QString name READ name WRITE setName)
Q_PROPERTY(int shoeSize READ shoeSize WRITE setShoeSize)
public:
- Person(QObject *parent = 0);
+ Person(QObject *parent = nullptr);
QString name() const;
void setName(const QString &);
@@ -76,7 +76,7 @@ class Boy : public Person
{
Q_OBJECT
public:
- Boy(QObject * parent = 0);
+ Boy(QObject * parent = nullptr);
};
//! [girl class]
@@ -84,7 +84,7 @@ class Girl : public Person
{
Q_OBJECT
public:
- Girl(QObject * parent = 0);
+ Girl(QObject * parent = nullptr);
};
//! [girl class]
diff --git a/examples/qml/referenceexamples/default/birthdayparty.cpp b/examples/qml/referenceexamples/default/birthdayparty.cpp
index e729c42bb5..1bae55076c 100644
--- a/examples/qml/referenceexamples/default/birthdayparty.cpp
+++ b/examples/qml/referenceexamples/default/birthdayparty.cpp
@@ -66,7 +66,7 @@ void BirthdayParty::setHost(Person *c)
QQmlListProperty<Person> BirthdayParty::guests()
{
- return QQmlListProperty<Person>(this, m_guests);
+ return {this, m_guests};
}
int BirthdayParty::guestCount() const
diff --git a/examples/qml/referenceexamples/default/birthdayparty.h b/examples/qml/referenceexamples/default/birthdayparty.h
index 6acb395f47..ea63a6a16d 100644
--- a/examples/qml/referenceexamples/default/birthdayparty.h
+++ b/examples/qml/referenceexamples/default/birthdayparty.h
@@ -62,7 +62,7 @@ class BirthdayParty : public QObject
Q_PROPERTY(QQmlListProperty<Person> guests READ guests)
Q_CLASSINFO("DefaultProperty", "guests")
public:
- BirthdayParty(QObject *parent = 0);
+ BirthdayParty(QObject *parent = nullptr);
Person *host() const;
void setHost(Person *);
diff --git a/examples/qml/referenceexamples/default/main.cpp b/examples/qml/referenceexamples/default/main.cpp
index d8c3e466ce..017d6495cd 100644
--- a/examples/qml/referenceexamples/default/main.cpp
+++ b/examples/qml/referenceexamples/default/main.cpp
@@ -65,7 +65,7 @@ int main(int argc, char ** argv)
QQmlEngine engine;
QQmlComponent component(&engine, QUrl("qrc:example.qml"));
- BirthdayParty *party = qobject_cast<BirthdayParty *>(component.create());
+ auto *party = qobject_cast<BirthdayParty *>(component.create());
if (party && party->host()) {
qWarning() << party->host()->name() << "is having a birthday!";
diff --git a/examples/qml/referenceexamples/default/person.h b/examples/qml/referenceexamples/default/person.h
index 878c2953e5..87f69276bf 100644
--- a/examples/qml/referenceexamples/default/person.h
+++ b/examples/qml/referenceexamples/default/person.h
@@ -58,7 +58,7 @@ class Person : public QObject
Q_PROPERTY(QString name READ name WRITE setName)
Q_PROPERTY(int shoeSize READ shoeSize WRITE setShoeSize)
public:
- Person(QObject *parent = 0);
+ Person(QObject *parent = nullptr);
QString name() const;
void setName(const QString &);
@@ -74,14 +74,14 @@ class Boy : public Person
{
Q_OBJECT
public:
- Boy(QObject * parent = 0);
+ Boy(QObject * parent = nullptr);
};
class Girl : public Person
{
Q_OBJECT
public:
- Girl(QObject * parent = 0);
+ Girl(QObject * parent = nullptr);
};
#endif // PERSON_H
diff --git a/examples/qml/referenceexamples/extended/lineedit.cpp b/examples/qml/referenceexamples/extended/lineedit.cpp
index 777e15db07..feb1a08585 100644
--- a/examples/qml/referenceexamples/extended/lineedit.cpp
+++ b/examples/qml/referenceexamples/extended/lineedit.cpp
@@ -51,7 +51,7 @@
#include <qqml.h>
LineEditExtension::LineEditExtension(QObject *object)
-: QObject(object), m_lineedit(static_cast<QLineEdit *>(object))
+: QObject(object), m_lineedit(qobject_cast<QLineEdit *>(object))
{
}
diff --git a/examples/qml/referenceexamples/extended/main.cpp b/examples/qml/referenceexamples/extended/main.cpp
index c99e052ae5..f91cec76b1 100644
--- a/examples/qml/referenceexamples/extended/main.cpp
+++ b/examples/qml/referenceexamples/extended/main.cpp
@@ -65,7 +65,7 @@ int main(int argc, char ** argv)
// ![1]
QQmlEngine engine;
QQmlComponent component(&engine, QUrl("qrc:example.qml"));
- QLineEdit *edit = qobject_cast<QLineEdit *>(component.create());
+ auto *edit = qobject_cast<QLineEdit *>(component.create());
// ![1]
if (edit) {
diff --git a/examples/qml/referenceexamples/grouped/birthdayparty.cpp b/examples/qml/referenceexamples/grouped/birthdayparty.cpp
index e729c42bb5..1bae55076c 100644
--- a/examples/qml/referenceexamples/grouped/birthdayparty.cpp
+++ b/examples/qml/referenceexamples/grouped/birthdayparty.cpp
@@ -66,7 +66,7 @@ void BirthdayParty::setHost(Person *c)
QQmlListProperty<Person> BirthdayParty::guests()
{
- return QQmlListProperty<Person>(this, m_guests);
+ return {this, m_guests};
}
int BirthdayParty::guestCount() const
diff --git a/examples/qml/referenceexamples/grouped/birthdayparty.h b/examples/qml/referenceexamples/grouped/birthdayparty.h
index 7a9a03dabb..edaa11fa88 100644
--- a/examples/qml/referenceexamples/grouped/birthdayparty.h
+++ b/examples/qml/referenceexamples/grouped/birthdayparty.h
@@ -61,7 +61,7 @@ class BirthdayParty : public QObject
Q_PROPERTY(QQmlListProperty<Person> guests READ guests)
Q_CLASSINFO("DefaultProperty", "guests")
public:
- BirthdayParty(QObject *parent = 0);
+ BirthdayParty(QObject *parent = nullptr);
Person *host() const;
void setHost(Person *);
diff --git a/examples/qml/referenceexamples/grouped/main.cpp b/examples/qml/referenceexamples/grouped/main.cpp
index 17dcd09c34..14cd64fe68 100644
--- a/examples/qml/referenceexamples/grouped/main.cpp
+++ b/examples/qml/referenceexamples/grouped/main.cpp
@@ -66,7 +66,7 @@ int main(int argc, char ** argv)
QQmlEngine engine;
QQmlComponent component(&engine, QUrl("qrc:example.qml"));
- BirthdayParty *party = qobject_cast<BirthdayParty *>(component.create());
+ auto *party = qobject_cast<BirthdayParty *>(component.create());
if (party && party->host()) {
qWarning() << party->host()->name() << "is having a birthday!";
diff --git a/examples/qml/referenceexamples/grouped/person.h b/examples/qml/referenceexamples/grouped/person.h
index b4e6a894cd..6f6caaee7c 100644
--- a/examples/qml/referenceexamples/grouped/person.h
+++ b/examples/qml/referenceexamples/grouped/person.h
@@ -61,7 +61,7 @@ class ShoeDescription : public QObject
Q_PROPERTY(QString brand READ brand WRITE setBrand)
Q_PROPERTY(qreal price READ price WRITE setPrice)
public:
- ShoeDescription(QObject *parent = 0);
+ ShoeDescription(QObject *parent = nullptr);
int size() const;
void setSize(int);
@@ -89,7 +89,7 @@ class Person : public QObject
Q_PROPERTY(ShoeDescription *shoe READ shoe)
// ![1]
public:
- Person(QObject *parent = 0);
+ Person(QObject *parent = nullptr);
QString name() const;
void setName(const QString &);
@@ -104,14 +104,14 @@ class Boy : public Person
{
Q_OBJECT
public:
- Boy(QObject * parent = 0);
+ Boy(QObject * parent = nullptr);
};
class Girl : public Person
{
Q_OBJECT
public:
- Girl(QObject * parent = 0);
+ Girl(QObject * parent = nullptr);
};
#endif // PERSON_H
diff --git a/examples/qml/referenceexamples/methods/birthdayparty.cpp b/examples/qml/referenceexamples/methods/birthdayparty.cpp
index dfb36257eb..7e750e4f4b 100644
--- a/examples/qml/referenceexamples/methods/birthdayparty.cpp
+++ b/examples/qml/referenceexamples/methods/birthdayparty.cpp
@@ -67,7 +67,7 @@ void BirthdayParty::setHost(Person *c)
QQmlListProperty<Person> BirthdayParty::guests()
{
- return QQmlListProperty<Person>(this, m_guests);
+ return {this, m_guests};
}
int BirthdayParty::guestCount() const
@@ -82,7 +82,7 @@ Person *BirthdayParty::guest(int index) const
void BirthdayParty::invite(const QString &name)
{
- Person *person = new Person(this);
+ auto *person = new Person(this);
person->setName(name);
m_guests.append(person);
}
diff --git a/examples/qml/referenceexamples/methods/birthdayparty.h b/examples/qml/referenceexamples/methods/birthdayparty.h
index 27c164728a..0eb968a841 100644
--- a/examples/qml/referenceexamples/methods/birthdayparty.h
+++ b/examples/qml/referenceexamples/methods/birthdayparty.h
@@ -60,7 +60,7 @@ class BirthdayParty : public QObject
Q_PROPERTY(Person *host READ host WRITE setHost)
Q_PROPERTY(QQmlListProperty<Person> guests READ guests)
public:
- BirthdayParty(QObject *parent = 0);
+ BirthdayParty(QObject *parent = nullptr);
Person *host() const;
void setHost(Person *);
diff --git a/examples/qml/referenceexamples/methods/main.cpp b/examples/qml/referenceexamples/methods/main.cpp
index 974cc26338..89404ec822 100644
--- a/examples/qml/referenceexamples/methods/main.cpp
+++ b/examples/qml/referenceexamples/methods/main.cpp
@@ -63,7 +63,7 @@ int main(int argc, char ** argv)
QQmlEngine engine;
QQmlComponent component(&engine, QUrl("qrc:example.qml"));
- BirthdayParty *party = qobject_cast<BirthdayParty *>(component.create());
+ auto *party = qobject_cast<BirthdayParty *>(component.create());
if (party && party->host()) {
qWarning() << party->host()->name() << "is having a birthday!";
diff --git a/examples/qml/referenceexamples/methods/person.h b/examples/qml/referenceexamples/methods/person.h
index 488f8ebac4..749109dc72 100644
--- a/examples/qml/referenceexamples/methods/person.h
+++ b/examples/qml/referenceexamples/methods/person.h
@@ -58,7 +58,7 @@ class Person : public QObject
Q_PROPERTY(QString name READ name WRITE setName)
Q_PROPERTY(int shoeSize READ shoeSize WRITE setShoeSize)
public:
- Person(QObject *parent = 0);
+ Person(QObject *parent = nullptr);
QString name() const;
void setName(const QString &);
diff --git a/examples/qml/referenceexamples/properties/birthdayparty.cpp b/examples/qml/referenceexamples/properties/birthdayparty.cpp
index 717c3e0f71..9abb08dbd9 100644
--- a/examples/qml/referenceexamples/properties/birthdayparty.cpp
+++ b/examples/qml/referenceexamples/properties/birthdayparty.cpp
@@ -67,11 +67,11 @@ void BirthdayParty::setHost(Person *c)
QQmlListProperty<Person> BirthdayParty::guests()
{
- return QQmlListProperty<Person>(this, this,
+ return {this, this,
&BirthdayParty::appendGuest,
&BirthdayParty::guestCount,
&BirthdayParty::guest,
- &BirthdayParty::clearGuests);
+ &BirthdayParty::clearGuests};
}
void BirthdayParty::appendGuest(Person* p) {
diff --git a/examples/qml/referenceexamples/properties/birthdayparty.h b/examples/qml/referenceexamples/properties/birthdayparty.h
index 00c5e443b4..8d62c8dcd5 100644
--- a/examples/qml/referenceexamples/properties/birthdayparty.h
+++ b/examples/qml/referenceexamples/properties/birthdayparty.h
@@ -68,7 +68,7 @@ class BirthdayParty : public QObject
// ![2]
// ![3]
public:
- BirthdayParty(QObject *parent = 0);
+ BirthdayParty(QObject *parent = nullptr);
Person *host() const;
void setHost(Person *);
diff --git a/examples/qml/referenceexamples/properties/main.cpp b/examples/qml/referenceexamples/properties/main.cpp
index fbdbd13fd0..a0a2335034 100644
--- a/examples/qml/referenceexamples/properties/main.cpp
+++ b/examples/qml/referenceexamples/properties/main.cpp
@@ -65,7 +65,7 @@ int main(int argc, char ** argv)
QQmlEngine engine;
QQmlComponent component(&engine, QUrl("qrc:example.qml"));
- BirthdayParty *party = qobject_cast<BirthdayParty *>(component.create());
+ auto *party = qobject_cast<BirthdayParty *>(component.create());
if (party && party->host()) {
qWarning() << party->host()->name() << "is having a birthday!";
diff --git a/examples/qml/referenceexamples/properties/person.h b/examples/qml/referenceexamples/properties/person.h
index 488f8ebac4..749109dc72 100644
--- a/examples/qml/referenceexamples/properties/person.h
+++ b/examples/qml/referenceexamples/properties/person.h
@@ -58,7 +58,7 @@ class Person : public QObject
Q_PROPERTY(QString name READ name WRITE setName)
Q_PROPERTY(int shoeSize READ shoeSize WRITE setShoeSize)
public:
- Person(QObject *parent = 0);
+ Person(QObject *parent = nullptr);
QString name() const;
void setName(const QString &);
diff --git a/examples/qml/referenceexamples/signal/birthdayparty.cpp b/examples/qml/referenceexamples/signal/birthdayparty.cpp
index a5fbb742a5..9d34cdf146 100644
--- a/examples/qml/referenceexamples/signal/birthdayparty.cpp
+++ b/examples/qml/referenceexamples/signal/birthdayparty.cpp
@@ -82,7 +82,7 @@ void BirthdayParty::setHost(Person *c)
QQmlListProperty<Person> BirthdayParty::guests()
{
- return QQmlListProperty<Person>(this, m_guests);
+ return {this, m_guests};
}
int BirthdayParty::guestCount() const
diff --git a/examples/qml/referenceexamples/signal/birthdayparty.h b/examples/qml/referenceexamples/signal/birthdayparty.h
index 759450691e..9aecc8929c 100644
--- a/examples/qml/referenceexamples/signal/birthdayparty.h
+++ b/examples/qml/referenceexamples/signal/birthdayparty.h
@@ -76,7 +76,7 @@ class BirthdayParty : public QObject
Q_PROPERTY(QQmlListProperty<Person> guests READ guests)
Q_CLASSINFO("DefaultProperty", "guests")
public:
- BirthdayParty(QObject *parent = 0);
+ BirthdayParty(QObject *parent = nullptr);
Person *host() const;
void setHost(Person *);
diff --git a/examples/qml/referenceexamples/signal/main.cpp b/examples/qml/referenceexamples/signal/main.cpp
index 7e096edd78..bb75e02bc2 100644
--- a/examples/qml/referenceexamples/signal/main.cpp
+++ b/examples/qml/referenceexamples/signal/main.cpp
@@ -67,7 +67,7 @@ int main(int argc, char ** argv)
QQmlEngine engine;
QQmlComponent component(&engine, QUrl("qrc:example.qml"));
- BirthdayParty *party = qobject_cast<BirthdayParty *>(component.create());
+ auto *party = qobject_cast<BirthdayParty *>(component.create());
if (party && party->host()) {
qWarning() << party->host()->name() << "is having a birthday!";
diff --git a/examples/qml/referenceexamples/signal/person.h b/examples/qml/referenceexamples/signal/person.h
index 9b63773d49..06d4f2eb27 100644
--- a/examples/qml/referenceexamples/signal/person.h
+++ b/examples/qml/referenceexamples/signal/person.h
@@ -61,7 +61,7 @@ class ShoeDescription : public QObject
Q_PROPERTY(QString brand READ brand WRITE setBrand)
Q_PROPERTY(qreal price READ price WRITE setPrice)
public:
- ShoeDescription(QObject *parent = 0);
+ ShoeDescription(QObject *parent = nullptr);
int size() const;
void setSize(int);
@@ -87,7 +87,7 @@ class Person : public QObject
Q_PROPERTY(QString name READ name WRITE setName)
Q_PROPERTY(ShoeDescription *shoe READ shoe)
public:
- Person(QObject *parent = 0);
+ Person(QObject *parent = nullptr);
QString name() const;
void setName(const QString &);
@@ -102,14 +102,14 @@ class Boy : public Person
{
Q_OBJECT
public:
- Boy(QObject * parent = 0);
+ Boy(QObject * parent = nullptr);
};
class Girl : public Person
{
Q_OBJECT
public:
- Girl(QObject * parent = 0);
+ Girl(QObject * parent = nullptr);
};
#endif // PERSON_H
diff --git a/examples/qml/referenceexamples/valuesource/birthdayparty.cpp b/examples/qml/referenceexamples/valuesource/birthdayparty.cpp
index b107c61570..68d5767e8d 100644
--- a/examples/qml/referenceexamples/valuesource/birthdayparty.cpp
+++ b/examples/qml/referenceexamples/valuesource/birthdayparty.cpp
@@ -82,7 +82,7 @@ void BirthdayParty::setHost(Person *c)
QQmlListProperty<Person> BirthdayParty::guests()
{
- return QQmlListProperty<Person>(this, m_guests);
+ return {this, m_guests};
}
int BirthdayParty::guestCount() const
diff --git a/examples/qml/referenceexamples/valuesource/birthdayparty.h b/examples/qml/referenceexamples/valuesource/birthdayparty.h
index f965695cf6..18a9b96147 100644
--- a/examples/qml/referenceexamples/valuesource/birthdayparty.h
+++ b/examples/qml/referenceexamples/valuesource/birthdayparty.h
@@ -80,7 +80,7 @@ class BirthdayParty : public QObject
// ![0]
Q_CLASSINFO("DefaultProperty", "guests")
public:
- BirthdayParty(QObject *parent = 0);
+ BirthdayParty(QObject *parent = nullptr);
Person *host() const;
void setHost(Person *);
diff --git a/examples/qml/referenceexamples/valuesource/happybirthdaysong.cpp b/examples/qml/referenceexamples/valuesource/happybirthdaysong.cpp
index d8e4cad963..da09d3d7ba 100644
--- a/examples/qml/referenceexamples/valuesource/happybirthdaysong.cpp
+++ b/examples/qml/referenceexamples/valuesource/happybirthdaysong.cpp
@@ -54,7 +54,7 @@ HappyBirthdaySong::HappyBirthdaySong(QObject *parent)
: QObject(parent), m_line(-1)
{
setName(QString());
- QTimer *timer = new QTimer(this);
+ auto *timer = new QTimer(this);
QObject::connect(timer, &QTimer::timeout, this, &HappyBirthdaySong::advance);
timer->start(1000);
}
diff --git a/examples/qml/referenceexamples/valuesource/happybirthdaysong.h b/examples/qml/referenceexamples/valuesource/happybirthdaysong.h
index 89bd13c295..e2205a4ebb 100644
--- a/examples/qml/referenceexamples/valuesource/happybirthdaysong.h
+++ b/examples/qml/referenceexamples/valuesource/happybirthdaysong.h
@@ -65,9 +65,9 @@ class HappyBirthdaySong : public QObject, public QQmlPropertyValueSource
Q_PROPERTY(QString name READ name WRITE setName)
// ![1]
public:
- HappyBirthdaySong(QObject *parent = 0);
+ HappyBirthdaySong(QObject *parent = nullptr);
- virtual void setTarget(const QQmlProperty &);
+ void setTarget(const QQmlProperty &) override;
// ![1]
QString name() const;
diff --git a/examples/qml/referenceexamples/valuesource/main.cpp b/examples/qml/referenceexamples/valuesource/main.cpp
index 2f3c466935..4bef695fe2 100644
--- a/examples/qml/referenceexamples/valuesource/main.cpp
+++ b/examples/qml/referenceexamples/valuesource/main.cpp
@@ -69,7 +69,7 @@ int main(int argc, char ** argv)
QQmlEngine engine;
QQmlComponent component(&engine, QUrl("qrc:example.qml"));
- BirthdayParty *party = qobject_cast<BirthdayParty *>(component.create());
+ auto *party = qobject_cast<BirthdayParty *>(component.create());
if (party && party->host()) {
qWarning() << party->host()->name() << "is having a birthday!";
diff --git a/examples/qml/referenceexamples/valuesource/person.h b/examples/qml/referenceexamples/valuesource/person.h
index 9b63773d49..06d4f2eb27 100644
--- a/examples/qml/referenceexamples/valuesource/person.h
+++ b/examples/qml/referenceexamples/valuesource/person.h
@@ -61,7 +61,7 @@ class ShoeDescription : public QObject
Q_PROPERTY(QString brand READ brand WRITE setBrand)
Q_PROPERTY(qreal price READ price WRITE setPrice)
public:
- ShoeDescription(QObject *parent = 0);
+ ShoeDescription(QObject *parent = nullptr);
int size() const;
void setSize(int);
@@ -87,7 +87,7 @@ class Person : public QObject
Q_PROPERTY(QString name READ name WRITE setName)
Q_PROPERTY(ShoeDescription *shoe READ shoe)
public:
- Person(QObject *parent = 0);
+ Person(QObject *parent = nullptr);
QString name() const;
void setName(const QString &);
@@ -102,14 +102,14 @@ class Boy : public Person
{
Q_OBJECT
public:
- Boy(QObject * parent = 0);
+ Boy(QObject * parent = nullptr);
};
class Girl : public Person
{
Q_OBJECT
public:
- Girl(QObject * parent = 0);
+ Girl(QObject * parent = nullptr);
};
#endif // PERSON_H
diff --git a/examples/quick/imageelements/content/multi.ico b/examples/quick/imageelements/content/multi.ico
new file mode 100644
index 0000000000..b748ceaa29
--- /dev/null
+++ b/examples/quick/imageelements/content/multi.ico
Binary files differ
diff --git a/examples/quick/imageelements/framestepping.qml b/examples/quick/imageelements/framestepping.qml
new file mode 100644
index 0000000000..f5bad46e7b
--- /dev/null
+++ b/examples/quick/imageelements/framestepping.qml
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.14
+
+Rectangle {
+ width: 480
+ height: 320
+ Image {
+ id: img
+ anchors.centerIn: parent
+ cache: true
+ source: "content/multi.ico"
+
+ Shortcut {
+ sequence: StandardKey.MoveToNextPage
+ enabled: img.currentFrame < img.frameCount - 1
+ onActivated: img.currentFrame++
+ }
+ Shortcut {
+ sequence: StandardKey.MoveToPreviousPage
+ enabled: img.currentFrame > 0
+ onActivated: img.currentFrame--
+ }
+ }
+
+ Text {
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.bottom: parent.bottom
+ anchors.margins: 6
+ horizontalAlignment: Text.AlignHCenter
+ text: "frame " + (img.currentFrame + 1) + " of " + img.frameCount +
+ "\nPress PgUp/PgDn to switch frames"
+ }
+}
diff --git a/examples/quick/imageelements/imageelements.qml b/examples/quick/imageelements/imageelements.qml
index dfb4d24ea6..91f2e034f7 100644
--- a/examples/quick/imageelements/imageelements.qml
+++ b/examples/quick/imageelements/imageelements.qml
@@ -64,6 +64,8 @@ Item {
addExample("AnimatedImage", "An image which plays animated formats", Qt.resolvedUrl("animatedimage.qml"));
addExample("AnimatedSprite", "A simple sprite-based animation", Qt.resolvedUrl("animatedsprite.qml"));
addExample("SpriteSequence", "A sprite-based animation with complex transitions", Qt.resolvedUrl("spritesequence.qml"));
+ addExample("FrameStepping", "A multi-frame non-animated image", Qt.resolvedUrl("framestepping.qml"));
+ addExample("MultiBorderImage", "A multi-frame image with scaled borders", Qt.resolvedUrl("multiframeborderimage.qml"));
}
}
}
diff --git a/examples/quick/imageelements/imageelements.qrc b/examples/quick/imageelements/imageelements.qrc
index 2488fb083b..cedef2204c 100644
--- a/examples/quick/imageelements/imageelements.qrc
+++ b/examples/quick/imageelements/imageelements.qrc
@@ -8,6 +8,7 @@
<file>content/colors-stretch.sci</file>
<file>content/colors.png</file>
<file>content/ImageCell.qml</file>
+ <file>content/multi.ico</file>
<file>content/MyBorderImage.qml</file>
<file>content/qt-logo.png</file>
<file>content/shadow.png</file>
@@ -18,6 +19,8 @@
<file>animatedimage.qml</file>
<file>animatedsprite.qml</file>
<file>borderimage.qml</file>
+ <file>framestepping.qml</file>
+ <file>multiframeborderimage.qml</file>
<file>image.qml</file>
<file>shadows.qml</file>
<file>spritesequence.qml</file>
diff --git a/examples/quick/imageelements/multiframeborderimage.qml b/examples/quick/imageelements/multiframeborderimage.qml
new file mode 100644
index 0000000000..0805ea4243
--- /dev/null
+++ b/examples/quick/imageelements/multiframeborderimage.qml
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.14
+
+Rectangle {
+ width: 480
+ height: 320
+ BorderImage {
+ id: img
+ anchors.fill: parent
+ anchors.margins: 6
+ cache: true
+ source: "content/multi.ico"
+ border { left: 19; top: 19; right: 19; bottom: 19 }
+ horizontalTileMode: BorderImage.Stretch
+
+ Shortcut {
+ sequence: StandardKey.MoveToNextPage
+ enabled: img.currentFrame < img.frameCount - 1
+ onActivated: img.currentFrame++
+ }
+ Shortcut {
+ sequence: StandardKey.MoveToPreviousPage
+ enabled: img.currentFrame > 0
+ onActivated: img.currentFrame--
+ }
+ }
+
+ Text {
+ anchors.centerIn: parent
+ horizontalAlignment: Text.AlignHCenter
+ text: "frame " + (img.currentFrame + 1) + " of " + img.frameCount +
+ "\nPress PgUp/PgDn to switch frames"
+ }
+}
diff --git a/examples/quick/scenegraph/d3d11underqml/doc/images/d3d11underqml-example.jpg b/examples/quick/scenegraph/d3d11underqml/doc/images/d3d11underqml-example.jpg
new file mode 100644
index 0000000000..9f1e53ad61
--- /dev/null
+++ b/examples/quick/scenegraph/d3d11underqml/doc/images/d3d11underqml-example.jpg
Binary files differ
diff --git a/examples/quick/scenegraph/d3d11underqml/doc/src/d3d11underqml.qdoc b/examples/quick/scenegraph/d3d11underqml/doc/src/d3d11underqml.qdoc
new file mode 100644
index 0000000000..d7b60d3b81
--- /dev/null
+++ b/examples/quick/scenegraph/d3d11underqml/doc/src/d3d11underqml.qdoc
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** 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. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example scenegraph/d3d11underqml
+ \title Scene Graph - Direct3D 11 Under QML
+ \ingroup qtquickexamples
+ \brief Shows how to render directly with Direct3D 11 under a Qt Quick scene.
+
+ \image d3d11underqml-example.jpg
+
+ The Direct3D 11 Under QML example shows how an application can make use
+ of the \l QQuickWindow::beforeRendering() signal to draw custom
+ D3D11 content under a Qt Quick scene. This signal is emitted at
+ the start of every frame, before the scene graph starts its
+ rendering, thus any D3D11 draw calls that are made as a response
+ to this signal, will stack under the Qt Quick items.
+
+ As an alternative, applications that wish to render D3D11 content
+ on top of the Qt Quick scene, can do so by connecting to the \l
+ QQuickWindow::afterRendering() signal.
+
+ In this example, we will also see how it is possible to have
+ values that are exposed to QML which affect the D3D11
+ rendering. We animate the threshold value using a NumberAnimation
+ in the QML file and this value is used by the HLSL shader
+ program that draws the squircles.
+
+ The example is equivalent in most ways to the \l{Scene Graph - OpenGL Under
+ QML}{OpenGL Under QML} and \l{Scene Graph - Metal Under QML}{Metal Under
+ QML} examples, they all render the same custom content, just via different
+ native APIs.
+
+ */
diff --git a/examples/quick/scenegraph/metalunderqml/doc/images/metalunderqml-example.jpg b/examples/quick/scenegraph/metalunderqml/doc/images/metalunderqml-example.jpg
new file mode 100644
index 0000000000..98085773de
--- /dev/null
+++ b/examples/quick/scenegraph/metalunderqml/doc/images/metalunderqml-example.jpg
Binary files differ
diff --git a/examples/quick/scenegraph/metalunderqml/doc/src/metalunderqml.qdoc b/examples/quick/scenegraph/metalunderqml/doc/src/metalunderqml.qdoc
new file mode 100644
index 0000000000..d499f47de3
--- /dev/null
+++ b/examples/quick/scenegraph/metalunderqml/doc/src/metalunderqml.qdoc
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** 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. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example scenegraph/metalunderqml
+ \title Scene Graph - Metal Under QML
+ \ingroup qtquickexamples
+ \brief Shows how to render directly with Metal under a Qt Quick scene.
+
+ \image metalunderqml-example.jpg
+
+ The Metal Under QML example shows how an application can make use
+ of the \l QQuickWindow::beforeRendering() and \l
+ QQuickWindow::beforeRenderPassRecording() signals to draw custom
+ Metal content under a Qt Quick scene. This signal is emitted at
+ the start of every frame, before the scene graph starts its
+ rendering, thus any Metal draw calls that are made as a response
+ to this signal, will stack under the Qt Quick items. There are two
+ signals, because the custom Metal commands are recorded onto the
+ same command buffer with the same render command encoder that the
+ scene graph uses. beforeRendering() on its own is not sufficient
+ for this because it gets emitted at the start of the frame, before
+ having an
+ \l{https://developer.apple.com/documentation/metal/mtlrendercommandencoder}{MTLRenderCommandEncoder}
+ available. By also connecting to beforeRenderPassRecording(), the
+ application can gain access to the necessary native objects.
+
+ As an alternative, applications that wish to render Metal content
+ on top of the Qt Quick scene, can do so by connecting to the \l
+ QQuickWindow::afterRendering() and \l
+ QQuickWindow::afterRenderPassRecording() signals.
+
+ In this example, we will also see how it is possible to have
+ values that are exposed to QML which affect the Metal
+ rendering. We animate the threshold value using a NumberAnimation
+ in the QML file and this value is used by the Metal shader
+ program that draws the squircles.
+
+ The example is equivalent in most ways to the \l{Scene Graph - OpenGL Under
+ QML}{OpenGL Under QML} and \l{Scene Graph - Direct3D 11 Under QML}{Direct3D
+ 11 Under QML} examples, they all render the same custom content, just via
+ different native APIs.
+
+ */
diff --git a/examples/quick/scenegraph/openglunderqml/doc/src/openglunderqml.qdoc b/examples/quick/scenegraph/openglunderqml/doc/src/openglunderqml.qdoc
index 69a9d2ce4b..ed46b40420 100644
--- a/examples/quick/scenegraph/openglunderqml/doc/src/openglunderqml.qdoc
+++ b/examples/quick/scenegraph/openglunderqml/doc/src/openglunderqml.qdoc
@@ -50,6 +50,11 @@
in the QML file and this value is used by the OpenGL shader
program that draws the squircles.
+ The example is equivalent in most ways to the \l{Scene Graph - Direct3D 11 Under
+ QML}{Direct3D 11 Under QML} and \l{Scene Graph - Metal Under QML}{Metal Under
+ QML} examples, they all render the same custom content, just via different
+ native APIs.
+
\snippet scenegraph/openglunderqml/squircle.h 2
First of all, we need an object we can expose to QML. This is a
diff --git a/examples/quick/scenegraph/rendernode/customrenderitem.cpp b/examples/quick/scenegraph/rendernode/customrenderitem.cpp
index 8f248e2ecb..67a9cccfc6 100644
--- a/examples/quick/scenegraph/rendernode/customrenderitem.cpp
+++ b/examples/quick/scenegraph/rendernode/customrenderitem.cpp
@@ -53,16 +53,20 @@
#include <QSGRendererInterface>
#include "openglrenderer.h"
+#include "metalrenderer.h"
#include "d3d12renderer.h"
#include "softwarerenderer.h"
+//! [1]
CustomRenderItem::CustomRenderItem(QQuickItem *parent)
: QQuickItem(parent)
{
// Our item shows something so set the flag.
setFlag(ItemHasContents);
}
+//! [1]
+//! [2]
QSGNode *CustomRenderItem::updatePaintNode(QSGNode *node, UpdatePaintNodeData *)
{
QSGRenderNode *n = static_cast<QSGRenderNode *>(node);
@@ -71,24 +75,46 @@ QSGNode *CustomRenderItem::updatePaintNode(QSGNode *node, UpdatePaintNodeData *)
if (!ri)
return nullptr;
switch (ri->graphicsApi()) {
- case QSGRendererInterface::OpenGL:
+ case QSGRendererInterface::OpenGL:
+ Q_FALLTHROUGH();
+ case QSGRendererInterface::OpenGLRhi:
#if QT_CONFIG(opengl)
- n = new OpenGLRenderNode(this);
- break;
+ n = new OpenGLRenderNode(this);
#endif
- case QSGRendererInterface::Direct3D12:
+ break;
+
+ case QSGRendererInterface::MetalRhi:
+#ifdef Q_OS_DARWIN
+ {
+ MetalRenderNode *metalNode = new MetalRenderNode(this);
+ n = metalNode;
+ metalNode->resourceBuilder()->setWindow(window());
+ QObject::connect(window(), &QQuickWindow::beforeRendering,
+ metalNode->resourceBuilder(), &MetalRenderNodeResourceBuilder::build);
+ }
+#endif
+ break;
+
+ case QSGRendererInterface::Direct3D12: // ### Qt 6: remove
#if QT_CONFIG(d3d12)
- n = new D3D12RenderNode(this);
- break;
+ n = new D3D12RenderNode(this);
#endif
- case QSGRendererInterface::Software:
- n = new SoftwareRenderNode(this);
- break;
+ break;
+
+ case QSGRendererInterface::Software:
+ n = new SoftwareRenderNode(this);
+ break;
- default:
- return nullptr;
+ default:
+ break;
}
+ if (!n)
+ qWarning("QSGRendererInterface reports unknown graphics API %d", ri->graphicsApi());
}
return n;
}
+//! [2]
+
+// This item does not support being moved between windows. If that is desired,
+// itemChange() should be reimplemented as well.
diff --git a/examples/quick/scenegraph/rendernode/d3d12renderer.cpp b/examples/quick/scenegraph/rendernode/d3d12renderer.cpp
index df0e29eb67..878b022950 100644
--- a/examples/quick/scenegraph/rendernode/d3d12renderer.cpp
+++ b/examples/quick/scenegraph/rendernode/d3d12renderer.cpp
@@ -54,6 +54,8 @@
#include <QSGRendererInterface>
#include <QFile>
+// ### Qt 6: remove
+
#if QT_CONFIG(d3d12)
D3D12RenderNode::D3D12RenderNode(QQuickItem *item)
@@ -166,8 +168,8 @@ void D3D12RenderNode::init()
psoDesc.RasterizerState = rastDesc;
psoDesc.BlendState = blendDesc;
// No depth. The correct stacking of the item is ensured by the projection matrix.
- // Do not bother with stencil since we do not apply clipping in the
- // example. If clipping is desired, render() needs to set a different PSO
+ // Note that this does not support clipping.
+ // If clipping is desired, render() needs to set a different PSO
// with stencil enabled whenever the RenderState indicates so.
psoDesc.SampleMask = UINT_MAX;
psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
diff --git a/examples/quick/scenegraph/rendernode/doc/images/rendernode-example.jpg b/examples/quick/scenegraph/rendernode/doc/images/rendernode-example.jpg
new file mode 100644
index 0000000000..cbb59b950d
--- /dev/null
+++ b/examples/quick/scenegraph/rendernode/doc/images/rendernode-example.jpg
Binary files differ
diff --git a/examples/quick/scenegraph/rendernode/doc/src/rendernode.qdoc b/examples/quick/scenegraph/rendernode/doc/src/rendernode.qdoc
new file mode 100644
index 0000000000..ba6551fddf
--- /dev/null
+++ b/examples/quick/scenegraph/rendernode/doc/src/rendernode.qdoc
@@ -0,0 +1,165 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** 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. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example scenegraph/rendernode
+ \title Scene Graph - Custom Rendering with QSGRenderNode
+ \ingroup qtquickexamples
+ \brief Shows how to integrate drawing via the native graphics API with the Qt Quick scene graph.
+
+ \image rendernode-example.jpg
+
+ \l QSGRenderNode allows integrating draw and other calls made directly via
+ the Qt Quick scene graph's underlying native graphics API (such as, Vulkan,
+ Metal, Direct 3D, or OpenGL). This example demonstrates implementing a
+ custom QQuickItem backed by a QSGRenderNode implementation, where the node
+ renders a triangle directly via the graphics API. The rest of the scene
+ (background, text, rectangles) are standard Qt Quick items. The example has
+ full support for OpenGL and Metal, as well as the software backend of Qt
+ Quick.
+
+ The custom item behaves like any other Qt Quick item, meaning it
+ participates and stacking and clipping as usual, which is a big difference
+ to the alternative approaches like having the custom rendering as an
+ overlay (connecting to \l QQuickWindow::afterRendering()) and underlay
+ (connecting to \l QQuickWindow::beforeRendering()) because those do not
+ offer the possibility of proper mixing of the custom content with the Qt
+ Quick scene.
+
+ Another important feature is that QSGRenderNode can be helpful to preserve
+ performance, when compared to some of the alternatives. Going through \l
+ QQuickFramebufferObject allows creating a custom item similarly to what
+ this example does, but it does it by rendering the custom content in a
+ texture, and then drawing a textured quad with that texture. This can be
+ expensive on some systems due to the cost of texturing and blending.
+ QSGRenderNode avoids this since the native graphics calls are issued in
+ line with the draw calls for the scene graph's batches.
+
+ All this comes at the cost of being more complex, and not necessarily being
+ suitable for all types of 3D content, in particular where vertices and
+ different depth would clash with the 2D content in the Qt Quick scene
+ graph's batches (those are better served by "flattening" into a 2D texture
+ via approaches like QQuickFramebufferObject). Therefore QSGRenderNode is
+ not always the right choice. It can however a good and powerful choice in
+ many cases. This is what the example demonstrates.
+
+ Let's go through the most important parts of the code:
+
+ \snippet scenegraph/rendernode/main.cpp 1
+
+ Our custom QML type is implemented in the class CustomRenderItem.
+
+ \snippet scenegraph/rendernode/main.qml 2
+
+ The corresponding import in the QML document.
+
+ \snippet scenegraph/rendernode/main.qml 3
+
+ The CustomRenderItem object. It is positioned to fill a big part of the
+ scene, covering its parent (the yellow rectangle; this will be used to
+ demonstrate clipping). The item will have its scale and rotation animated.
+
+ \snippet scenegraph/rendernode/main.qml 4
+
+ Text items are used to show some helpful information, such as, the
+ active graphics API Qt Quick uses.
+
+ \snippet scenegraph/rendernode/main.qml 5
+
+ Clicking the left mouse button is used to toggle clipping on the custom
+ item's parent item. By default this is done using scissoring (GL_SCISSOR_TEST
+ with OpenGL). A well-written QSGRenderNode implementation is expected to be
+ able to take this into account and enable scissor testing when the scene graph
+ indicates that it is necessary.
+
+ The right mouse button is used to toggle an animation on the rotation of
+ the parent item. With clipping enabled, this demonstrates clipping via the
+ stencil buffer since a rectangular scissor is not appropriate when we need
+ to clip to a rotated rectangle shape. The scene graph fills up the stencil
+ buffer as necessary, the QSGRenderNode implementation just has to enable
+ stencil testing using the provided reference value.
+
+ \snippet scenegraph/rendernode/customrenderitem.cpp 1
+
+ Moving on to the CustomRenderItem implementation. This is a visual item.
+
+ \snippet scenegraph/rendernode/customrenderitem.cpp 2
+
+ The implementation of \l QQuickItem::updatePaintNode() creates (if not yet
+ done) and returns an instance of a suitable QSGRenderNode subclass. The
+ example supports multiple graphics APIs, and also the \c software backend.
+
+ Let's look at the the render node for OpenGL (supporting both the
+ traditional, direct OpenGL-based scene graph, and also the modern,
+ abstracted variant using the RHI). For other graphics APIs, the concepts
+ and the outline of a QSGRenderNode implementation are the same. It is worth
+ noting that in some cases it will also be necessary to connect to a signal
+ like \l QQuickWindow::beforeRendering() to perform copy type of operations
+ (such as, vertex buffer uploads). This is not necessary for OpenGL, but it
+ is essential for Vulkan or Metal since there such operations cannot be
+ issued in render() as there is a renderpass being recorded when render() is
+ called.
+
+ \snippet scenegraph/rendernode/openglrenderer.h 1
+
+ The main job is to provide implementations of the virtual QSGRenderNode functions.
+
+ \snippet scenegraph/rendernode/openglrenderer.cpp 1
+
+ The pattern for safe graphics resource management is to do any cleanup in
+ \l{QSGRenderNode::releaseResources()}{releaseResources()}, while also
+ calling this from the destructor.
+
+ \snippet scenegraph/rendernode/openglrenderer.cpp 2
+
+ The render() function initializes graphics resources (in this case, an
+ OpenGL shader program and a vertex buffer), if not yet done. It then
+ makes sure the necessary resources are bound and updates uniforms.
+ The transformation matrix and the opacity are provided by the scene graph
+ either via the \c state argument or base class functions.
+
+ \snippet scenegraph/rendernode/openglrenderer.cpp 5
+
+ This render node is well-behaving since it basically renders in 2D,
+ respecting the item's geometry. This is not mandatory, but then flags() has
+ to return (or not return) the appropriate flags.
+
+ \snippet scenegraph/rendernode/openglrenderer.cpp 3
+
+ After setting up vertex inputs, but before recording a draw call for our
+ triangle, it is important to set some state in order to integrate with the
+ rest of the scene correctly. Setting scissor and stencil as instructed by
+ \c state allows our item to render correctly even when there are one or
+ more clips in the parent chain.
+
+ \snippet scenegraph/rendernode/openglrenderer.cpp 4
+
+ As shown above, we only really render in 2D (no depth), within the item's
+ geometry. changedStates() returns the flags corresponding to the OpenGL
+ states render() touches.
+
+*/
diff --git a/examples/quick/scenegraph/rendernode/main.cpp b/examples/quick/scenegraph/rendernode/main.cpp
index 21419abfc9..146d787e50 100644
--- a/examples/quick/scenegraph/rendernode/main.cpp
+++ b/examples/quick/scenegraph/rendernode/main.cpp
@@ -58,7 +58,9 @@ int main(int argc, char **argv)
{
QGuiApplication app(argc, argv);
+//! [1]
qmlRegisterType<CustomRenderItem>("SceneGraphRendering", 2, 0, "CustomRenderItem");
+//! [1]
QQuickView view;
diff --git a/examples/quick/scenegraph/rendernode/main.qml b/examples/quick/scenegraph/rendernode/main.qml
index d0ba4a4669..153a71e097 100644
--- a/examples/quick/scenegraph/rendernode/main.qml
+++ b/examples/quick/scenegraph/rendernode/main.qml
@@ -49,27 +49,65 @@
****************************************************************************/
import QtQuick 2.8
+//! [2]
import SceneGraphRendering 2.0
+//! [2]
Item {
Rectangle {
+ id: bg
anchors.fill: parent
gradient: Gradient {
GradientStop { position: 0; color: "steelblue" }
GradientStop { position: 1; color: "black" }
}
- CustomRenderItem {
- id: renderer
+ //! [5]
+ MouseArea {
anchors.fill: parent
- anchors.margins: 10
+ acceptedButtons: Qt.LeftButton | Qt.RightButton
+ onClicked: {
+ if (mouse.button === Qt.LeftButton) {
+ clipper.clip = !clipper.clip
+ } else if (mouse.button === Qt.RightButton) {
+ nonRectClipAnim.running = !nonRectClipAnim.running
+ if (!nonRectClipAnim.running)
+ clipper.rotation = 0;
+ }
+ }
+ }
+ // ![5]
+
+ Rectangle {
+ id: clipper
+ width: parent.width / 2
+ height: parent.height / 2
+ anchors.centerIn: parent
+ border.color: "yellow"
+ border.width: 2
+ color: "transparent"
+ NumberAnimation on rotation {
+ id: nonRectClipAnim
+ from: 0; to: 360; duration: 5000; loops: Animation.Infinite
+ running: false
+ }
+
+ //! [3]
+ CustomRenderItem {
+ id: renderer
+ width: bg.width - 20
+ height: bg.height - 20
+ x: -clipper.x + 10
+ y: -clipper.y + 10
- transform: [
- Rotation { id: rotation; axis.x: 0; axis.z: 0; axis.y: 1; angle: 0; origin.x: renderer.width / 2; origin.y: renderer.height / 2; },
- Translate { id: txOut; x: -renderer.width / 2; y: -renderer.height / 2 },
- Scale { id: scale; },
- Translate { id: txIn; x: renderer.width / 2; y: renderer.height / 2 }
- ]
+ transform: [
+ Rotation { id: rotation; axis.x: 0; axis.z: 0; axis.y: 1; angle: 0; origin.x: renderer.width / 2; origin.y: renderer.height / 2; },
+ Translate { id: txOut; x: -renderer.width / 2; y: -renderer.height / 2 },
+ Scale { id: scale; },
+ Translate { id: txIn; x: renderer.width / 2; y: renderer.height / 2 }
+ ]
+ }
+ //! [3]
}
SequentialAnimation {
@@ -92,19 +130,39 @@ Item {
loops: Animation.Infinite
}
+ //! [4]
Text {
id: label
- anchors.bottom: renderer.bottom
- anchors.left: renderer.left
- anchors.right: renderer.right
+ anchors.bottom: parent.bottom
+ anchors.left: parent.left
anchors.margins: 20
+ color: "yellow"
wrapMode: Text.WordWrap
property int api: GraphicsInfo.api
- text: "Custom rendering via the graphics API "
- + (api === GraphicsInfo.OpenGL ? "OpenGL"
- : api === GraphicsInfo.Direct3D12 ? "Direct3D 12"
- : api === GraphicsInfo.Software ? "Software" : "")
+ text: {
+ var apiStr;
+ switch (api) {
+ case GraphicsInfo.OpenGL: apiStr = "OpenGL (direct)"; break;
+ case GraphicsInfo.Direct3D12: apiStr = "Direct3D 12 (direct)"; break;
+ case GraphicsInfo.Software: apiStr = "Software (QPainter)"; break;
+ case GraphicsInfo.OpenGLRhi: apiStr = "OpenGL (RHI)"; break;
+ case GraphicsInfo.MetalRhi: apiStr = "Metal (RHI)"; break;
+ // the example has no other QSGRenderNode subclasses
+ default: apiStr = "<UNSUPPORTED>"; break;
+ }
+ "Custom rendering via the graphics API " + apiStr
+ + "\nLeft click to toggle clipping to yellow rect"
+ + "\nRight click to rotate (can be used to exercise stencil clip instead of scissor)"
+ }
+ // ![4]
+ }
+
+ Text {
+ id: label2
+ anchors.top: parent.top
+ anchors.right: parent.right
color: "yellow"
+ text: "Clip: " + (clipper.clip ? "ON" : "OFF") + " Rotation: " + (nonRectClipAnim.running ? "ON" : "OFF")
}
}
}
diff --git a/examples/quick/scenegraph/rendernode/metalrenderer.h b/examples/quick/scenegraph/rendernode/metalrenderer.h
new file mode 100644
index 0000000000..77c9892313
--- /dev/null
+++ b/examples/quick/scenegraph/rendernode/metalrenderer.h
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef METALRENDERER_H
+#define METALRENDERER_H
+
+#include <qsgrendernode.h>
+
+#ifdef Q_OS_DARWIN
+
+QT_BEGIN_NAMESPACE
+
+class QQuickItem;
+class QQuickWindow;
+
+QT_END_NAMESPACE
+
+class MetalRenderNodeResourceBuilder : public QObject
+{
+ Q_OBJECT
+
+public:
+ void setWindow(QQuickWindow *w) { m_window = w; }
+
+public slots:
+ void build();
+
+private:
+ QQuickWindow *m_window = nullptr;
+};
+
+class MetalRenderNode : public QSGRenderNode
+{
+public:
+ MetalRenderNode(QQuickItem *item);
+ ~MetalRenderNode();
+
+ void render(const RenderState *state) override;
+ void releaseResources() override;
+ StateFlags changedStates() const override;
+ RenderingFlags flags() const override;
+ QRectF rect() const override;
+
+ MetalRenderNodeResourceBuilder *resourceBuilder() { return &m_resourceBuilder; }
+
+private:
+ QQuickItem *m_item;
+ MetalRenderNodeResourceBuilder m_resourceBuilder;
+};
+
+#endif // Q_OS_DARWIN
+
+#endif
diff --git a/examples/quick/scenegraph/rendernode/metalrenderer.mm b/examples/quick/scenegraph/rendernode/metalrenderer.mm
new file mode 100644
index 0000000000..4cb973abee
--- /dev/null
+++ b/examples/quick/scenegraph/rendernode/metalrenderer.mm
@@ -0,0 +1,326 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "metalrenderer.h"
+#include <QQuickItem>
+#include <QQuickWindow>
+
+#include <Metal/Metal.h>
+
+using FuncAndLib = QPair<id<MTLFunction>, id<MTLLibrary> >;
+
+const int MAX_FRAMES_IN_FLIGHT = 3;
+
+struct {
+ id<MTLDevice> dev = nil;
+ QByteArray vsSource;
+ FuncAndLib vs;
+ QByteArray fsSource;
+ FuncAndLib fs;
+ id<MTLBuffer> vbuf[MAX_FRAMES_IN_FLIGHT];
+ id<MTLBuffer> ubuf[MAX_FRAMES_IN_FLIGHT];
+ id<MTLDepthStencilState> stencilEnabledDsState = nil;
+ id<MTLRenderPipelineState> pipeline = nil;
+} g;
+
+static FuncAndLib compileShaderFromSource(const QByteArray &src, const QByteArray &entryPoint)
+{
+ FuncAndLib fl;
+
+ NSString *srcstr = [NSString stringWithUTF8String: src.constData()];
+ MTLCompileOptions *opts = [[MTLCompileOptions alloc] init];
+ opts.languageVersion = MTLLanguageVersion1_2;
+ NSError *err = nil;
+ fl.second = [g.dev newLibraryWithSource: srcstr options: opts error: &err];
+ [opts release];
+ // srcstr is autoreleased
+
+ if (err) {
+ const QString msg = QString::fromNSString(err.localizedDescription);
+ qFatal("%s", qPrintable(msg));
+ return fl;
+ }
+
+ NSString *name = [NSString stringWithUTF8String: entryPoint.constData()];
+ fl.first = [fl.second newFunctionWithName: name];
+ [name release];
+
+ return fl;
+}
+
+const int VERTEX_SIZE = 6 * sizeof(float);
+
+static float colors[] = {
+ 1.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f
+};
+
+void MetalRenderNodeResourceBuilder::build()
+{
+ if (!g.dev) {
+ QSGRendererInterface *rif = m_window->rendererInterface();
+ Q_ASSERT(rif->graphicsApi() == QSGRendererInterface::MetalRhi);
+
+ g.dev = (id<MTLDevice>) rif->getResource(m_window, QSGRendererInterface::DeviceResource);
+ Q_ASSERT(g.dev);
+ }
+
+ if (g.vsSource.isEmpty()) {
+ const QString filename = QLatin1String(":/scenegraph/rendernode/metalshader.vert");
+ QFile f(filename);
+ if (!f.open(QIODevice::ReadOnly | QIODevice::Text))
+ qFatal("Failed to read shader %s", qPrintable(filename));
+ g.vsSource = f.readAll();
+ g.vs = compileShaderFromSource(g.vsSource, QByteArrayLiteral("main0"));
+ }
+
+ if (g.fsSource.isEmpty()) {
+ const QString filename = QLatin1String(":/scenegraph/rendernode/metalshader.frag");
+ QFile f(filename);
+ if (!f.open(QIODevice::ReadOnly | QIODevice::Text))
+ qFatal("Failed to read shader %s", qPrintable(filename));
+ g.fsSource = f.readAll();
+ g.fs = compileShaderFromSource(g.fsSource, QByteArrayLiteral("main0"));
+ }
+
+ const int framesInFlight = m_window->graphicsStateInfo()->framesInFlight;
+
+ // For simplicity's sake we use shared mode (something like host visible +
+ // host coherent) for everything.
+
+ for (int i = 0; i < framesInFlight; ++i) {
+ // Have multiple versions for vertex too since we'll just memcpy new
+ // vertices based on item width and height on every render(). This could
+ // be optimized further however.
+ if (!g.vbuf[i]) {
+ g.vbuf[i] = [g.dev newBufferWithLength: VERTEX_SIZE + sizeof(colors) options: MTLResourceStorageModeShared];
+ char *p = (char *) [g.vbuf[i] contents];
+ memcpy(p + VERTEX_SIZE, colors, sizeof(colors));
+ }
+
+ if (!g.ubuf[i])
+ g.ubuf[i] = [g.dev newBufferWithLength: 256 options: MTLResourceStorageModeShared];
+ }
+
+ if (!g.stencilEnabledDsState) {
+ MTLDepthStencilDescriptor *dsDesc = [[MTLDepthStencilDescriptor alloc] init];
+ dsDesc.frontFaceStencil = [[MTLStencilDescriptor alloc] init];
+ dsDesc.frontFaceStencil.stencilFailureOperation = MTLStencilOperationKeep;
+ dsDesc.frontFaceStencil.depthFailureOperation = MTLStencilOperationKeep;
+ dsDesc.frontFaceStencil.depthStencilPassOperation = MTLStencilOperationKeep;
+ dsDesc.frontFaceStencil.stencilCompareFunction = MTLCompareFunctionEqual;
+ dsDesc.frontFaceStencil.readMask = 0xFF;
+ dsDesc.frontFaceStencil.writeMask = 0xFF;
+
+ dsDesc.backFaceStencil = [[MTLStencilDescriptor alloc] init];
+ dsDesc.backFaceStencil.stencilFailureOperation = MTLStencilOperationKeep;
+ dsDesc.backFaceStencil.depthFailureOperation = MTLStencilOperationKeep;
+ dsDesc.backFaceStencil.depthStencilPassOperation = MTLStencilOperationKeep;
+ dsDesc.backFaceStencil.stencilCompareFunction = MTLCompareFunctionEqual;
+ dsDesc.backFaceStencil.readMask = 0xFF;
+ dsDesc.backFaceStencil.writeMask = 0xFF;
+
+ g.stencilEnabledDsState = [g.dev newDepthStencilStateWithDescriptor: dsDesc];
+ [dsDesc release];
+ }
+
+ if (!g.pipeline) {
+ MTLVertexDescriptor *inputLayout = [MTLVertexDescriptor vertexDescriptor];
+ inputLayout.attributes[0].format = MTLVertexFormatFloat2;
+ inputLayout.attributes[0].offset = 0;
+ inputLayout.attributes[0].bufferIndex = 1; // ubuf is 0, vbuf is 1 and 2
+ inputLayout.attributes[1].format = MTLVertexFormatFloat3;
+ inputLayout.attributes[1].offset = 0;
+ inputLayout.attributes[1].bufferIndex = 2;
+ inputLayout.layouts[1].stride = 2 * sizeof(float);
+ inputLayout.layouts[2].stride = 3 * sizeof(float);
+
+ MTLRenderPipelineDescriptor *rpDesc = [[MTLRenderPipelineDescriptor alloc] init];
+ rpDesc.vertexDescriptor = inputLayout;
+
+ rpDesc.vertexFunction = g.vs.first;
+ rpDesc.fragmentFunction = g.fs.first;
+
+ rpDesc.colorAttachments[0].pixelFormat = MTLPixelFormatBGRA8Unorm;
+ rpDesc.colorAttachments[0].blendingEnabled = true;
+ rpDesc.colorAttachments[0].sourceRGBBlendFactor = MTLBlendFactorOne;
+ rpDesc.colorAttachments[0].sourceAlphaBlendFactor = MTLBlendFactorOne;
+ rpDesc.colorAttachments[0].destinationRGBBlendFactor = MTLBlendFactorOneMinusSourceAlpha;
+ rpDesc.colorAttachments[0].destinationAlphaBlendFactor = MTLBlendFactorOneMinusSourceAlpha;
+
+ if (g.dev.depth24Stencil8PixelFormatSupported) {
+ rpDesc.depthAttachmentPixelFormat = MTLPixelFormatDepth24Unorm_Stencil8;
+ rpDesc.stencilAttachmentPixelFormat = MTLPixelFormatDepth24Unorm_Stencil8;
+ } else {
+ rpDesc.depthAttachmentPixelFormat = MTLPixelFormatDepth32Float_Stencil8;
+ rpDesc.stencilAttachmentPixelFormat = MTLPixelFormatDepth32Float_Stencil8;
+ }
+
+ NSError *err = nil;
+ g.pipeline = [g.dev newRenderPipelineStateWithDescriptor: rpDesc error: &err];
+ if (!g.pipeline) {
+ const QString msg = QString::fromNSString(err.localizedDescription);
+ qFatal("Failed to create render pipeline state: %s", qPrintable(msg));
+ }
+ [rpDesc release];
+ }
+}
+
+MetalRenderNode::MetalRenderNode(QQuickItem *item)
+ : m_item(item)
+{
+ g.vs.first = g.fs.first = nil;
+ g.vs.second = g.fs.second = nil;
+
+ for (int i = 0; i < MAX_FRAMES_IN_FLIGHT; ++i) {
+ g.vbuf[i] = nil;
+ g.ubuf[i] = nil;
+ }
+}
+
+MetalRenderNode::~MetalRenderNode()
+{
+ releaseResources();
+}
+
+void MetalRenderNode::releaseResources()
+{
+ [g.stencilEnabledDsState release];
+ g.stencilEnabledDsState = nil;
+
+ [g.pipeline release];
+ g.pipeline = nil;
+
+ [g.vs.first release];
+ [g.vs.second release];
+
+ [g.fs.first release];
+ [g.fs.second release];
+
+ g.vs.first = g.fs.first = nil;
+ g.vs.second = g.fs.second = nil;
+
+ for (int i = 0; i < MAX_FRAMES_IN_FLIGHT; ++i) {
+ [g.vbuf[i] release];
+ g.vbuf[i] = nil;
+ [g.ubuf[i] release];
+ g.ubuf[i] = nil;
+ }
+}
+
+void MetalRenderNode::render(const RenderState *state)
+{
+ QQuickWindow *window = m_item->window();
+ const QQuickWindow::GraphicsStateInfo *stateInfo = window->graphicsStateInfo();
+ id<MTLBuffer> vbuf = g.vbuf[stateInfo->currentFrameSlot];
+ id<MTLBuffer> ubuf = g.ubuf[stateInfo->currentFrameSlot];
+
+ QPointF p0(m_item->width() - 1, m_item->height() - 1);
+ QPointF p1(0, 0);
+ QPointF p2(0, m_item->height() - 1);
+
+ float vertices[6] = { float(p0.x()), float(p0.y()),
+ float(p1.x()), float(p1.y()),
+ float(p2.x()), float(p2.y()) };
+ char *p = (char *) [vbuf contents];
+ memcpy(p, vertices, VERTEX_SIZE);
+
+ const QMatrix4x4 mvp = *state->projectionMatrix() * *matrix();
+ const float opacity = inheritedOpacity();
+
+ p = (char *) [ubuf contents];
+ memcpy(p, mvp.constData(), 64);
+ memcpy(p + 64, &opacity, 4);
+
+ QSGRendererInterface *rif = window->rendererInterface();
+ id<MTLRenderCommandEncoder> encoder = (id<MTLRenderCommandEncoder>) rif->getResource(
+ window, QSGRendererInterface::CommandEncoderResource);
+ Q_ASSERT(encoder);
+
+ [encoder setVertexBuffer: vbuf offset: 0 atIndex: 1];
+ [encoder setVertexBuffer: vbuf offset: VERTEX_SIZE atIndex: 2];
+
+ [encoder setVertexBuffer: ubuf offset: 0 atIndex: 0];
+ [encoder setFragmentBuffer: ubuf offset: 0 atIndex: 0];
+
+ // Clip support.
+ if (state->scissorEnabled()) {
+ const QRect r = state->scissorRect(); // bottom-up
+ MTLScissorRect s;
+ s.x = r.x();
+ s.y = (window->height() * window->effectiveDevicePixelRatio()) - (r.y() + r.height());
+ s.width = r.width();
+ s.height = r.height();
+ [encoder setScissorRect: s];
+ }
+ if (state->stencilEnabled()) {
+ [encoder setDepthStencilState: g.stencilEnabledDsState];
+ [encoder setStencilReferenceValue: state->stencilValue()];
+ }
+
+ [encoder setRenderPipelineState: g.pipeline];
+ [encoder drawPrimitives: MTLPrimitiveTypeTriangle vertexStart: 0 vertexCount: 3 instanceCount: 1 baseInstance: 0];
+}
+
+QSGRenderNode::StateFlags MetalRenderNode::changedStates() const
+{
+ return BlendState | ScissorState | StencilState;
+}
+
+QSGRenderNode::RenderingFlags MetalRenderNode::flags() const
+{
+ return BoundedRectRendering | DepthAwareRendering;
+}
+
+QRectF MetalRenderNode::rect() const
+{
+ return QRect(0, 0, m_item->width(), m_item->height());
+}
diff --git a/examples/quick/scenegraph/rendernode/metalshader.frag b/examples/quick/scenegraph/rendernode/metalshader.frag
new file mode 100644
index 0000000000..907faa537f
--- /dev/null
+++ b/examples/quick/scenegraph/rendernode/metalshader.frag
@@ -0,0 +1,28 @@
+#include <metal_stdlib>
+#include <simd/simd.h>
+
+using namespace metal;
+
+struct buf
+{
+ float4x4 matrix;
+ float opacity;
+};
+
+struct main0_out
+{
+ float4 fragColor [[color(0)]];
+};
+
+struct main0_in
+{
+ float4 v_color [[user(locn0)]];
+};
+
+fragment main0_out main0(main0_in in [[stage_in]], constant buf& ubuf [[buffer(0)]])
+{
+ main0_out out = {};
+ out.fragColor = in.v_color * ubuf.opacity;
+ return out;
+}
+
diff --git a/examples/quick/scenegraph/rendernode/metalshader.vert b/examples/quick/scenegraph/rendernode/metalshader.vert
new file mode 100644
index 0000000000..12b721f524
--- /dev/null
+++ b/examples/quick/scenegraph/rendernode/metalshader.vert
@@ -0,0 +1,31 @@
+#include <metal_stdlib>
+#include <simd/simd.h>
+
+using namespace metal;
+
+struct buf
+{
+ float4x4 matrix;
+ float opacity;
+};
+
+struct main0_out
+{
+ float4 v_color [[user(locn0)]];
+ float4 gl_Position [[position]];
+};
+
+struct main0_in
+{
+ float4 pos [[attribute(0)]];
+ float4 color [[attribute(1)]];
+};
+
+vertex main0_out main0(main0_in in [[stage_in]], constant buf& ubuf [[buffer(0)]])
+{
+ main0_out out = {};
+ out.v_color = in.color;
+ out.gl_Position = ubuf.matrix * in.pos;
+ return out;
+}
+
diff --git a/examples/quick/scenegraph/rendernode/openglrenderer.cpp b/examples/quick/scenegraph/rendernode/openglrenderer.cpp
index 3c68830db6..0633731617 100644
--- a/examples/quick/scenegraph/rendernode/openglrenderer.cpp
+++ b/examples/quick/scenegraph/rendernode/openglrenderer.cpp
@@ -57,6 +57,7 @@
#include <QOpenGLBuffer>
#include <QOpenGLFunctions>
+//! [1]
OpenGLRenderNode::OpenGLRenderNode(QQuickItem *item)
: m_item(item)
{
@@ -74,6 +75,7 @@ void OpenGLRenderNode::releaseResources()
delete m_vbo;
m_vbo = nullptr;
}
+//! [1]
void OpenGLRenderNode::init()
{
@@ -121,19 +123,21 @@ void OpenGLRenderNode::init()
m_vbo->release();
}
+//! [2]
void OpenGLRenderNode::render(const RenderState *state)
{
if (!m_program)
init();
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
-
m_program->bind();
m_program->setUniformValue(m_matrixUniform, *state->projectionMatrix() * *matrix());
m_program->setUniformValue(m_opacityUniform, float(inheritedOpacity()));
+//! [2]
m_vbo->bind();
+//! [5]
QPointF p0(m_item->width() - 1, m_item->height() - 1);
QPointF p1(0, 0);
QPointF p2(0, m_item->height() - 1);
@@ -142,23 +146,43 @@ void OpenGLRenderNode::render(const RenderState *state)
GLfloat(p1.x()), GLfloat(p1.y()),
GLfloat(p2.x()), GLfloat(p2.y()) };
m_vbo->write(0, vertices, sizeof(vertices));
+//! [5]
m_program->setAttributeBuffer(0, GL_FLOAT, 0, 2);
m_program->setAttributeBuffer(1, GL_FLOAT, sizeof(vertices), 3);
m_program->enableAttributeArray(0);
m_program->enableAttributeArray(1);
- // Note that clipping (scissor or stencil) is ignored in this example.
+ // We are prepared both for the legacy (direct OpenGL) and the modern
+ // (abstracted by RHI) OpenGL scenegraph. So set all the states that are
+ // important to us.
+
+ //! [3]
+ f->glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
f->glEnable(GL_BLEND);
f->glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+ // Clip support.
+ if (state->scissorEnabled()) {
+ f->glEnable(GL_SCISSOR_TEST);
+ const QRect r = state->scissorRect(); // already bottom-up
+ f->glScissor(r.x(), r.y(), r.width(), r.height());
+ }
+ if (state->stencilEnabled()) {
+ f->glEnable(GL_STENCIL_TEST);
+ f->glStencilFunc(GL_EQUAL, state->stencilValue(), 0xFF);
+ f->glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
+ }
+
f->glDrawArrays(GL_TRIANGLES, 0, 3);
+ //! [3]
}
+//! [4]
QSGRenderNode::StateFlags OpenGLRenderNode::changedStates() const
{
- return BlendState;
+ return BlendState | ScissorState | StencilState;
}
QSGRenderNode::RenderingFlags OpenGLRenderNode::flags() const
@@ -170,5 +194,6 @@ QRectF OpenGLRenderNode::rect() const
{
return QRect(0, 0, m_item->width(), m_item->height());
}
+//! [4]
#endif // opengl
diff --git a/examples/quick/scenegraph/rendernode/openglrenderer.h b/examples/quick/scenegraph/rendernode/openglrenderer.h
index ac640405c5..8d2d3caad1 100644
--- a/examples/quick/scenegraph/rendernode/openglrenderer.h
+++ b/examples/quick/scenegraph/rendernode/openglrenderer.h
@@ -63,6 +63,7 @@ class QOpenGLBuffer;
QT_END_NAMESPACE
+//! [1]
class OpenGLRenderNode : public QSGRenderNode
{
public:
@@ -74,6 +75,7 @@ public:
StateFlags changedStates() const override;
RenderingFlags flags() const override;
QRectF rect() const override;
+//! [1]
private:
void init();
diff --git a/examples/quick/scenegraph/rendernode/rendernode.pro b/examples/quick/scenegraph/rendernode/rendernode.pro
index 76e498042b..897b0b1f08 100644
--- a/examples/quick/scenegraph/rendernode/rendernode.pro
+++ b/examples/quick/scenegraph/rendernode/rendernode.pro
@@ -22,3 +22,9 @@ qtConfig(d3d12) {
SOURCES += d3d12renderer.cpp
LIBS += -ld3d12
}
+
+macos {
+ HEADERS += metalrenderer.h
+ SOURCES += metalrenderer.mm
+ LIBS += -framework Metal -framework AppKit
+}
diff --git a/examples/quick/scenegraph/rendernode/rendernode.qrc b/examples/quick/scenegraph/rendernode/rendernode.qrc
index 049adcf8a6..5907eab62c 100644
--- a/examples/quick/scenegraph/rendernode/rendernode.qrc
+++ b/examples/quick/scenegraph/rendernode/rendernode.qrc
@@ -3,5 +3,7 @@
<file>main.qml</file>
<file>shader_vert.cso</file>
<file>shader_frag.cso</file>
+ <file>metalshader.vert</file>
+ <file>metalshader.frag</file>
</qresource>
</RCC>
diff --git a/examples/quick/shared/CheckBox.qml b/examples/quick/shared/CheckBox.qml
index 7b1588d2d9..51b6aabc09 100644
--- a/examples/quick/shared/CheckBox.qml
+++ b/examples/quick/shared/CheckBox.qml
@@ -87,7 +87,7 @@ Item {
anchors.margins: frame.width / 5
fillMode: Image.PreserveAspectFit
smooth: true
- visible: checked
+ visible: root.checked
}
}
Text {
diff --git a/examples/quick/shared/LauncherList.qml b/examples/quick/shared/LauncherList.qml
index fe44cf3634..9859b5b635 100644
--- a/examples/quick/shared/LauncherList.qml
+++ b/examples/quick/shared/LauncherList.qml
@@ -51,6 +51,7 @@
import QtQuick 2.12
Rectangle {
+ id: root
property int activePageCount: 0
//model is a list of {"name":"somename", "url":"file:///some/url/mainfile.qml"}
@@ -74,7 +75,7 @@ Rectangle {
id: launcherList
clip: true
delegate: SimpleLauncherDelegate{
- onClicked: showExample(url)
+ onClicked: root.showExample(url)
}
model: ListModel {id:myModel}
anchors.fill: parent
@@ -116,7 +117,7 @@ Rectangle {
ParallelAnimation {
id: showAnim
ScriptAction {
- script: activePageCount++
+ script: root.activePageCount++
}
NumberAnimation {
target: launcherList
@@ -144,7 +145,7 @@ Rectangle {
id: exitAnim
ScriptAction {
- script: activePageCount--
+ script: root.activePageCount--
}
ParallelAnimation {
@@ -182,7 +183,7 @@ Rectangle {
visible: height > 0
anchors.bottom: parent.bottom
width: parent.width
- height: activePageCount > 0 ? 40 : 0
+ height: root.activePageCount > 0 ? 40 : 0
Behavior on height {
NumberAnimation {
@@ -222,7 +223,7 @@ Rectangle {
TapHandler {
id: tapHandler
- enabled: activePageCount > 0
+ enabled: root.activePageCount > 0
onTapped: {
pageContainer.children[pageContainer.children.length - 1].exit()
}
diff --git a/examples/quick/shared/Slider.qml b/examples/quick/shared/Slider.qml
index cdda86e39e..5b08034571 100644
--- a/examples/quick/shared/Slider.qml
+++ b/examples/quick/shared/Slider.qml
@@ -83,7 +83,7 @@ Item {
anchors.left: parent.left
anchors.leftMargin: 16
height: childrenRect.height
- width: Math.max(minLabelWidth, childrenRect.width)
+ width: Math.max(slider.minLabelWidth, childrenRect.width)
anchors.verticalCenter: parent.verticalCenter
Text {
text: slider.name + ":"
diff --git a/src/imports/builtins/builtins.qmltypes b/src/imports/builtins/builtins.qmltypes
index 4ad103f8de..c783c63caf 100644
--- a/src/imports/builtins/builtins.qmltypes
+++ b/src/imports/builtins/builtins.qmltypes
@@ -131,6 +131,13 @@ Module {
}
}
Enum {
+ name: "SplitBehavior"
+ values: {
+ "KeepEmptyParts": 0,
+ "SkipEmptyParts": 1
+ }
+ }
+ Enum {
name: "Alignment"
values: {
"AlignLeft": 1,
@@ -466,7 +473,8 @@ Module {
"AA_DontShowShortcutsInContextMenus": 28,
"AA_CompressTabletEvents": 29,
"AA_DisableWindowContextHelpButton": 30,
- "AA_AttributeCount": 31
+ "AA_DisableSessionManager": 31,
+ "AA_AttributeCount": 32
}
}
Enum {
@@ -1081,7 +1089,8 @@ Module {
values: {
"PlainText": 0,
"RichText": 1,
- "AutoText": 2
+ "AutoText": 2,
+ "MarkdownText": 3
}
}
Enum {
diff --git a/src/imports/folderlistmodel/plugins.qmltypes b/src/imports/folderlistmodel/plugins.qmltypes
index 6f5466dbda..0fdbae66d3 100644
--- a/src/imports/folderlistmodel/plugins.qmltypes
+++ b/src/imports/folderlistmodel/plugins.qmltypes
@@ -4,7 +4,7 @@ import QtQuick.tooling 1.2
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable Qt.labs.folderlistmodel 2.13'
+// 'qmlplugindump -nonrelocatable Qt.labs.folderlistmodel 2.14'
Module {
dependencies: ["QtQuick 2.0"]
diff --git a/src/imports/labsmodels/plugins.qmltypes b/src/imports/labsmodels/plugins.qmltypes
index 6272069060..f2a5752422 100644
--- a/src/imports/labsmodels/plugins.qmltypes
+++ b/src/imports/labsmodels/plugins.qmltypes
@@ -9,6 +9,280 @@ import QtQuick.tooling 1.2
Module {
dependencies: []
Component {
+ name: "QAbstractItemModel"
+ prototype: "QObject"
+ Enum {
+ name: "LayoutChangeHint"
+ values: {
+ "NoLayoutChangeHint": 0,
+ "VerticalSortHint": 1,
+ "HorizontalSortHint": 2
+ }
+ }
+ Enum {
+ name: "CheckIndexOption"
+ values: {
+ "NoOption": 0,
+ "IndexIsValid": 1,
+ "DoNotUseParent": 2,
+ "ParentIsInvalid": 4
+ }
+ }
+ Signal {
+ name: "dataChanged"
+ Parameter { name: "topLeft"; type: "QModelIndex" }
+ Parameter { name: "bottomRight"; type: "QModelIndex" }
+ Parameter { name: "roles"; type: "QVector<int>" }
+ }
+ Signal {
+ name: "dataChanged"
+ Parameter { name: "topLeft"; type: "QModelIndex" }
+ Parameter { name: "bottomRight"; type: "QModelIndex" }
+ }
+ Signal {
+ name: "headerDataChanged"
+ Parameter { name: "orientation"; type: "Qt::Orientation" }
+ Parameter { name: "first"; type: "int" }
+ Parameter { name: "last"; type: "int" }
+ }
+ Signal {
+ name: "layoutChanged"
+ Parameter { name: "parents"; type: "QList<QPersistentModelIndex>" }
+ Parameter { name: "hint"; type: "QAbstractItemModel::LayoutChangeHint" }
+ }
+ Signal {
+ name: "layoutChanged"
+ Parameter { name: "parents"; type: "QList<QPersistentModelIndex>" }
+ }
+ Signal { name: "layoutChanged" }
+ Signal {
+ name: "layoutAboutToBeChanged"
+ Parameter { name: "parents"; type: "QList<QPersistentModelIndex>" }
+ Parameter { name: "hint"; type: "QAbstractItemModel::LayoutChangeHint" }
+ }
+ Signal {
+ name: "layoutAboutToBeChanged"
+ Parameter { name: "parents"; type: "QList<QPersistentModelIndex>" }
+ }
+ Signal { name: "layoutAboutToBeChanged" }
+ Signal {
+ name: "rowsAboutToBeInserted"
+ Parameter { name: "parent"; type: "QModelIndex" }
+ Parameter { name: "first"; type: "int" }
+ Parameter { name: "last"; type: "int" }
+ }
+ Signal {
+ name: "rowsInserted"
+ Parameter { name: "parent"; type: "QModelIndex" }
+ Parameter { name: "first"; type: "int" }
+ Parameter { name: "last"; type: "int" }
+ }
+ Signal {
+ name: "rowsAboutToBeRemoved"
+ Parameter { name: "parent"; type: "QModelIndex" }
+ Parameter { name: "first"; type: "int" }
+ Parameter { name: "last"; type: "int" }
+ }
+ Signal {
+ name: "rowsRemoved"
+ Parameter { name: "parent"; type: "QModelIndex" }
+ Parameter { name: "first"; type: "int" }
+ Parameter { name: "last"; type: "int" }
+ }
+ Signal {
+ name: "columnsAboutToBeInserted"
+ Parameter { name: "parent"; type: "QModelIndex" }
+ Parameter { name: "first"; type: "int" }
+ Parameter { name: "last"; type: "int" }
+ }
+ Signal {
+ name: "columnsInserted"
+ Parameter { name: "parent"; type: "QModelIndex" }
+ Parameter { name: "first"; type: "int" }
+ Parameter { name: "last"; type: "int" }
+ }
+ Signal {
+ name: "columnsAboutToBeRemoved"
+ Parameter { name: "parent"; type: "QModelIndex" }
+ Parameter { name: "first"; type: "int" }
+ Parameter { name: "last"; type: "int" }
+ }
+ Signal {
+ name: "columnsRemoved"
+ Parameter { name: "parent"; type: "QModelIndex" }
+ Parameter { name: "first"; type: "int" }
+ Parameter { name: "last"; type: "int" }
+ }
+ Signal { name: "modelAboutToBeReset" }
+ Signal { name: "modelReset" }
+ Signal {
+ name: "rowsAboutToBeMoved"
+ Parameter { name: "sourceParent"; type: "QModelIndex" }
+ Parameter { name: "sourceStart"; type: "int" }
+ Parameter { name: "sourceEnd"; type: "int" }
+ Parameter { name: "destinationParent"; type: "QModelIndex" }
+ Parameter { name: "destinationRow"; type: "int" }
+ }
+ Signal {
+ name: "rowsMoved"
+ Parameter { name: "parent"; type: "QModelIndex" }
+ Parameter { name: "start"; type: "int" }
+ Parameter { name: "end"; type: "int" }
+ Parameter { name: "destination"; type: "QModelIndex" }
+ Parameter { name: "row"; type: "int" }
+ }
+ Signal {
+ name: "columnsAboutToBeMoved"
+ Parameter { name: "sourceParent"; type: "QModelIndex" }
+ Parameter { name: "sourceStart"; type: "int" }
+ Parameter { name: "sourceEnd"; type: "int" }
+ Parameter { name: "destinationParent"; type: "QModelIndex" }
+ Parameter { name: "destinationColumn"; type: "int" }
+ }
+ Signal {
+ name: "columnsMoved"
+ Parameter { name: "parent"; type: "QModelIndex" }
+ Parameter { name: "start"; type: "int" }
+ Parameter { name: "end"; type: "int" }
+ Parameter { name: "destination"; type: "QModelIndex" }
+ Parameter { name: "column"; type: "int" }
+ }
+ Method { name: "submit"; type: "bool" }
+ Method { name: "revert" }
+ Method {
+ name: "hasIndex"
+ type: "bool"
+ Parameter { name: "row"; type: "int" }
+ Parameter { name: "column"; type: "int" }
+ Parameter { name: "parent"; type: "QModelIndex" }
+ }
+ Method {
+ name: "hasIndex"
+ type: "bool"
+ Parameter { name: "row"; type: "int" }
+ Parameter { name: "column"; type: "int" }
+ }
+ Method {
+ name: "index"
+ type: "QModelIndex"
+ Parameter { name: "row"; type: "int" }
+ Parameter { name: "column"; type: "int" }
+ Parameter { name: "parent"; type: "QModelIndex" }
+ }
+ Method {
+ name: "index"
+ type: "QModelIndex"
+ Parameter { name: "row"; type: "int" }
+ Parameter { name: "column"; type: "int" }
+ }
+ Method {
+ name: "parent"
+ type: "QModelIndex"
+ Parameter { name: "child"; type: "QModelIndex" }
+ }
+ Method {
+ name: "sibling"
+ type: "QModelIndex"
+ Parameter { name: "row"; type: "int" }
+ Parameter { name: "column"; type: "int" }
+ Parameter { name: "idx"; type: "QModelIndex" }
+ }
+ Method {
+ name: "rowCount"
+ type: "int"
+ Parameter { name: "parent"; type: "QModelIndex" }
+ }
+ Method { name: "rowCount"; type: "int" }
+ Method {
+ name: "columnCount"
+ type: "int"
+ Parameter { name: "parent"; type: "QModelIndex" }
+ }
+ Method { name: "columnCount"; type: "int" }
+ Method {
+ name: "hasChildren"
+ type: "bool"
+ Parameter { name: "parent"; type: "QModelIndex" }
+ }
+ Method { name: "hasChildren"; type: "bool" }
+ Method {
+ name: "data"
+ type: "QVariant"
+ Parameter { name: "index"; type: "QModelIndex" }
+ Parameter { name: "role"; type: "int" }
+ }
+ Method {
+ name: "data"
+ type: "QVariant"
+ Parameter { name: "index"; type: "QModelIndex" }
+ }
+ Method {
+ name: "setData"
+ type: "bool"
+ Parameter { name: "index"; type: "QModelIndex" }
+ Parameter { name: "value"; type: "QVariant" }
+ Parameter { name: "role"; type: "int" }
+ }
+ Method {
+ name: "setData"
+ type: "bool"
+ Parameter { name: "index"; type: "QModelIndex" }
+ Parameter { name: "value"; type: "QVariant" }
+ }
+ Method {
+ name: "headerData"
+ type: "QVariant"
+ Parameter { name: "section"; type: "int" }
+ Parameter { name: "orientation"; type: "Qt::Orientation" }
+ Parameter { name: "role"; type: "int" }
+ }
+ Method {
+ name: "headerData"
+ type: "QVariant"
+ Parameter { name: "section"; type: "int" }
+ Parameter { name: "orientation"; type: "Qt::Orientation" }
+ }
+ Method {
+ name: "fetchMore"
+ Parameter { name: "parent"; type: "QModelIndex" }
+ }
+ Method {
+ name: "canFetchMore"
+ type: "bool"
+ Parameter { name: "parent"; type: "QModelIndex" }
+ }
+ Method {
+ name: "flags"
+ type: "Qt::ItemFlags"
+ Parameter { name: "index"; type: "QModelIndex" }
+ }
+ Method {
+ name: "match"
+ type: "QModelIndexList"
+ Parameter { name: "start"; type: "QModelIndex" }
+ Parameter { name: "role"; type: "int" }
+ Parameter { name: "value"; type: "QVariant" }
+ Parameter { name: "hits"; type: "int" }
+ Parameter { name: "flags"; type: "Qt::MatchFlags" }
+ }
+ Method {
+ name: "match"
+ type: "QModelIndexList"
+ Parameter { name: "start"; type: "QModelIndex" }
+ Parameter { name: "role"; type: "int" }
+ Parameter { name: "value"; type: "QVariant" }
+ Parameter { name: "hits"; type: "int" }
+ }
+ Method {
+ name: "match"
+ type: "QModelIndexList"
+ Parameter { name: "start"; type: "QModelIndex" }
+ Parameter { name: "role"; type: "int" }
+ Parameter { name: "value"; type: "QVariant" }
+ }
+ }
+ Component { name: "QAbstractTableModel"; prototype: "QAbstractItemModel" }
+ Component {
name: "QQmlAbstractDelegateComponent"
prototype: "QQmlComponent"
exports: ["Qt.labs.qmlmodels/AbstractDelegateComponent 1.0"]
@@ -38,4 +312,103 @@ Module {
Property { name: "role"; type: "string" }
Property { name: "choices"; type: "QQmlDelegateChoice"; isList: true; isReadonly: true }
}
+ Component {
+ name: "QQmlTableModel"
+ defaultProperty: "columns"
+ prototype: "QAbstractTableModel"
+ exports: ["Qt.labs.qmlmodels/TableModel 1.0"]
+ exportMetaObjectRevisions: [0]
+ Property { name: "columnCount"; type: "int"; isReadonly: true }
+ Property { name: "rowCount"; type: "int"; isReadonly: true }
+ Property { name: "rows"; type: "QVariant" }
+ Property { name: "columns"; type: "QQmlTableModelColumn"; isList: true; isReadonly: true }
+ Method {
+ name: "appendRow"
+ Parameter { name: "row"; type: "QVariant" }
+ }
+ Method { name: "clear" }
+ Method {
+ name: "getRow"
+ type: "QVariant"
+ Parameter { name: "rowIndex"; type: "int" }
+ }
+ Method {
+ name: "insertRow"
+ Parameter { name: "rowIndex"; type: "int" }
+ Parameter { name: "row"; type: "QVariant" }
+ }
+ Method {
+ name: "moveRow"
+ Parameter { name: "fromRowIndex"; type: "int" }
+ Parameter { name: "toRowIndex"; type: "int" }
+ Parameter { name: "rows"; type: "int" }
+ }
+ Method {
+ name: "moveRow"
+ Parameter { name: "fromRowIndex"; type: "int" }
+ Parameter { name: "toRowIndex"; type: "int" }
+ }
+ Method {
+ name: "removeRow"
+ Parameter { name: "rowIndex"; type: "int" }
+ Parameter { name: "rows"; type: "int" }
+ }
+ Method {
+ name: "removeRow"
+ Parameter { name: "rowIndex"; type: "int" }
+ }
+ Method {
+ name: "setRow"
+ Parameter { name: "rowIndex"; type: "int" }
+ Parameter { name: "row"; type: "QVariant" }
+ }
+ Method {
+ name: "data"
+ type: "QVariant"
+ Parameter { name: "index"; type: "QModelIndex" }
+ Parameter { name: "role"; type: "string" }
+ }
+ Method {
+ name: "setData"
+ type: "bool"
+ Parameter { name: "index"; type: "QModelIndex" }
+ Parameter { name: "role"; type: "string" }
+ Parameter { name: "value"; type: "QVariant" }
+ }
+ }
+ Component {
+ name: "QQmlTableModelColumn"
+ prototype: "QObject"
+ exports: ["Qt.labs.qmlmodels/TableModelColumn 1.0"]
+ exportMetaObjectRevisions: [0]
+ Property { name: "display"; type: "QJSValue" }
+ Property { name: "setDisplay"; type: "QJSValue" }
+ Property { name: "decoration"; type: "QJSValue" }
+ Property { name: "setDecoration"; type: "QJSValue" }
+ Property { name: "edit"; type: "QJSValue" }
+ Property { name: "setEdit"; type: "QJSValue" }
+ Property { name: "toolTip"; type: "QJSValue" }
+ Property { name: "setToolTip"; type: "QJSValue" }
+ Property { name: "statusTip"; type: "QJSValue" }
+ Property { name: "setStatusTip"; type: "QJSValue" }
+ Property { name: "whatsThis"; type: "QJSValue" }
+ Property { name: "setWhatsThis"; type: "QJSValue" }
+ Property { name: "font"; type: "QJSValue" }
+ Property { name: "setFont"; type: "QJSValue" }
+ Property { name: "textAlignment"; type: "QJSValue" }
+ Property { name: "setTextAlignment"; type: "QJSValue" }
+ Property { name: "background"; type: "QJSValue" }
+ Property { name: "setBackground"; type: "QJSValue" }
+ Property { name: "foreground"; type: "QJSValue" }
+ Property { name: "setForeground"; type: "QJSValue" }
+ Property { name: "checkState"; type: "QJSValue" }
+ Property { name: "setCheckState"; type: "QJSValue" }
+ Property { name: "accessibleText"; type: "QJSValue" }
+ Property { name: "setAccessibleText"; type: "QJSValue" }
+ Property { name: "accessibleDescription"; type: "QJSValue" }
+ Property { name: "setAccessibleDescription"; type: "QJSValue" }
+ Property { name: "sizeHint"; type: "QJSValue" }
+ Property { name: "setSizeHint"; type: "QJSValue" }
+ Signal { name: "indexChanged" }
+ }
}
diff --git a/src/imports/layouts/plugins.qmltypes b/src/imports/layouts/plugins.qmltypes
index 22e8d79ece..6015164511 100644
--- a/src/imports/layouts/plugins.qmltypes
+++ b/src/imports/layouts/plugins.qmltypes
@@ -4,7 +4,7 @@ import QtQuick.tooling 1.2
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable QtQuick.Layouts 1.13'
+// 'qmlplugindump -nonrelocatable QtQuick.Layouts 1.14'
Module {
dependencies: ["QtQuick 2.0"]
diff --git a/src/imports/localstorage/plugins.qmltypes b/src/imports/localstorage/plugins.qmltypes
index 3c8c1404f2..6ed334cc9d 100644
--- a/src/imports/localstorage/plugins.qmltypes
+++ b/src/imports/localstorage/plugins.qmltypes
@@ -4,7 +4,7 @@ import QtQuick.tooling 1.2
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable -dependencies dependencies.json QtQuick.LocalStorage 2.13'
+// 'qmlplugindump -nonrelocatable -dependencies dependencies.json QtQuick.LocalStorage 2.14'
Module {
dependencies: []
diff --git a/src/imports/models/plugins.qmltypes b/src/imports/models/plugins.qmltypes
index 6e112c41b6..0d8b94df23 100644
--- a/src/imports/models/plugins.qmltypes
+++ b/src/imports/models/plugins.qmltypes
@@ -4,7 +4,7 @@ import QtQuick.tooling 1.2
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable -dependencies dependencies.json QtQml.Models 2.13'
+// 'qmlplugindump -nonrelocatable -dependencies dependencies.json QtQml.Models 2.14'
Module {
dependencies: []
@@ -441,8 +441,8 @@ Module {
Signal { name: "defaultIncludeChanged" }
Signal {
name: "changed"
- Parameter { name: "removed"; type: "QQmlV4Handle" }
- Parameter { name: "inserted"; type: "QQmlV4Handle" }
+ Parameter { name: "removed"; type: "QJSValue" }
+ Parameter { name: "inserted"; type: "QJSValue" }
}
Method {
name: "insert"
@@ -478,7 +478,7 @@ Module {
}
Method {
name: "get"
- type: "QQmlV4Handle"
+ type: "QJSValue"
Parameter { name: "index"; type: "int" }
}
}
@@ -496,6 +496,7 @@ Module {
exportMetaObjectRevisions: [0]
Property { name: "count"; type: "int"; isReadonly: true }
Property { name: "dynamicRoles"; type: "bool" }
+ Property { name: "agent"; revision: 14; type: "QObject"; isReadonly: true; isPointer: true }
Method { name: "clear" }
Method {
name: "remove"
@@ -511,13 +512,61 @@ Module {
}
Method {
name: "get"
- type: "QQmlV4Handle"
+ type: "QJSValue"
Parameter { name: "index"; type: "int" }
}
Method {
name: "set"
Parameter { name: "index"; type: "int" }
- Parameter { type: "QQmlV4Handle" }
+ Parameter { name: "value"; type: "QJSValue" }
+ }
+ Method {
+ name: "setProperty"
+ Parameter { name: "index"; type: "int" }
+ Parameter { name: "property"; type: "string" }
+ Parameter { name: "value"; type: "QVariant" }
+ }
+ Method {
+ name: "move"
+ Parameter { name: "from"; type: "int" }
+ Parameter { name: "to"; type: "int" }
+ Parameter { name: "count"; type: "int" }
+ }
+ Method { name: "sync" }
+ }
+ Component {
+ name: "QQmlListModelWorkerAgent"
+ prototype: "QObject"
+ Property { name: "count"; type: "int"; isReadonly: true }
+ Property { name: "engine"; type: "QV4::ExecutionEngine"; isPointer: true }
+ Signal {
+ name: "engineChanged"
+ Parameter { name: "engine"; type: "QV4::ExecutionEngine"; isPointer: true }
+ }
+ Method { name: "addref" }
+ Method { name: "release" }
+ Method { name: "clear" }
+ Method {
+ name: "remove"
+ Parameter { name: "args"; type: "QQmlV4Function"; isPointer: true }
+ }
+ Method {
+ name: "append"
+ Parameter { name: "args"; type: "QQmlV4Function"; isPointer: true }
+ }
+ Method {
+ name: "insert"
+ Parameter { name: "args"; type: "QQmlV4Function"; isPointer: true }
+ }
+ Method {
+ name: "get"
+ type: "QJSValue"
+ Parameter { name: "index"; type: "int" }
+ }
+ Method {
+ name: "set"
+ Parameter { name: "index"; type: "int" }
+ Parameter { name: "value"; type: "QJSValue" }
}
Method {
name: "setProperty"
@@ -592,4 +641,18 @@ Module {
prototype: "QObject"
Property { name: "index"; type: "int"; isReadonly: true }
}
+ Component {
+ name: "QQuickPackage"
+ defaultProperty: "data"
+ prototype: "QObject"
+ exports: ["QtQml.Models/Package 2.14"]
+ exportMetaObjectRevisions: [0]
+ attachedType: "QQuickPackageAttached"
+ Property { name: "data"; type: "QObject"; isList: true; isReadonly: true }
+ }
+ Component {
+ name: "QQuickPackageAttached"
+ prototype: "QObject"
+ Property { name: "name"; type: "string" }
+ }
}
diff --git a/src/imports/particles/plugins.qmltypes b/src/imports/particles/plugins.qmltypes
index b6db00e683..0fe5dc808c 100644
--- a/src/imports/particles/plugins.qmltypes
+++ b/src/imports/particles/plugins.qmltypes
@@ -4,7 +4,7 @@ import QtQuick.tooling 1.2
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable QtQuick.Particles 2.13'
+// 'qmlplugindump -nonrelocatable QtQuick.Particles 2.14'
Module {
dependencies: ["QtQuick 2.0"]
@@ -165,7 +165,7 @@ Module {
Property { name: "acceleration"; type: "QQuickDirection"; isPointer: true }
Signal {
name: "affectParticles"
- Parameter { name: "particles"; type: "QQmlV4Handle" }
+ Parameter { name: "particles"; type: "QJSValue" }
Parameter { name: "dt"; type: "double" }
}
Signal {
@@ -668,7 +668,7 @@ Module {
Property { name: "velocityFromMovement"; type: "double" }
Signal {
name: "emitParticles"
- Parameter { name: "particles"; type: "QQmlV4Handle" }
+ Parameter { name: "particles"; type: "QJSValue" }
}
Signal {
name: "particlesPerSecondChanged"
@@ -1084,8 +1084,8 @@ Module {
Property { name: "emitWidth"; type: "double" }
Signal {
name: "emitFollowParticles"
- Parameter { name: "particles"; type: "QQmlV4Handle" }
- Parameter { name: "followed"; type: "QQmlV4Handle" }
+ Parameter { name: "particles"; type: "QJSValue" }
+ Parameter { name: "followed"; type: "QJSValue" }
}
Signal {
name: "particlesPerParticlePerSecondChanged"
diff --git a/src/imports/qtqml/dependencies.json b/src/imports/qtqml/dependencies.json
new file mode 100644
index 0000000000..0d4f101c7a
--- /dev/null
+++ b/src/imports/qtqml/dependencies.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/src/imports/qtqml/plugins.qmltypes b/src/imports/qtqml/plugins.qmltypes
index d548a78dd0..63f5bada9b 100644
--- a/src/imports/qtqml/plugins.qmltypes
+++ b/src/imports/qtqml/plugins.qmltypes
@@ -4,14 +4,14 @@ import QtQuick.tooling 1.2
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable -noforceqtquick QtQml 2.13'
+// 'qmlplugindump -nonrelocatable -dependencies dependencies.json QtQml 2.14'
Module {
dependencies: []
Component {
name: "QObject"
- exports: ["QtQml/QtObject 2.0"]
- exportMetaObjectRevisions: [0]
+ exports: ["QML/QtObject 1.0", "QtQml/QtObject 2.0"]
+ exportMetaObjectRevisions: [0, 0]
Property { name: "objectName"; type: "string" }
Signal {
name: "objectNameChanged"
@@ -27,13 +27,27 @@ Module {
Component {
name: "QQmlBind"
prototype: "QObject"
- exports: ["QtQml/Binding 2.0", "QtQml/Binding 2.8"]
- exportMetaObjectRevisions: [0, 8]
+ exports: [
+ "QtQml/Binding 2.0",
+ "QtQml/Binding 2.14",
+ "QtQml/Binding 2.8"
+ ]
+ exportMetaObjectRevisions: [0, 14, 8]
+ Enum {
+ name: "RestorationMode"
+ values: {
+ "RestoreNone": 0,
+ "RestoreBinding": 1,
+ "RestoreValue": 2,
+ "RestoreBindingOrValue": 3
+ }
+ }
Property { name: "target"; type: "QObject"; isPointer: true }
Property { name: "property"; type: "string" }
Property { name: "value"; type: "QVariant" }
Property { name: "when"; type: "bool" }
Property { name: "delayed"; revision: 8; type: "bool" }
+ Property { name: "restoreMode"; revision: 14; type: "RestorationMode" }
}
Component {
name: "QQmlComponent"
@@ -94,11 +108,11 @@ Module {
name: "QQmlConnections"
prototype: "QObject"
exports: ["QtQml/Connections 2.0", "QtQml/Connections 2.3"]
- exportMetaObjectRevisions: [0, 1]
+ exportMetaObjectRevisions: [0, 3]
Property { name: "target"; type: "QObject"; isPointer: true }
- Property { name: "enabled"; revision: 1; type: "bool" }
+ Property { name: "enabled"; revision: 3; type: "bool" }
Property { name: "ignoreUnknownSignals"; type: "bool" }
- Signal { name: "enabledChanged"; revision: 1 }
+ Signal { name: "enabledChanged"; revision: 3 }
}
Component {
name: "QQmlInstanceModel"
@@ -199,7 +213,7 @@ Module {
name: "QQmlLoggingCategory"
prototype: "QObject"
exports: ["QtQml/LoggingCategory 2.12", "QtQml/LoggingCategory 2.8"]
- exportMetaObjectRevisions: [1, 0]
+ exportMetaObjectRevisions: [12, 0]
Enum {
name: "DefaultLogLevel"
values: {
@@ -211,7 +225,7 @@ Module {
}
}
Property { name: "name"; type: "string" }
- Property { name: "defaultLogLevel"; revision: 1; type: "DefaultLogLevel" }
+ Property { name: "defaultLogLevel"; revision: 12; type: "DefaultLogLevel" }
}
Component {
name: "QQmlTimer"
diff --git a/src/imports/qtquick2/plugins.qmltypes b/src/imports/qtquick2/plugins.qmltypes
index f006c874da..c8aae2087d 100644
--- a/src/imports/qtquick2/plugins.qmltypes
+++ b/src/imports/qtquick2/plugins.qmltypes
@@ -4,7 +4,7 @@ import QtQuick.tooling 1.2
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable -dependencies dependencies.json QtQuick 2.13'
+// 'qmlplugindump -nonrelocatable -dependencies dependencies.json QtQuick 2.14'
Module {
dependencies: []
@@ -529,8 +529,8 @@ Module {
Signal { name: "defaultIncludeChanged" }
Signal {
name: "changed"
- Parameter { name: "removed"; type: "QQmlV4Handle" }
- Parameter { name: "inserted"; type: "QQmlV4Handle" }
+ Parameter { name: "removed"; type: "QJSValue" }
+ Parameter { name: "inserted"; type: "QJSValue" }
}
Method {
name: "insert"
@@ -566,7 +566,7 @@ Module {
}
Method {
name: "get"
- type: "QQmlV4Handle"
+ type: "QJSValue"
Parameter { name: "index"; type: "int" }
}
}
@@ -646,6 +646,7 @@ Module {
exportMetaObjectRevisions: [0]
Property { name: "count"; type: "int"; isReadonly: true }
Property { name: "dynamicRoles"; type: "bool" }
+ Property { name: "agent"; revision: 14; type: "QObject"; isReadonly: true; isPointer: true }
Method { name: "clear" }
Method {
name: "remove"
@@ -661,13 +662,61 @@ Module {
}
Method {
name: "get"
- type: "QQmlV4Handle"
+ type: "QJSValue"
Parameter { name: "index"; type: "int" }
}
Method {
name: "set"
Parameter { name: "index"; type: "int" }
- Parameter { type: "QQmlV4Handle" }
+ Parameter { name: "value"; type: "QJSValue" }
+ }
+ Method {
+ name: "setProperty"
+ Parameter { name: "index"; type: "int" }
+ Parameter { name: "property"; type: "string" }
+ Parameter { name: "value"; type: "QVariant" }
+ }
+ Method {
+ name: "move"
+ Parameter { name: "from"; type: "int" }
+ Parameter { name: "to"; type: "int" }
+ Parameter { name: "count"; type: "int" }
+ }
+ Method { name: "sync" }
+ }
+ Component {
+ name: "QQmlListModelWorkerAgent"
+ prototype: "QObject"
+ Property { name: "count"; type: "int"; isReadonly: true }
+ Property { name: "engine"; type: "QV4::ExecutionEngine"; isPointer: true }
+ Signal {
+ name: "engineChanged"
+ Parameter { name: "engine"; type: "QV4::ExecutionEngine"; isPointer: true }
+ }
+ Method { name: "addref" }
+ Method { name: "release" }
+ Method { name: "clear" }
+ Method {
+ name: "remove"
+ Parameter { name: "args"; type: "QQmlV4Function"; isPointer: true }
+ }
+ Method {
+ name: "append"
+ Parameter { name: "args"; type: "QQmlV4Function"; isPointer: true }
+ }
+ Method {
+ name: "insert"
+ Parameter { name: "args"; type: "QQmlV4Function"; isPointer: true }
+ }
+ Method {
+ name: "get"
+ type: "QJSValue"
+ Parameter { name: "index"; type: "int" }
+ }
+ Method {
+ name: "set"
+ Parameter { name: "index"; type: "int" }
+ Parameter { name: "value"; type: "QJSValue" }
}
Method {
name: "setProperty"
@@ -1300,7 +1349,7 @@ Module {
}
Property { name: "available"; type: "bool"; isReadonly: true }
Property { name: "contextType"; type: "string" }
- Property { name: "context"; type: "QQmlV4Handle"; isReadonly: true }
+ Property { name: "context"; type: "QJSValue"; isReadonly: true }
Property { name: "canvasSize"; type: "QSizeF" }
Property { name: "tileSize"; type: "QSize" }
Property { name: "canvasWindow"; type: "QRectF" }
@@ -1480,9 +1529,19 @@ Module {
prototype: "QQuickMultiPointHandler"
exports: ["QtQuick/DragHandler 2.12"]
exportMetaObjectRevisions: [0]
+ Enum {
+ name: "SnapMode"
+ values: {
+ "NoSnap": 0,
+ "SnapAuto": 1,
+ "SnapIfPressedOutsideTarget": 2,
+ "SnapAlways": 3
+ }
+ }
Property { name: "xAxis"; type: "QQuickDragAxis"; isReadonly: true; isPointer: true }
Property { name: "yAxis"; type: "QQuickDragAxis"; isReadonly: true; isPointer: true }
Property { name: "translation"; type: "QVector2D"; isReadonly: true }
+ Property { name: "snapMode"; type: "SnapMode" }
}
Component {
name: "QQuickDropArea"
@@ -1959,7 +2018,13 @@ Module {
"Unknown": 0,
"Software": 1,
"OpenGL": 2,
- "Direct3D12": 3
+ "Direct3D12": 3,
+ "OpenVG": 4,
+ "OpenGLRhi": 5,
+ "Direct3D11Rhi": 6,
+ "VulkanRhi": 7,
+ "MetalRhi": 8,
+ "NullRhi": 9
}
}
Enum {
@@ -1967,7 +2032,8 @@ Module {
values: {
"UnknownShadingLanguage": 0,
"GLSL": 1,
- "HLSL": 2
+ "HLSL": 2,
+ "RhiShader": 3
}
}
Enum {
@@ -2131,7 +2197,7 @@ Module {
"QtQuick/Image 2.3",
"QtQuick/Image 2.5"
]
- exportMetaObjectRevisions: [0, 1, 2]
+ exportMetaObjectRevisions: [0, 3, 5]
Enum {
name: "HAlignment"
values: {
@@ -2165,8 +2231,8 @@ Module {
Property { name: "paintedHeight"; type: "double"; isReadonly: true }
Property { name: "horizontalAlignment"; type: "HAlignment" }
Property { name: "verticalAlignment"; type: "VAlignment" }
- Property { name: "mipmap"; revision: 1; type: "bool" }
- Property { name: "autoTransform"; revision: 2; type: "bool" }
+ Property { name: "mipmap"; revision: 3; type: "bool" }
+ Property { name: "autoTransform"; revision: 5; type: "bool" }
Signal { name: "paintedGeometryChanged" }
Signal {
name: "horizontalAlignmentChanged"
@@ -2178,10 +2244,10 @@ Module {
}
Signal {
name: "mipmapChanged"
- revision: 1
+ revision: 3
Parameter { type: "bool" }
}
- Signal { name: "autoTransformChanged"; revision: 2 }
+ Signal { name: "autoTransformChanged"; revision: 5 }
}
Component {
name: "QQuickImageBase"
@@ -2242,7 +2308,7 @@ Module {
"QtQuick/Item 2.4",
"QtQuick/Item 2.7"
]
- exportMetaObjectRevisions: [0, 1, 11, 2, 7]
+ exportMetaObjectRevisions: [0, 1, 11, 4, 7]
Enum {
name: "Flags"
values: {
@@ -2362,14 +2428,14 @@ Module {
Method { name: "update" }
Method {
name: "grabToImage"
- revision: 2
+ revision: 4
type: "bool"
Parameter { name: "callback"; type: "QJSValue" }
Parameter { name: "targetSize"; type: "QSize" }
}
Method {
name: "grabToImage"
- revision: 2
+ revision: 4
type: "bool"
Parameter { name: "callback"; type: "QJSValue" }
}
@@ -2502,7 +2568,7 @@ Module {
"QtQuick/ItemView 2.7"
]
isCreatable: false
- exportMetaObjectRevisions: [1, 13, 2, 7]
+ exportMetaObjectRevisions: [1, 13, 3, 7]
Enum {
name: "LayoutDirection"
values: {
@@ -2546,8 +2612,8 @@ Module {
Property { name: "keyNavigationWraps"; type: "bool" }
Property { name: "keyNavigationEnabled"; revision: 7; type: "bool" }
Property { name: "cacheBuffer"; type: "int" }
- Property { name: "displayMarginBeginning"; revision: 2; type: "int" }
- Property { name: "displayMarginEnd"; revision: 2; type: "int" }
+ Property { name: "displayMarginBeginning"; revision: 3; type: "int" }
+ Property { name: "displayMarginEnd"; revision: 3; type: "int" }
Property { name: "layoutDirection"; type: "Qt::LayoutDirection" }
Property { name: "effectiveLayoutDirection"; type: "Qt::LayoutDirection"; isReadonly: true }
Property { name: "verticalLayoutDirection"; type: "VerticalLayoutDirection" }
@@ -2858,7 +2924,7 @@ Module {
"QtQuick/ListView 2.4",
"QtQuick/ListView 2.7"
]
- exportMetaObjectRevisions: [0, 1, 2, 7]
+ exportMetaObjectRevisions: [0, 1, 4, 7]
attachedType: "QQuickListViewAttached"
Enum {
name: "Orientation"
@@ -2899,10 +2965,10 @@ Module {
Property { name: "section"; type: "QQuickViewSection"; isReadonly: true; isPointer: true }
Property { name: "currentSection"; type: "string"; isReadonly: true }
Property { name: "snapMode"; type: "SnapMode" }
- Property { name: "headerPositioning"; revision: 2; type: "HeaderPositioning" }
- Property { name: "footerPositioning"; revision: 2; type: "FooterPositioning" }
- Signal { name: "headerPositioningChanged"; revision: 2 }
- Signal { name: "footerPositioningChanged"; revision: 2 }
+ Property { name: "headerPositioning"; revision: 4; type: "HeaderPositioning" }
+ Property { name: "footerPositioning"; revision: 4; type: "FooterPositioning" }
+ Signal { name: "headerPositioningChanged"; revision: 4 }
+ Signal { name: "footerPositioningChanged"; revision: 4 }
Method { name: "incrementCurrentIndex" }
Method { name: "decrementCurrentIndex" }
}
@@ -2952,13 +3018,13 @@ Module {
"QtQuick/MouseArea 2.5",
"QtQuick/MouseArea 2.9"
]
- exportMetaObjectRevisions: [0, 1, 2, 9]
+ exportMetaObjectRevisions: [0, 4, 5, 9]
Property { name: "mouseX"; type: "double"; isReadonly: true }
Property { name: "mouseY"; type: "double"; isReadonly: true }
Property { name: "containsMouse"; type: "bool"; isReadonly: true }
Property { name: "pressed"; type: "bool"; isReadonly: true }
Property { name: "enabled"; type: "bool" }
- Property { name: "scrollGestureEnabled"; revision: 2; type: "bool" }
+ Property { name: "scrollGestureEnabled"; revision: 5; type: "bool" }
Property { name: "pressedButtons"; type: "Qt::MouseButtons"; isReadonly: true }
Property { name: "acceptedButtons"; type: "Qt::MouseButtons" }
Property { name: "hoverEnabled"; type: "bool" }
@@ -2966,10 +3032,10 @@ Module {
Property { name: "preventStealing"; type: "bool" }
Property { name: "propagateComposedEvents"; type: "bool" }
Property { name: "cursorShape"; type: "Qt::CursorShape" }
- Property { name: "containsPress"; revision: 1; type: "bool"; isReadonly: true }
+ Property { name: "containsPress"; revision: 4; type: "bool"; isReadonly: true }
Property { name: "pressAndHoldInterval"; revision: 9; type: "int" }
Signal { name: "hoveredChanged" }
- Signal { name: "scrollGestureEnabledChanged"; revision: 2 }
+ Signal { name: "scrollGestureEnabledChanged"; revision: 5 }
Signal {
name: "positionChanged"
Parameter { name: "mouse"; type: "QQuickMouseEvent"; isPointer: true }
@@ -3009,7 +3075,7 @@ Module {
Signal { name: "entered" }
Signal { name: "exited" }
Signal { name: "canceled" }
- Signal { name: "containsPressChanged"; revision: 1 }
+ Signal { name: "containsPressChanged"; revision: 4 }
Signal { name: "pressAndHoldIntervalChanged"; revision: 9 }
}
Component {
@@ -3172,13 +3238,21 @@ Module {
name: "QQuickPath"
defaultProperty: "pathElements"
prototype: "QObject"
- exports: ["QtQuick/Path 2.0"]
- exportMetaObjectRevisions: [0]
+ exports: ["QtQuick/Path 2.0", "QtQuick/Path 2.14"]
+ exportMetaObjectRevisions: [0, 14]
Property { name: "pathElements"; type: "QQuickPathElement"; isList: true; isReadonly: true }
Property { name: "startX"; type: "double" }
Property { name: "startY"; type: "double" }
Property { name: "closed"; type: "bool"; isReadonly: true }
+ Property { name: "scale"; revision: 14; type: "QSizeF" }
Signal { name: "changed" }
+ Signal { name: "scaleChanged"; revision: 14 }
+ Method {
+ name: "pointAtPercent"
+ revision: 14
+ type: "QPointF"
+ Parameter { name: "t"; type: "double" }
+ }
}
Component {
name: "QQuickPathAngleArc"
@@ -3250,7 +3324,7 @@ Module {
name: "QQuickPathArc"
prototype: "QQuickCurve"
exports: ["QtQuick/PathArc 2.0", "QtQuick/PathArc 2.9"]
- exportMetaObjectRevisions: [0, 2]
+ exportMetaObjectRevisions: [0, 9]
Enum {
name: "ArcDirection"
values: {
@@ -3262,8 +3336,8 @@ Module {
Property { name: "radiusY"; type: "double" }
Property { name: "useLargeArc"; type: "bool" }
Property { name: "direction"; type: "ArcDirection" }
- Property { name: "xAxisRotation"; revision: 2; type: "double" }
- Signal { name: "xAxisRotationChanged"; revision: 2 }
+ Property { name: "xAxisRotation"; revision: 9; type: "double" }
+ Signal { name: "xAxisRotationChanged"; revision: 9 }
}
Component {
name: "QQuickPathAttribute"
@@ -3322,6 +3396,14 @@ Module {
exportMetaObjectRevisions: [0]
}
Component {
+ name: "QQuickPathMultiline"
+ prototype: "QQuickCurve"
+ exports: ["QtQuick/PathMultiline 2.14"]
+ exportMetaObjectRevisions: [0]
+ Property { name: "start"; type: "QPointF"; isReadonly: true }
+ Property { name: "paths"; type: "QVariantList" }
+ }
+ Component {
name: "QQuickPathPercent"
prototype: "QQuickPathElement"
exports: ["QtQuick/PathPercent 2.0"]
@@ -3329,6 +3411,14 @@ Module {
Property { name: "value"; type: "double" }
}
Component {
+ name: "QQuickPathPolyline"
+ prototype: "QQuickCurve"
+ exports: ["QtQuick/PathPolyline 2.14"]
+ exportMetaObjectRevisions: [0]
+ Property { name: "start"; type: "QPointF"; isReadonly: true }
+ Property { name: "path"; type: "QVariantList" }
+ }
+ Component {
name: "QQuickPathQuad"
prototype: "QQuickCurve"
exports: ["QtQuick/PathQuad 2.0"]
@@ -3508,7 +3598,7 @@ Module {
defaultProperty: "data"
prototype: "QQuickItem"
exports: ["QtQuick/PinchArea 2.0", "QtQuick/PinchArea 2.5"]
- exportMetaObjectRevisions: [0, 1]
+ exportMetaObjectRevisions: [0, 5]
Property { name: "enabled"; type: "bool" }
Property { name: "pinch"; type: "QQuickPinch"; isReadonly: true; isPointer: true }
Signal {
@@ -3525,7 +3615,7 @@ Module {
}
Signal {
name: "smartZoom"
- revision: 1
+ revision: 5
Parameter { name: "pinch"; type: "QQuickPinchEvent"; isPointer: true }
}
}
@@ -3920,7 +4010,7 @@ Module {
defaultProperty: "data"
prototype: "QQuickItem"
exports: ["QtQuick/ShaderEffect 2.0", "QtQuick/ShaderEffect 2.4"]
- exportMetaObjectRevisions: [0, 1]
+ exportMetaObjectRevisions: [0, 4]
Enum {
name: "CullMode"
values: {
@@ -3944,7 +4034,7 @@ Module {
Property { name: "cullMode"; type: "CullMode" }
Property { name: "log"; type: "string"; isReadonly: true }
Property { name: "status"; type: "Status"; isReadonly: true }
- Property { name: "supportsAtlasTextures"; revision: 1; type: "bool" }
+ Property { name: "supportsAtlasTextures"; revision: 4; type: "bool" }
}
Component {
name: "QQuickShaderEffectMesh"
@@ -3963,7 +4053,7 @@ Module {
"QtQuick/ShaderEffectSource 2.6",
"QtQuick/ShaderEffectSource 2.9"
]
- exportMetaObjectRevisions: [0, 1, 2]
+ exportMetaObjectRevisions: [0, 6, 9]
Enum {
name: "WrapMode"
values: {
@@ -3998,8 +4088,8 @@ Module {
Property { name: "hideSource"; type: "bool" }
Property { name: "mipmap"; type: "bool" }
Property { name: "recursive"; type: "bool" }
- Property { name: "textureMirroring"; revision: 1; type: "TextureMirroring" }
- Property { name: "samples"; revision: 2; type: "int" }
+ Property { name: "textureMirroring"; revision: 6; type: "TextureMirroring" }
+ Property { name: "samples"; revision: 9; type: "int" }
Signal { name: "scheduledUpdateCompleted" }
Method { name: "scheduleUpdate" }
}
@@ -4011,11 +4101,11 @@ Module {
"QtQuick/Shortcut 2.6",
"QtQuick/Shortcut 2.9"
]
- exportMetaObjectRevisions: [0, 1, 9]
+ exportMetaObjectRevisions: [0, 6, 9]
Property { name: "sequence"; type: "QVariant" }
Property { name: "sequences"; revision: 9; type: "QVariantList" }
- Property { name: "nativeText"; revision: 1; type: "string"; isReadonly: true }
- Property { name: "portableText"; revision: 1; type: "string"; isReadonly: true }
+ Property { name: "nativeText"; revision: 6; type: "string"; isReadonly: true }
+ Property { name: "portableText"; revision: 6; type: "string"; isReadonly: true }
Property { name: "enabled"; type: "bool" }
Property { name: "autoRepeat"; type: "bool" }
Property { name: "context"; type: "Qt::ShortcutContext" }
@@ -4229,7 +4319,7 @@ Module {
exports: ["QtQuick/State 2.0"]
exportMetaObjectRevisions: [0]
Property { name: "name"; type: "string" }
- Property { name: "when"; type: "QQmlBinding"; isPointer: true }
+ Property { name: "when"; type: "bool" }
Property { name: "extend"; type: "string" }
Property { name: "changes"; type: "QQuickStateOperation"; isList: true; isReadonly: true }
Signal { name: "completed" }
@@ -4340,8 +4430,8 @@ Module {
name: "QQuickTableView"
defaultProperty: "flickableData"
prototype: "QQuickFlickable"
- exports: ["QtQuick/TableView 2.12"]
- exportMetaObjectRevisions: [0]
+ exports: ["QtQuick/TableView 2.12", "QtQuick/TableView 2.14"]
+ exportMetaObjectRevisions: [0, 14]
attachedType: "QQuickTableViewAttached"
Property { name: "rows"; type: "int"; isReadonly: true }
Property { name: "columns"; type: "int"; isReadonly: true }
@@ -4354,6 +4444,10 @@ Module {
Property { name: "reuseItems"; type: "bool" }
Property { name: "contentWidth"; type: "double" }
Property { name: "contentHeight"; type: "double" }
+ Property { name: "syncView"; revision: 14; type: "QQuickTableView"; isPointer: true }
+ Property { name: "syncDirection"; revision: 14; type: "Qt::Orientations" }
+ Signal { name: "syncViewChanged"; revision: 14 }
+ Signal { name: "syncDirectionChanged"; revision: 14 }
Method { name: "forceLayout" }
}
Component {
@@ -4440,6 +4534,7 @@ Module {
values: {
"PlainText": 0,
"RichText": 1,
+ "MarkdownText": 3,
"AutoText": 2,
"StyledText": 4
}
@@ -4631,7 +4726,8 @@ Module {
values: {
"PlainText": 0,
"RichText": 1,
- "AutoText": 2
+ "AutoText": 2,
+ "MarkdownText": 3
}
}
Enum {
@@ -4892,7 +4988,7 @@ Module {
"QtQuick/TextInput 2.7",
"QtQuick/TextInput 2.9"
]
- exportMetaObjectRevisions: [0, 2, 3, 6, 7, 9]
+ exportMetaObjectRevisions: [0, 2, 4, 6, 7, 9]
Enum {
name: "EchoMode"
values: {
@@ -4976,7 +5072,7 @@ Module {
Property { name: "echoMode"; type: "EchoMode" }
Property { name: "activeFocusOnPress"; type: "bool" }
Property { name: "passwordCharacter"; type: "string" }
- Property { name: "passwordMaskDelay"; revision: 3; type: "int" }
+ Property { name: "passwordMaskDelay"; revision: 4; type: "int" }
Property { name: "displayText"; type: "string"; isReadonly: true }
Property { name: "preeditText"; revision: 7; type: "string"; isReadonly: true }
Property { name: "autoScroll"; type: "bool" }
@@ -5036,7 +5132,7 @@ Module {
}
Signal {
name: "passwordMaskDelayChanged"
- revision: 3
+ revision: 4
Parameter { name: "delay"; type: "int" }
}
Signal { name: "preeditTextChanged"; revision: 7 }
@@ -5093,7 +5189,7 @@ Module {
}
Method {
name: "ensureVisible"
- revision: 3
+ revision: 4
Parameter { name: "position"; type: "int" }
}
Method { name: "clear"; revision: 7 }
@@ -5117,7 +5213,7 @@ Module {
}
Method {
name: "inputMethodQuery"
- revision: 3
+ revision: 4
type: "QVariant"
Parameter { name: "query"; type: "Qt::InputMethodQuery" }
Parameter { name: "argument"; type: "QVariant" }
@@ -5272,6 +5368,24 @@ Module {
Property { name: "accepted"; type: "bool" }
}
Component {
+ name: "QQuickWheelHandler"
+ prototype: "QQuickSinglePointHandler"
+ exports: ["QtQuick/WheelHandler 2.14"]
+ exportMetaObjectRevisions: [0]
+ Property { name: "orientation"; type: "Qt::Orientation" }
+ Property { name: "invertible"; type: "bool" }
+ Property { name: "activeTimeout"; type: "double" }
+ Property { name: "rotation"; type: "double" }
+ Property { name: "rotationScale"; type: "double" }
+ Property { name: "property"; type: "string" }
+ Property { name: "targetScaleMultiplier"; type: "double" }
+ Property { name: "targetTransformAroundCursor"; type: "bool" }
+ Signal {
+ name: "wheel"
+ Parameter { name: "event"; type: "QQuickPointerScrollEvent"; isPointer: true }
+ }
+ }
+ Component {
name: "QQuickWorkerScript"
prototype: "QObject"
exports: ["QtQuick/WorkerScript 2.0"]
@@ -5279,7 +5393,7 @@ Module {
Property { name: "source"; type: "QUrl" }
Signal {
name: "message"
- Parameter { name: "messageObject"; type: "QQmlV4Handle" }
+ Parameter { name: "messageObject"; type: "QJSValue" }
}
Method {
name: "sendMessage"
@@ -5310,8 +5424,31 @@ Module {
}
}
Component {
+ name: "QRegularExpressionValidator"
+ prototype: "QValidator"
+ exports: ["QtQuick/RegularExpressionValidator 2.14"]
+ exportMetaObjectRevisions: [0]
+ Property { name: "regularExpression"; type: "QRegularExpression" }
+ Signal {
+ name: "regularExpressionChanged"
+ Parameter { name: "re"; type: "QRegularExpression" }
+ }
+ Method {
+ name: "setRegularExpression"
+ Parameter { name: "re"; type: "QRegularExpression" }
+ }
+ }
+ Component {
name: "QValidator"
prototype: "QObject"
+ Enum {
+ name: "State"
+ values: {
+ "Invalid": 0,
+ "Intermediate": 1,
+ "Acceptable": 2
+ }
+ }
Signal { name: "changed" }
}
}
diff --git a/src/imports/shapes/plugins.qmltypes b/src/imports/shapes/plugins.qmltypes
index b78c5a1130..cd779e7149 100644
--- a/src/imports/shapes/plugins.qmltypes
+++ b/src/imports/shapes/plugins.qmltypes
@@ -4,7 +4,7 @@ import QtQuick.tooling 1.2
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable QtQuick.Shapes 1.13'
+// 'qmlplugindump -nonrelocatable QtQuick.Shapes 1.14'
Module {
dependencies: ["QtQuick 2.0"]
@@ -89,8 +89,11 @@ Module {
name: "QQuickShapePath"
defaultProperty: "pathElements"
prototype: "QQuickPath"
- exports: ["QtQuick.Shapes/ShapePath 1.0"]
- exportMetaObjectRevisions: [0]
+ exports: [
+ "QtQuick.Shapes/ShapePath 1.0",
+ "QtQuick.Shapes/ShapePath 1.14"
+ ]
+ exportMetaObjectRevisions: [0, 14]
Enum {
name: "FillRule"
values: {
@@ -132,6 +135,7 @@ Module {
Property { name: "dashOffset"; type: "double" }
Property { name: "dashPattern"; type: "QVector<qreal>" }
Property { name: "fillGradient"; type: "QQuickShapeGradient"; isPointer: true }
+ Property { name: "scale"; revision: 14; type: "QSizeF" }
Signal { name: "shapePathChanged" }
}
Component {
diff --git a/src/imports/statemachine/plugins.qmltypes b/src/imports/statemachine/plugins.qmltypes
index f92aeaa080..541b1cc114 100644
--- a/src/imports/statemachine/plugins.qmltypes
+++ b/src/imports/statemachine/plugins.qmltypes
@@ -4,7 +4,7 @@ import QtQuick.tooling 1.2
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable -dependencies dependencies.json QtQml.StateMachine 1.13'
+// 'qmlplugindump -nonrelocatable -dependencies dependencies.json QtQml.StateMachine 1.14'
Module {
dependencies: []
diff --git a/src/imports/testlib/main.cpp b/src/imports/testlib/main.cpp
index fbaf3bc4e2..33fe912692 100644
--- a/src/imports/testlib/main.cpp
+++ b/src/imports/testlib/main.cpp
@@ -150,7 +150,7 @@ public:
qmlRegisterType<QuickTestEvent>(uri,1,0,"TestEvent");
qmlRegisterType<QuickTestEvent>(uri,1,2,"TestEvent");
qmlRegisterType<QuickTestUtil>(uri,1,0,"TestUtil");
- qmlRegisterType<QQuickTouchEventSequence>();
+ qmlRegisterAnonymousType<QQuickTouchEventSequence>(uri);
// Auto-increment the import to stay in sync with ALL future QtQuick minor versions from 5.11 onward
qmlRegisterModule(uri, 1, QT_VERSION_MINOR);
diff --git a/src/imports/testlib/plugins.qmltypes b/src/imports/testlib/plugins.qmltypes
index 1e081d82ff..6a1371e5f1 100644
--- a/src/imports/testlib/plugins.qmltypes
+++ b/src/imports/testlib/plugins.qmltypes
@@ -4,7 +4,7 @@ import QtQuick.tooling 1.2
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable QtTest 1.13'
+// 'qmlplugindump -nonrelocatable QtTest 1.14'
Module {
dependencies: ["QtQuick 2.0", "QtQuick.Window 2.0"]
@@ -343,7 +343,7 @@ Module {
Property { name: "dragThreshold"; type: "int"; isReadonly: true }
Method {
name: "typeName"
- type: "QQmlV4Handle"
+ type: "QJSValue"
Parameter { name: "v"; type: "QVariant" }
}
Method {
@@ -354,10 +354,10 @@ Module {
}
Method {
name: "callerFile"
- type: "QQmlV4Handle"
+ type: "QJSValue"
Parameter { name: "frameIndex"; type: "int" }
}
- Method { name: "callerFile"; type: "QQmlV4Handle" }
+ Method { name: "callerFile"; type: "QJSValue" }
Method {
name: "callerLine"
type: "int"
diff --git a/src/imports/wavefrontmesh/plugins.qmltypes b/src/imports/wavefrontmesh/plugins.qmltypes
index b9dd9e4c46..4e6a1dca73 100644
--- a/src/imports/wavefrontmesh/plugins.qmltypes
+++ b/src/imports/wavefrontmesh/plugins.qmltypes
@@ -4,7 +4,7 @@ import QtQuick.tooling 1.2
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable Qt.labs.wavefrontmesh 1.13'
+// 'qmlplugindump -nonrelocatable Qt.labs.wavefrontmesh 1.14'
Module {
dependencies: ["QtQuick 2.0"]
diff --git a/src/imports/window/plugins.qmltypes b/src/imports/window/plugins.qmltypes
index b5786ed5a6..82b7ce0fc5 100644
--- a/src/imports/window/plugins.qmltypes
+++ b/src/imports/window/plugins.qmltypes
@@ -4,7 +4,7 @@ import QtQuick.tooling 1.2
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable QtQuick.Window 2.13'
+// 'qmlplugindump -nonrelocatable QtQuick.Window 2.14'
Module {
dependencies: ["QtQuick 2.0"]
@@ -26,7 +26,7 @@ Module {
prototype: "QObject"
exports: ["QtQuick.Window/Screen 2.0", "QtQuick.Window/Screen 2.3"]
isCreatable: false
- exportMetaObjectRevisions: [0, 1]
+ exportMetaObjectRevisions: [0, 3]
attachedType: "QQuickScreenAttached"
}
Component {
@@ -48,7 +48,7 @@ Module {
"QtQuick.Window/ScreenInfo 2.3"
]
isCreatable: false
- exportMetaObjectRevisions: [10, 2]
+ exportMetaObjectRevisions: [10, 3]
Property { name: "name"; type: "string"; isReadonly: true }
Property { name: "manufacturer"; revision: 10; type: "string"; isReadonly: true }
Property { name: "model"; revision: 10; type: "string"; isReadonly: true }
@@ -62,14 +62,14 @@ Module {
Property { name: "devicePixelRatio"; type: "double"; isReadonly: true }
Property { name: "primaryOrientation"; type: "Qt::ScreenOrientation"; isReadonly: true }
Property { name: "orientation"; type: "Qt::ScreenOrientation"; isReadonly: true }
- Property { name: "virtualX"; revision: 1; type: "int"; isReadonly: true }
- Property { name: "virtualY"; revision: 1; type: "int"; isReadonly: true }
+ Property { name: "virtualX"; revision: 3; type: "int"; isReadonly: true }
+ Property { name: "virtualY"; revision: 3; type: "int"; isReadonly: true }
Signal { name: "manufacturerChanged"; revision: 10 }
Signal { name: "modelChanged"; revision: 10 }
Signal { name: "serialNumberChanged"; revision: 10 }
Signal { name: "desktopGeometryChanged" }
- Signal { name: "virtualXChanged"; revision: 1 }
- Signal { name: "virtualYChanged"; revision: 1 }
+ Signal { name: "virtualXChanged"; revision: 3 }
+ Signal { name: "virtualYChanged"; revision: 3 }
}
Component {
name: "QQuickWindow"
@@ -140,6 +140,8 @@ Module {
Parameter { name: "error"; type: "QQuickWindow::SceneGraphError" }
Parameter { name: "message"; type: "string" }
}
+ Signal { name: "beforeRenderPassRecording"; revision: 14 }
+ Signal { name: "afterRenderPassRecording"; revision: 14 }
Method { name: "update" }
Method { name: "releaseResources" }
}
@@ -164,11 +166,11 @@ Module {
"QtQuick.Window/Window 2.2",
"QtQuick.Window/Window 2.3"
]
- exportMetaObjectRevisions: [0, 13, 1, 2]
+ exportMetaObjectRevisions: [0, 13, 2, 3]
attachedType: "QQuickWindowAttached"
Property { name: "visible"; type: "bool" }
Property { name: "visibility"; type: "Visibility" }
- Property { name: "screen"; revision: 2; type: "QObject"; isPointer: true }
+ Property { name: "screen"; revision: 3; type: "QObject"; isPointer: true }
Signal {
name: "visibleChanged"
Parameter { name: "arg"; type: "bool" }
@@ -177,7 +179,7 @@ Module {
name: "visibilityChanged"
Parameter { name: "visibility"; type: "QWindow::Visibility" }
}
- Signal { name: "screenChanged"; revision: 2 }
+ Signal { name: "screenChanged"; revision: 3 }
}
Component {
name: "QWindow"
diff --git a/src/imports/workerscript/plugins.qmltypes b/src/imports/workerscript/plugins.qmltypes
new file mode 100644
index 0000000000..b1d6107022
--- /dev/null
+++ b/src/imports/workerscript/plugins.qmltypes
@@ -0,0 +1,26 @@
+import QtQuick.tooling 1.2
+
+// This file describes the plugin-supplied types contained in the library.
+// It is used for QML tooling purposes only.
+//
+// This file was auto-generated by:
+// 'qmlplugindump -nonrelocatable -dependencies dependencies.json QtQml.WorkerScript 2.14'
+
+Module {
+ dependencies: []
+ Component {
+ name: "QQuickWorkerScript"
+ prototype: "QObject"
+ exports: ["QtQml.WorkerScript/WorkerScript 2.0"]
+ exportMetaObjectRevisions: [0]
+ Property { name: "source"; type: "QUrl" }
+ Signal {
+ name: "message"
+ Parameter { name: "messageObject"; type: "QJSValue" }
+ }
+ Method {
+ name: "sendMessage"
+ Parameter { type: "QQmlV4Function"; isPointer: true }
+ }
+ }
+}
diff --git a/src/particles/particles.qrc b/src/particles/particles.qrc
index ad44cf406e..c7102b9aa5 100644
--- a/src/particles/particles.qrc
+++ b/src/particles/particles.qrc
@@ -16,5 +16,16 @@
<file>shaders/customparticletemplate_core.vert</file>
<file>shaders/imageparticle_core.frag</file>
<file>shaders/imageparticle_core.vert</file>
+
+ <file>shaders_ng/imageparticle_simple.vert.qsb</file>
+ <file>shaders_ng/imageparticle_simple.frag.qsb</file>
+ <file>shaders_ng/imageparticle_tabled.vert.qsb</file>
+ <file>shaders_ng/imageparticle_tabled.frag.qsb</file>
+ <file>shaders_ng/imageparticle_deformed.vert.qsb</file>
+ <file>shaders_ng/imageparticle_deformed.frag.qsb</file>
+ <file>shaders_ng/imageparticle_sprite.vert.qsb</file>
+ <file>shaders_ng/imageparticle_sprite.frag.qsb</file>
+ <file>shaders_ng/imageparticle_colored.vert.qsb</file>
+ <file>shaders_ng/imageparticle_colored.frag.qsb</file>
</qresource>
</RCC>
diff --git a/src/particles/qquickimageparticle.cpp b/src/particles/qquickimageparticle.cpp
index ae1ef80026..649fbb30c2 100644
--- a/src/particles/qquickimageparticle.cpp
+++ b/src/particles/qquickimageparticle.cpp
@@ -1,6 +1,6 @@
-/****************************************************************************
+/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQuick module of the Qt Toolkit.
@@ -41,7 +41,6 @@
#include <private/qsgadaptationlayer_p.h>
#include <private/qquickitem_p.h>
#include <QtQuick/qsgnode.h>
-#include <QtQuick/qsgtexturematerial.h>
#include <QtQuick/qsgtexture.h>
#include <QFile>
#include <QRandomGenerator>
@@ -56,13 +55,15 @@
#include <private/qqmlglobal_p.h>
#include <QtQml/qqmlinfo.h>
#include <cmath>
+#include <QtGui/private/qrhi_p.h>
QT_BEGIN_NAMESPACE
-//TODO: Make it larger on desktop? Requires fixing up shader code with the same define
+// Must match the shader code
#define UNIFORM_ARRAY_SIZE 64
const qreal CONV = 0.017453292519943295;
+
class ImageMaterialData
{
public:
@@ -85,13 +86,10 @@ class ImageMaterialData
QSizeF animSheetSize;
};
-class TabledMaterialData : public ImageMaterialData {};
-class TabledMaterial : public QSGSimpleMaterialShader<TabledMaterialData>
+class TabledMaterialShader : public QSGMaterialShader
{
- QSG_DECLARE_SIMPLE_SHADER(TabledMaterial, TabledMaterialData)
-
public:
- TabledMaterial()
+ TabledMaterialShader()
{
QSGShaderSourceBuilder builder;
const bool isES = QOpenGLContext::currentContext()->isOpenGLES();
@@ -122,36 +120,47 @@ public:
const char *vertexShader() const override { return m_vertex_code.constData(); }
const char *fragmentShader() const override { return m_fragment_code.constData(); }
- QList<QByteArray> attributes() const override {
- return QList<QByteArray>() << "vPosTex" << "vData" << "vVec"
- << "vColor" << "vDeformVec" << "vRotation";
- };
+ char const *const *attributeNames() const override
+ {
+ static const char *const attr[] = { "vPosTex", "vData", "vVec", "vColor", "vDeformVec", "vRotation", nullptr };
+ return attr;
+ }
void initialize() override {
- QSGSimpleMaterialShader<TabledMaterialData>::initialize();
program()->bind();
program()->setUniformValue("_qt_texture", 0);
program()->setUniformValue("colortable", 1);
glFuncs = QOpenGLContext::currentContext()->functions();
+ m_matrix_id = program()->uniformLocation("qt_Matrix");
+ m_opacity_id = program()->uniformLocation("qt_Opacity");
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*) override {
+ void updateState(const RenderState &renderState, QSGMaterial *mat, QSGMaterial *) override {
+ ImageMaterialData *state = static_cast<ImageMaterial *>(mat)->state();
+
+ if (renderState.isMatrixDirty())
+ program()->setUniformValue(m_matrix_id, renderState.combinedMatrix());
+ if (renderState.isOpacityDirty() && m_opacity_id >= 0)
+ program()->setUniformValue(m_opacity_id, renderState.opacity());
+
glFuncs->glActiveTexture(GL_TEXTURE1);
- d->colorTable->bind();
+ state->colorTable->bind();
glFuncs->glActiveTexture(GL_TEXTURE0);
- d->texture->bind();
+ state->texture->bind();
- program()->setUniformValue(m_timestamp_id, (float) d->timestamp);
- program()->setUniformValue(m_entry_id, (float) d->entry);
- program()->setUniformValueArray(m_sizetable_id, (const float*) d->sizeTable, UNIFORM_ARRAY_SIZE, 1);
- program()->setUniformValueArray(m_opacitytable_id, (const float*) d->opacityTable, UNIFORM_ARRAY_SIZE, 1);
+ program()->setUniformValue(m_timestamp_id, (float) state->timestamp);
+ program()->setUniformValue(m_entry_id, (float) state->entry);
+ program()->setUniformValueArray(m_sizetable_id, (const float*) state->sizeTable, UNIFORM_ARRAY_SIZE, 1);
+ program()->setUniformValueArray(m_opacitytable_id, (const float*) state->opacityTable, UNIFORM_ARRAY_SIZE, 1);
}
+ int m_matrix_id;
+ int m_opacity_id;
int m_entry_id;
int m_timestamp_id;
int m_sizetable_id;
@@ -161,13 +170,91 @@ public:
QOpenGLFunctions* glFuncs;
};
-class DeformableMaterialData : public ImageMaterialData {};
-class DeformableMaterial : public QSGSimpleMaterialShader<DeformableMaterialData>
+class TabledMaterialRhiShader : public QSGMaterialRhiShader
+{
+public:
+ TabledMaterialRhiShader()
+ {
+ setShaderFileName(VertexStage, QStringLiteral(":/particles/shaders_ng/imageparticle_tabled.vert.qsb"));
+ setShaderFileName(FragmentStage, QStringLiteral(":/particles/shaders_ng/imageparticle_tabled.frag.qsb"));
+ }
+
+ bool updateUniformData(const RenderState &renderState, QSGMaterial *newMaterial, QSGMaterial *) override
+ {
+ QByteArray *buf = renderState.uniformData();
+ Q_ASSERT(buf->size() >= 80 + 2 * (UNIFORM_ARRAY_SIZE * 4 * 4));
+
+ if (renderState.isMatrixDirty()) {
+ const QMatrix4x4 m = renderState.combinedMatrix();
+ memcpy(buf->data(), m.constData(), 64);
+ }
+
+ if (renderState.isOpacityDirty()) {
+ const float opacity = renderState.opacity();
+ memcpy(buf->data() + 64, &opacity, 4);
+ }
+
+ ImageMaterialData *state = static_cast<ImageMaterial *>(newMaterial)->state();
+
+ float entry = float(state->entry);
+ memcpy(buf->data() + 68, &entry, 4);
+
+ float timestamp = float(state->timestamp);
+ memcpy(buf->data() + 72, &timestamp, 4);
+
+ float *p = reinterpret_cast<float *>(buf->data() + 80);
+ for (int i = 0; i < UNIFORM_ARRAY_SIZE; ++i) {
+ *p = state->sizeTable[i];
+ p += 4;
+ }
+ p = reinterpret_cast<float *>(buf->data() + 80 + (UNIFORM_ARRAY_SIZE * 4 * 4));
+ for (int i = 0; i < UNIFORM_ARRAY_SIZE; ++i) {
+ *p = state->opacityTable[i];
+ p += 4;
+ }
+
+ return true;
+ }
+
+ void updateSampledImage(const RenderState &renderState, int binding, QSGTexture **texture,
+ QSGMaterial *newMaterial, QSGMaterial *) override
+ {
+ ImageMaterialData *state = static_cast<ImageMaterial *>(newMaterial)->state();
+ if (binding == 2) {
+ state->colorTable->updateRhiTexture(renderState.rhi(), renderState.resourceUpdateBatch());
+ *texture = state->colorTable;
+ } else if (binding == 1) {
+ state->texture->updateRhiTexture(renderState.rhi(), renderState.resourceUpdateBatch());
+ *texture = state->texture;
+ }
+ }
+};
+
+class TabledMaterial : public ImageMaterial
{
- QSG_DECLARE_SIMPLE_SHADER(DeformableMaterial, DeformableMaterialData)
+public:
+ TabledMaterial() { setFlag(SupportsRhiShader, true); }
+ QSGMaterialShader *createShader() const override {
+ if (flags().testFlag(RhiShaderWanted))
+ return new TabledMaterialRhiShader;
+ else
+ return new TabledMaterialShader;
+ }
+ QSGMaterialType *type() const override { return &m_type; }
+
+ ImageMaterialData *state() override { return &m_state; }
+private:
+ static QSGMaterialType m_type;
+ ImageMaterialData m_state;
+};
+
+QSGMaterialType TabledMaterial::m_type;
+
+class DeformableMaterialShader : public QSGMaterialShader
+{
public:
- DeformableMaterial()
+ DeformableMaterialShader()
{
QSGShaderSourceBuilder builder;
const bool isES = QOpenGLContext::currentContext()->isOpenGLES();
@@ -196,27 +283,38 @@ public:
const char *vertexShader() const override { return m_vertex_code.constData(); }
const char *fragmentShader() const override { return m_fragment_code.constData(); }
- QList<QByteArray> attributes() const override {
- return QList<QByteArray>() << "vPosTex" << "vData" << "vVec"
- << "vColor" << "vDeformVec" << "vRotation";
- };
+ char const *const *attributeNames() const override
+ {
+ static const char *const attr[] = { "vPosTex", "vData", "vVec", "vColor", "vDeformVec", "vRotation", nullptr };
+ return attr;
+ }
void initialize() override {
- QSGSimpleMaterialShader<DeformableMaterialData>::initialize();
program()->bind();
program()->setUniformValue("_qt_texture", 0);
glFuncs = QOpenGLContext::currentContext()->functions();
+ m_matrix_id = program()->uniformLocation("qt_Matrix");
+ m_opacity_id = program()->uniformLocation("qt_Opacity");
m_timestamp_id = program()->uniformLocation("timestamp");
m_entry_id = program()->uniformLocation("entry");
}
- void updateState(const DeformableMaterialData* d, const DeformableMaterialData*) override {
- d->texture->bind();
+ void updateState(const RenderState &renderState, QSGMaterial *mat, QSGMaterial *) override {
+ ImageMaterialData *state = static_cast<ImageMaterial *>(mat)->state();
+
+ if (renderState.isMatrixDirty())
+ program()->setUniformValue(m_matrix_id, renderState.combinedMatrix());
+ if (renderState.isOpacityDirty() && m_opacity_id >= 0)
+ program()->setUniformValue(m_opacity_id, renderState.opacity());
+
+ state->texture->bind();
- program()->setUniformValue(m_timestamp_id, (float) d->timestamp);
- program()->setUniformValue(m_entry_id, (float) d->entry);
+ program()->setUniformValue(m_timestamp_id, (float) state->timestamp);
+ program()->setUniformValue(m_entry_id, (float) state->entry);
}
+ int m_matrix_id;
+ int m_opacity_id;
int m_entry_id;
int m_timestamp_id;
QByteArray m_vertex_code;
@@ -224,13 +322,77 @@ public:
QOpenGLFunctions* glFuncs;
};
-class SpriteMaterialData : public ImageMaterialData {};
-class SpriteMaterial : public QSGSimpleMaterialShader<SpriteMaterialData>
+class DeformableMaterialRhiShader : public QSGMaterialRhiShader
{
- QSG_DECLARE_SIMPLE_SHADER(SpriteMaterial, SpriteMaterialData)
+public:
+ DeformableMaterialRhiShader()
+ {
+ setShaderFileName(VertexStage, QStringLiteral(":/particles/shaders_ng/imageparticle_deformed.vert.qsb"));
+ setShaderFileName(FragmentStage, QStringLiteral(":/particles/shaders_ng/imageparticle_deformed.frag.qsb"));
+ }
+ bool updateUniformData(const RenderState &renderState, QSGMaterial *newMaterial, QSGMaterial *) override
+ {
+ QByteArray *buf = renderState.uniformData();
+ Q_ASSERT(buf->size() >= 80 + 2 * (UNIFORM_ARRAY_SIZE * 4 * 4));
+
+ if (renderState.isMatrixDirty()) {
+ const QMatrix4x4 m = renderState.combinedMatrix();
+ memcpy(buf->data(), m.constData(), 64);
+ }
+
+ if (renderState.isOpacityDirty()) {
+ const float opacity = renderState.opacity();
+ memcpy(buf->data() + 64, &opacity, 4);
+ }
+
+ ImageMaterialData *state = static_cast<ImageMaterial *>(newMaterial)->state();
+
+ float entry = float(state->entry);
+ memcpy(buf->data() + 68, &entry, 4);
+
+ float timestamp = float(state->timestamp);
+ memcpy(buf->data() + 72, &timestamp, 4);
+
+ return true;
+ }
+
+ void updateSampledImage(const RenderState &renderState, int binding, QSGTexture **texture,
+ QSGMaterial *newMaterial, QSGMaterial *) override
+ {
+ ImageMaterialData *state = static_cast<ImageMaterial *>(newMaterial)->state();
+ if (binding == 1) {
+ state->texture->updateRhiTexture(renderState.rhi(), renderState.resourceUpdateBatch());
+ *texture = state->texture;
+ }
+ }
+};
+
+class DeformableMaterial : public ImageMaterial
+{
public:
- SpriteMaterial()
+ DeformableMaterial() { setFlag(SupportsRhiShader, true); }
+ QSGMaterialShader *createShader() const override {
+ if (flags().testFlag(RhiShaderWanted))
+ return new DeformableMaterialRhiShader;
+ else
+ return new DeformableMaterialShader;
+ }
+ QSGMaterialType *type() const override { return &m_type; }
+
+ ImageMaterialData *state() override { return &m_state; }
+
+private:
+ static QSGMaterialType m_type;
+ ImageMaterialData m_state;
+};
+
+QSGMaterialType DeformableMaterial::m_type;
+
+class SpriteMaterialShader : public QSGMaterialShader
+{
+public:
+ SpriteMaterialShader()
{
QSGShaderSourceBuilder builder;
const bool isES = QOpenGLContext::currentContext()->isOpenGLES();
@@ -263,17 +425,20 @@ public:
const char *vertexShader() const override { return m_vertex_code.constData(); }
const char *fragmentShader() const override { return m_fragment_code.constData(); }
- QList<QByteArray> attributes() const override {
- return QList<QByteArray>() << "vPosTex" << "vData" << "vVec"
- << "vColor" << "vDeformVec" << "vRotation" << "vAnimData" << "vAnimPos";
+ char const *const *attributeNames() const override
+ {
+ static const char *const attr[] = { "vPosTex", "vData", "vVec", "vColor", "vDeformVec", "vRotation",
+ "vAnimData", "vAnimPos", nullptr };
+ return attr;
}
void initialize() override {
- QSGSimpleMaterialShader<SpriteMaterialData>::initialize();
program()->bind();
program()->setUniformValue("_qt_texture", 0);
program()->setUniformValue("colortable", 1);
glFuncs = QOpenGLContext::currentContext()->functions();
+ m_matrix_id = program()->uniformLocation("qt_Matrix");
+ m_opacity_id = program()->uniformLocation("qt_Opacity");
//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");
@@ -281,20 +446,29 @@ public:
m_opacitytable_id = program()->uniformLocation("opacitytable");
}
- void updateState(const SpriteMaterialData* d, const SpriteMaterialData*) override {
+ void updateState(const RenderState &renderState, QSGMaterial *mat, QSGMaterial *) override {
+ ImageMaterialData *state = static_cast<ImageMaterial *>(mat)->state();
+
+ if (renderState.isMatrixDirty())
+ program()->setUniformValue(m_matrix_id, renderState.combinedMatrix());
+ if (renderState.isOpacityDirty() && m_opacity_id >= 0)
+ program()->setUniformValue(m_opacity_id, renderState.opacity());
+
glFuncs->glActiveTexture(GL_TEXTURE1);
- d->colorTable->bind();
+ state->colorTable->bind();
// make sure we end by setting GL_TEXTURE0 as active texture
glFuncs->glActiveTexture(GL_TEXTURE0);
- d->texture->bind();
+ state->texture->bind();
- program()->setUniformValue(m_timestamp_id, (float) d->timestamp);
- program()->setUniformValue(m_entry_id, (float) d->entry);
- program()->setUniformValueArray(m_sizetable_id, (const float*) d->sizeTable, 64, 1);
- program()->setUniformValueArray(m_opacitytable_id, (const float*) d->opacityTable, UNIFORM_ARRAY_SIZE, 1);
+ program()->setUniformValue(m_timestamp_id, (float) state->timestamp);
+ program()->setUniformValue(m_entry_id, (float) state->entry);
+ program()->setUniformValueArray(m_sizetable_id, (const float*) state->sizeTable, 64, 1);
+ program()->setUniformValueArray(m_opacitytable_id, (const float*) state->opacityTable, UNIFORM_ARRAY_SIZE, 1);
}
+ int m_matrix_id;
+ int m_opacity_id;
int m_timestamp_id;
int m_entry_id;
int m_sizetable_id;
@@ -304,13 +478,91 @@ public:
QOpenGLFunctions* glFuncs;
};
-class ColoredMaterialData : public ImageMaterialData {};
-class ColoredMaterial : public QSGSimpleMaterialShader<ColoredMaterialData>
+class SpriteMaterialRhiShader : public QSGMaterialRhiShader
{
- QSG_DECLARE_SIMPLE_SHADER(ColoredMaterial, ColoredMaterialData)
+public:
+ SpriteMaterialRhiShader()
+ {
+ setShaderFileName(VertexStage, QStringLiteral(":/particles/shaders_ng/imageparticle_sprite.vert.qsb"));
+ setShaderFileName(FragmentStage, QStringLiteral(":/particles/shaders_ng/imageparticle_sprite.frag.qsb"));
+ }
+
+ bool updateUniformData(const RenderState &renderState, QSGMaterial *newMaterial, QSGMaterial *) override
+ {
+ QByteArray *buf = renderState.uniformData();
+ Q_ASSERT(buf->size() >= 80 + 2 * (UNIFORM_ARRAY_SIZE * 4 * 4));
+
+ if (renderState.isMatrixDirty()) {
+ const QMatrix4x4 m = renderState.combinedMatrix();
+ memcpy(buf->data(), m.constData(), 64);
+ }
+
+ if (renderState.isOpacityDirty()) {
+ const float opacity = renderState.opacity();
+ memcpy(buf->data() + 64, &opacity, 4);
+ }
+ ImageMaterialData *state = static_cast<ImageMaterial *>(newMaterial)->state();
+
+ float entry = float(state->entry);
+ memcpy(buf->data() + 68, &entry, 4);
+
+ float timestamp = float(state->timestamp);
+ memcpy(buf->data() + 72, &timestamp, 4);
+
+ float *p = reinterpret_cast<float *>(buf->data() + 80);
+ for (int i = 0; i < UNIFORM_ARRAY_SIZE; ++i) {
+ *p = state->sizeTable[i];
+ p += 4;
+ }
+ p = reinterpret_cast<float *>(buf->data() + 80 + (UNIFORM_ARRAY_SIZE * 4 * 4));
+ for (int i = 0; i < UNIFORM_ARRAY_SIZE; ++i) {
+ *p = state->opacityTable[i];
+ p += 4;
+ }
+
+ return true;
+ }
+
+ void updateSampledImage(const RenderState &renderState, int binding, QSGTexture **texture,
+ QSGMaterial *newMaterial, QSGMaterial *) override
+ {
+ ImageMaterialData *state = static_cast<ImageMaterial *>(newMaterial)->state();
+ if (binding == 2) {
+ state->colorTable->updateRhiTexture(renderState.rhi(), renderState.resourceUpdateBatch());
+ *texture = state->colorTable;
+ } else if (binding == 1) {
+ state->texture->updateRhiTexture(renderState.rhi(), renderState.resourceUpdateBatch());
+ *texture = state->texture;
+ }
+ }
+};
+
+class SpriteMaterial : public ImageMaterial
+{
public:
- ColoredMaterial()
+ SpriteMaterial() { setFlag(SupportsRhiShader, true); }
+ QSGMaterialShader *createShader() const override {
+ if (flags().testFlag(RhiShaderWanted))
+ return new SpriteMaterialRhiShader;
+ else
+ return new SpriteMaterialShader;
+ }
+ QSGMaterialType *type() const override { return &m_type; }
+
+ ImageMaterialData *state() override { return &m_state; }
+
+private:
+ static QSGMaterialType m_type;
+ ImageMaterialData m_state;
+};
+
+QSGMaterialType SpriteMaterial::m_type;
+
+class ColoredMaterialShader : public QSGMaterialShader
+{
+public:
+ ColoredMaterialShader()
{
QSGShaderSourceBuilder builder;
const bool isES = QOpenGLContext::currentContext()->isOpenGLES();
@@ -337,8 +589,23 @@ public:
const char *vertexShader() const override { return m_vertex_code.constData(); }
const char *fragmentShader() const override { return m_fragment_code.constData(); }
+ char const *const *attributeNames() const override
+ {
+ static const char *const attr[] = { "vPos", "vData", "vVec", "vColor", nullptr };
+ return attr;
+ }
+
+ void initialize() override {
+ program()->bind();
+ program()->setUniformValue("_qt_texture", 0);
+ glFuncs = QOpenGLContext::currentContext()->functions();
+ m_matrix_id = program()->uniformLocation("qt_Matrix");
+ m_opacity_id = program()->uniformLocation("qt_Opacity");
+ m_timestamp_id = program()->uniformLocation("timestamp");
+ m_entry_id = program()->uniformLocation("entry");
+ }
+
void activate() override {
- QSGSimpleMaterialShader<ColoredMaterialData>::activate();
#if !defined(QT_OPENGL_ES_2) && !defined(Q_OS_WIN)
glEnable(GL_POINT_SPRITE);
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
@@ -346,33 +613,28 @@ public:
}
void deactivate() override {
- QSGSimpleMaterialShader<ColoredMaterialData>::deactivate();
#if !defined(QT_OPENGL_ES_2) && !defined(Q_OS_WIN)
glDisable(GL_POINT_SPRITE);
glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
#endif
}
- QList<QByteArray> attributes() const override {
- return QList<QByteArray>() << "vPos" << "vData" << "vVec" << "vColor";
- }
+ void updateState(const RenderState &renderState, QSGMaterial *mat, QSGMaterial *) override {
+ ImageMaterialData *state = static_cast<ImageMaterial *>(mat)->state();
- void initialize() override {
- QSGSimpleMaterialShader<ColoredMaterialData>::initialize();
- program()->bind();
- program()->setUniformValue("_qt_texture", 0);
- glFuncs = QOpenGLContext::currentContext()->functions();
- m_timestamp_id = program()->uniformLocation("timestamp");
- m_entry_id = program()->uniformLocation("entry");
- }
+ if (renderState.isMatrixDirty())
+ program()->setUniformValue(m_matrix_id, renderState.combinedMatrix());
+ if (renderState.isOpacityDirty() && m_opacity_id >= 0)
+ program()->setUniformValue(m_opacity_id, renderState.opacity());
- void updateState(const ColoredMaterialData* d, const ColoredMaterialData*) override {
- d->texture->bind();
+ state->texture->bind();
- program()->setUniformValue(m_timestamp_id, (float) d->timestamp);
- program()->setUniformValue(m_entry_id, (float) d->entry);
+ program()->setUniformValue(m_timestamp_id, (float) state->timestamp);
+ program()->setUniformValue(m_entry_id, (float) state->entry);
}
+ int m_matrix_id;
+ int m_opacity_id;
int m_timestamp_id;
int m_entry_id;
QByteArray m_vertex_code;
@@ -380,13 +642,77 @@ public:
QOpenGLFunctions* glFuncs;
};
-class SimpleMaterialData : public ImageMaterialData {};
-class SimpleMaterial : public QSGSimpleMaterialShader<SimpleMaterialData>
+class ColoredMaterialRhiShader : public QSGMaterialRhiShader
+{
+public:
+ ColoredMaterialRhiShader()
+ {
+ setShaderFileName(VertexStage, QStringLiteral(":/particles/shaders_ng/imageparticle_colored.vert.qsb"));
+ setShaderFileName(FragmentStage, QStringLiteral(":/particles/shaders_ng/imageparticle_colored.frag.qsb"));
+ }
+
+ bool updateUniformData(const RenderState &renderState, QSGMaterial *newMaterial, QSGMaterial *) override
+ {
+ QByteArray *buf = renderState.uniformData();
+ Q_ASSERT(buf->size() >= 80 + 2 * (UNIFORM_ARRAY_SIZE * 4 * 4));
+
+ if (renderState.isMatrixDirty()) {
+ const QMatrix4x4 m = renderState.combinedMatrix();
+ memcpy(buf->data(), m.constData(), 64);
+ }
+
+ if (renderState.isOpacityDirty()) {
+ const float opacity = renderState.opacity();
+ memcpy(buf->data() + 64, &opacity, 4);
+ }
+
+ ImageMaterialData *state = static_cast<ImageMaterial *>(newMaterial)->state();
+
+ float entry = float(state->entry);
+ memcpy(buf->data() + 68, &entry, 4);
+
+ float timestamp = float(state->timestamp);
+ memcpy(buf->data() + 72, &timestamp, 4);
+
+ return true;
+ }
+
+ void updateSampledImage(const RenderState &renderState, int binding, QSGTexture **texture,
+ QSGMaterial *newMaterial, QSGMaterial *) override
+ {
+ ImageMaterialData *state = static_cast<ImageMaterial *>(newMaterial)->state();
+ if (binding == 1) {
+ state->texture->updateRhiTexture(renderState.rhi(), renderState.resourceUpdateBatch());
+ *texture = state->texture;
+ }
+ }
+};
+
+class ColoredMaterial : public ImageMaterial
{
- QSG_DECLARE_SIMPLE_SHADER(SimpleMaterial, SimpleMaterialData)
+public:
+ ColoredMaterial() { setFlag(SupportsRhiShader, true); }
+ QSGMaterialShader *createShader() const override {
+ if (flags().testFlag(RhiShaderWanted))
+ return new ColoredMaterialRhiShader;
+ else
+ return new ColoredMaterialShader;
+ }
+ QSGMaterialType *type() const override { return &m_type; }
+ ImageMaterialData *state() override { return &m_state; }
+
+private:
+ static QSGMaterialType m_type;
+ ImageMaterialData m_state;
+};
+
+QSGMaterialType ColoredMaterial::m_type;
+
+class SimpleMaterialShader : public QSGMaterialShader
+{
public:
- SimpleMaterial()
+ SimpleMaterialShader()
{
QSGShaderSourceBuilder builder;
const bool isES = QOpenGLContext::currentContext()->isOpenGLES();
@@ -411,8 +737,23 @@ public:
const char *vertexShader() const override { return m_vertex_code.constData(); }
const char *fragmentShader() const override { return m_fragment_code.constData(); }
+ char const *const *attributeNames() const override
+ {
+ static const char *const attr[] = { "vPos", "vData", "vVec", nullptr };
+ return attr;
+ }
+
+ void initialize() override {
+ program()->bind();
+ program()->setUniformValue("_qt_texture", 0);
+ glFuncs = QOpenGLContext::currentContext()->functions();
+ m_matrix_id = program()->uniformLocation("qt_Matrix");
+ m_opacity_id = program()->uniformLocation("qt_Opacity");
+ m_timestamp_id = program()->uniformLocation("timestamp");
+ m_entry_id = program()->uniformLocation("entry");
+ }
+
void activate() override {
- QSGSimpleMaterialShader<SimpleMaterialData>::activate();
#if !defined(QT_OPENGL_ES_2) && !defined(Q_OS_WIN)
glEnable(GL_POINT_SPRITE);
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
@@ -420,33 +761,28 @@ public:
}
void deactivate() override {
- QSGSimpleMaterialShader<SimpleMaterialData>::deactivate();
#if !defined(QT_OPENGL_ES_2) && !defined(Q_OS_WIN)
glDisable(GL_POINT_SPRITE);
glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
#endif
}
- QList<QByteArray> attributes() const override {
- return QList<QByteArray>() << "vPos" << "vData" << "vVec";
- }
+ void updateState(const RenderState &renderState, QSGMaterial *mat, QSGMaterial *) override {
+ ImageMaterialData *state = static_cast<ImageMaterial *>(mat)->state();
- void initialize() override {
- QSGSimpleMaterialShader<SimpleMaterialData>::initialize();
- program()->bind();
- program()->setUniformValue("_qt_texture", 0);
- glFuncs = QOpenGLContext::currentContext()->functions();
- m_timestamp_id = program()->uniformLocation("timestamp");
- m_entry_id = program()->uniformLocation("entry");
- }
+ if (renderState.isMatrixDirty())
+ program()->setUniformValue(m_matrix_id, renderState.combinedMatrix());
+ if (renderState.isOpacityDirty() && m_opacity_id >= 0)
+ program()->setUniformValue(m_opacity_id, renderState.opacity());
- void updateState(const SimpleMaterialData* d, const SimpleMaterialData*) override {
- d->texture->bind();
+ state->texture->bind();
- program()->setUniformValue(m_timestamp_id, (float) d->timestamp);
- program()->setUniformValue(m_entry_id, (float) d->entry);
+ program()->setUniformValue(m_timestamp_id, (float) state->timestamp);
+ program()->setUniformValue(m_entry_id, (float) state->entry);
}
+ int m_matrix_id;
+ int m_opacity_id;
int m_timestamp_id;
int m_entry_id;
QByteArray m_vertex_code;
@@ -454,6 +790,73 @@ public:
QOpenGLFunctions* glFuncs;
};
+class SimpleMaterialRhiShader : public QSGMaterialRhiShader
+{
+public:
+ SimpleMaterialRhiShader()
+ {
+ setShaderFileName(VertexStage, QStringLiteral(":/particles/shaders_ng/imageparticle_simple.vert.qsb"));
+ setShaderFileName(FragmentStage, QStringLiteral(":/particles/shaders_ng/imageparticle_simple.frag.qsb"));
+ }
+
+ bool updateUniformData(const RenderState &renderState, QSGMaterial *newMaterial, QSGMaterial *) override
+ {
+ QByteArray *buf = renderState.uniformData();
+ Q_ASSERT(buf->size() >= 80 + 2 * (UNIFORM_ARRAY_SIZE * 4 * 4));
+
+ if (renderState.isMatrixDirty()) {
+ const QMatrix4x4 m = renderState.combinedMatrix();
+ memcpy(buf->data(), m.constData(), 64);
+ }
+
+ if (renderState.isOpacityDirty()) {
+ const float opacity = renderState.opacity();
+ memcpy(buf->data() + 64, &opacity, 4);
+ }
+
+ ImageMaterialData *state = static_cast<ImageMaterial *>(newMaterial)->state();
+
+ float entry = float(state->entry);
+ memcpy(buf->data() + 68, &entry, 4);
+
+ float timestamp = float(state->timestamp);
+ memcpy(buf->data() + 72, &timestamp, 4);
+
+ return true;
+ }
+
+ void updateSampledImage(const RenderState &renderState, int binding, QSGTexture **texture,
+ QSGMaterial *newMaterial, QSGMaterial *) override
+ {
+ ImageMaterialData *state = static_cast<ImageMaterial *>(newMaterial)->state();
+ if (binding == 1) {
+ state->texture->updateRhiTexture(renderState.rhi(), renderState.resourceUpdateBatch());
+ *texture = state->texture;
+ }
+ }
+};
+
+class SimpleMaterial : public ImageMaterial
+{
+public:
+ SimpleMaterial() { setFlag(SupportsRhiShader, true); }
+ QSGMaterialShader *createShader() const override {
+ if (flags().testFlag(RhiShaderWanted))
+ return new SimpleMaterialRhiShader;
+ else
+ return new SimpleMaterialShader;
+ }
+ QSGMaterialType *type() const override { return &m_type; }
+
+ ImageMaterialData *state() override { return &m_state; }
+
+private:
+ static QSGMaterialType m_type;
+ ImageMaterialData m_state;
+};
+
+QSGMaterialType SimpleMaterial::m_type;
+
void fillUniformArrayFromImage(float* array, const QImage& img, int size)
{
if (img.isNull()){
@@ -726,6 +1129,8 @@ QQuickImageParticle::QQuickImageParticle(QQuickItem* parent)
, m_debugMode(false)
, m_entryEffect(Fade)
, m_startedImageLoading(0)
+ , m_rhi(nullptr)
+ , m_apiChecked(false)
{
setFlag(ItemHasContents);
}
@@ -1000,7 +1405,7 @@ void QQuickImageParticle::setEntryEffect(EntryEffect arg)
if (m_entryEffect != arg) {
m_entryEffect = arg;
if (m_material)
- getState<ImageMaterialData>(m_material)->entry = (qreal) m_entryEffect;
+ getState(m_material)->entry = (qreal) m_entryEffect;
emit entryEffectChanged(arg);
}
}
@@ -1224,7 +1629,7 @@ void QQuickImageParticle::buildParticleNodes(QSGNode** passThrough)
void QQuickImageParticle::finishBuildParticleNodes(QSGNode** node)
{
- if (!QOpenGLContext::currentContext())
+ if (!m_rhi && !QOpenGLContext::currentContext())
return;
if (m_count * 4 > 0xffff) {
@@ -1271,28 +1676,38 @@ void QQuickImageParticle::finishBuildParticleNodes(QSGNode** node)
}
}
}
+
+ if (!m_rhi) { // the RHI may be backed by GL but these checks should be obsolete in any case
#ifdef Q_OS_WIN
- if (perfLevel < Deformable) //QTBUG-24540 , point sprite 'extension' isn't working on windows.
- perfLevel = Deformable;
+ if (perfLevel < Deformable) //QTBUG-24540 , point sprite 'extension' isn't working on windows.
+ perfLevel = Deformable;
#endif
#ifdef Q_OS_MAC
- // OS X 10.8.3 introduced a bug in the AMD drivers, for at least the 2011 macbook pros,
- // causing point sprites who read gl_PointCoord in the frag shader to come out as
- // green-red blobs.
- const GLubyte *glVendor = QOpenGLContext::currentContext()->functions()->glGetString(GL_VENDOR);
- if (perfLevel < Deformable && glVendor && strstr((char *) glVendor, "ATI")) {
- perfLevel = Deformable;
- }
+ // macOS 10.8.3 introduced a bug in the AMD drivers, for at least the 2011 macbook pros,
+ // causing point sprites who read gl_PointCoord in the frag shader to come out as
+ // green-red blobs.
+ const GLubyte *glVendor = QOpenGLContext::currentContext()->functions()->glGetString(GL_VENDOR);
+ if (perfLevel < Deformable && glVendor && strstr((char *) glVendor, "ATI")) {
+ perfLevel = Deformable;
+ }
#endif
#ifdef Q_OS_LINUX
- // Nouveau drivers can potentially freeze a machine entirely when taking the point-sprite path.
- const GLubyte *glVendor = QOpenGLContext::currentContext()->functions()->glGetString(GL_VENDOR);
- if (perfLevel < Deformable && glVendor && strstr((const char *) glVendor, "nouveau"))
- perfLevel = Deformable;
+ // Nouveau drivers can potentially freeze a machine entirely when taking the point-sprite path.
+ const GLubyte *glVendor = QOpenGLContext::currentContext()->functions()->glGetString(GL_VENDOR);
+ if (perfLevel < Deformable && glVendor && strstr((const char *) glVendor, "nouveau"))
+ perfLevel = Deformable;
#endif
+ } else {
+ // Points with a size other than 1 are an optional feature with QRhi
+ // because some of the underlying APIs have no support for this.
+ // Therefore, avoid the point sprite path with APIs like Direct3D.
+ if (perfLevel < Deformable && !m_rhi->isFeatureSupported(QRhi::VertexShaderPointSize))
+ perfLevel = Deformable;
+ }
+
if (perfLevel >= Colored && !m_color.isValid())
m_color = QColor(Qt::white);//Hidden default, but different from unset
@@ -1308,6 +1723,7 @@ void QQuickImageParticle::finishBuildParticleNodes(QSGNode** node)
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
@@ -1318,16 +1734,19 @@ void QQuickImageParticle::finishBuildParticleNodes(QSGNode** node)
return;
imageLoaded = true;
}
- m_material = SpriteMaterial::createMaterial();
+ m_material = new SpriteMaterial;
+ ImageMaterialData *state = getState(m_material);
if (imageLoaded)
- getState<ImageMaterialData>(m_material)->texture = QSGPlainTexture::fromImage(image);
- getState<ImageMaterialData>(m_material)->animSheetSize = QSizeF(image.size() / image.devicePixelRatioF());
+ state->texture = QSGPlainTexture::fromImage(image);
+ state->animSheetSize = QSizeF(image.size() / image.devicePixelRatioF());
if (m_spriteEngine)
m_spriteEngine->setCount(m_count);
+ }
Q_FALLTHROUGH();
case Tabled:
+ {
if (!m_material)
- m_material = TabledMaterial::createMaterial();
+ m_material = new TabledMaterial;
if (m_colorTable) {
if (m_colorTable->pix.isReady())
@@ -1354,21 +1773,29 @@ void QQuickImageParticle::finishBuildParticleNodes(QSGNode** node)
colortable = QImage(1,1,QImage::Format_ARGB32_Premultiplied);
colortable.fill(Qt::white);
}
- getState<ImageMaterialData>(m_material)->colorTable = QSGPlainTexture::fromImage(colortable);
- fillUniformArrayFromImage(getState<ImageMaterialData>(m_material)->sizeTable, sizetable, UNIFORM_ARRAY_SIZE);
- fillUniformArrayFromImage(getState<ImageMaterialData>(m_material)->opacityTable, opacitytable, UNIFORM_ARRAY_SIZE);
+ ImageMaterialData *state = getState(m_material);
+ state->colorTable = QSGPlainTexture::fromImage(colortable);
+ fillUniformArrayFromImage(state->sizeTable, sizetable, UNIFORM_ARRAY_SIZE);
+ fillUniformArrayFromImage(state->opacityTable, opacitytable, UNIFORM_ARRAY_SIZE);
+ }
Q_FALLTHROUGH();
case Deformable:
+ {
if (!m_material)
- m_material = DeformableMaterial::createMaterial();
+ m_material = new DeformableMaterial;
+ }
Q_FALLTHROUGH();
case Colored:
+ {
if (!m_material)
- m_material = ColoredMaterial::createMaterial();
+ m_material = new ColoredMaterial;
+ }
Q_FALLTHROUGH();
default://Also Simple
+ {
if (!m_material)
- m_material = SimpleMaterial::createMaterial();
+ m_material = new SimpleMaterial;
+ ImageMaterialData *state = getState(m_material);
if (!imageLoaded) {
if (!m_image || !m_image->pix.isReady()) {
if (m_image)
@@ -1376,14 +1803,15 @@ void QQuickImageParticle::finishBuildParticleNodes(QSGNode** node)
delete m_material;
return;
}
- //getState<ImageMaterialData>(m_material)->texture //TODO: Shouldn't this be better? But not crash?
+ //state->texture //TODO: Shouldn't this be better? But not crash?
// = QQuickItemPrivate::get(this)->sceneGraphContext()->textureForFactory(m_imagePix.textureFactory());
- getState<ImageMaterialData>(m_material)->texture = QSGPlainTexture::fromImage(m_image->pix.image());
+ state->texture = QSGPlainTexture::fromImage(m_image->pix.image());
}
- getState<ImageMaterialData>(m_material)->texture->setFiltering(QSGTexture::Linear);
- getState<ImageMaterialData>(m_material)->entry = (qreal) m_entryEffect;
+ state->texture->setFiltering(QSGTexture::Linear);
+ state->entry = (qreal) m_entryEffect;
m_material->setFlag(QSGMaterial::Blending | QSGMaterial::RequiresFullMatrix);
}
+ }
m_nodes.clear();
for (auto groupId : groupIds()) {
@@ -1416,14 +1844,23 @@ void QQuickImageParticle::finishBuildParticleNodes(QSGNode** node)
node->setFlag(QSGNode::OwnsGeometry);
node->setGeometry(g);
if (perfLevel <= Colored){
- g->setDrawingMode(GL_POINTS);
- if (m_debugMode){
- GLfloat pointSizeRange[2];
- QOpenGLContext::currentContext()->functions()->glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, pointSizeRange);
- qDebug() << "Using point sprites, GL_ALIASED_POINT_SIZE_RANGE " <<pointSizeRange[0] << ":" << pointSizeRange[1];
+ g->setDrawingMode(QSGGeometry::DrawPoints);
+ if (m_debugMode) {
+ if (m_rhi) {
+ qDebug("Using point sprites");
+ } else {
+#if QT_CONFIG(opengl)
+ GLfloat pointSizeRange[2];
+ QOpenGLContext::currentContext()->functions()->glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, pointSizeRange);
+ qDebug() << "Using point sprites, GL_ALIASED_POINT_SIZE_RANGE " <<pointSizeRange[0] << ":" << pointSizeRange[1];
+#else
+ qDebug("Using point sprites");
+#endif
+ }
}
- }else
- g->setDrawingMode(GL_TRIANGLES);
+ } else {
+ g->setDrawingMode(QSGGeometry::DrawTriangles);
+ }
for (int p=0; p < count; ++p)
commit(groupId, p);//commit sets geometry for the node, has its own perfLevel switch
@@ -1464,16 +1901,34 @@ void QQuickImageParticle::finishBuildParticleNodes(QSGNode** node)
update();
}
-static inline bool isOpenGL(QSGRenderContext *rc)
-{
- QSGRendererInterface *rif = rc->sceneGraphContext()->rendererInterface(rc);
- return !rif || rif->graphicsApi() == QSGRendererInterface::OpenGL;
-}
-
QSGNode *QQuickImageParticle::updatePaintNode(QSGNode *node, UpdatePaintNodeData *)
{
- if (!node && !isOpenGL(QQuickItemPrivate::get(this)->sceneGraphRenderContext()))
- return nullptr;
+ if (!m_apiChecked || m_windowChanged) {
+ m_apiChecked = true;
+ m_windowChanged = false;
+
+ QSGRenderContext *rc = QQuickItemPrivate::get(this)->sceneGraphRenderContext();
+ QSGRendererInterface *rif = rc->sceneGraphContext()->rendererInterface(rc);
+ if (!rif)
+ return nullptr;
+
+ QSGRendererInterface::GraphicsApi api = rif->graphicsApi();
+ const bool isDirectOpenGL = api == QSGRendererInterface::OpenGL;
+ const bool isRhi = QSGRendererInterface::isApiRhiBased(api);
+
+ if (!node && !isDirectOpenGL && !isRhi)
+ return nullptr;
+
+ if (isRhi)
+ m_rhi = static_cast<QRhi *>(rif->getResource(m_window, QSGRendererInterface::RhiResource));
+ else
+ m_rhi = nullptr;
+
+ if (isRhi && !m_rhi) {
+ qWarning("Failed to query QRhi, particles disabled");
+ return nullptr;
+ }
+ }
if (m_pleaseReset){
if (node)
@@ -1541,7 +1996,7 @@ void QQuickImageParticle::prepareNextFrame(QSGNode **node)
case Colored:
case Simple:
default: //Also Simple
- getState<ImageMaterialData>(m_material)->timestamp = time;
+ getState(m_material)->timestamp = time;
break;
}
foreach (QSGGeometryNode* node, m_nodes)
@@ -1550,6 +2005,7 @@ void QQuickImageParticle::prepareNextFrame(QSGNode **node)
void QQuickImageParticle::spritesUpdate(qreal time)
{
+ ImageMaterialData *state = getState(m_material);
// Sprite progression handled CPU side, so as to have per-frame control.
for (auto groupId : groupIds()) {
for (QQuickParticleData* mainDatum : qAsConst(m_system->groupData[groupId]->data)) {
@@ -1587,7 +2043,7 @@ void QQuickImageParticle::spritesUpdate(qreal time)
}
if (m_spriteEngine->sprite(spriteIdx)->reverse())//### Store this in datum too?
frameAt = (datum->frameCount - 1) - frameAt;
- QSizeF sheetSize = getState<ImageMaterialData>(m_material)->animSheetSize;
+ QSizeF sheetSize = state->animSheetSize;
qreal y = datum->animY / sheetSize.height();
qreal w = datum->animWidth / sheetSize.width();
qreal h = datum->animHeight / sheetSize.height();
@@ -1686,6 +2142,7 @@ void QQuickImageParticle::initialize(int gIdx, int pIdx)
writeTo->animHeight = m_spriteEngine->spriteHeight(spriteIdx);
}
} else {
+ ImageMaterialData *state = getState(m_material);
QQuickParticleData* writeTo = getShadowDatum(datum);
writeTo->animT = datum->t;
writeTo->frameCount = 1;
@@ -1694,8 +2151,8 @@ void QQuickImageParticle::initialize(int gIdx, int pIdx)
writeTo->animIdx = 0;
writeTo->animT = 0;
writeTo->animX = writeTo->animY = 0;
- writeTo->animWidth = getState<ImageMaterialData>(m_material)->animSheetSize.width();
- writeTo->animHeight = getState<ImageMaterialData>(m_material)->animSheetSize.height();
+ writeTo->animWidth = state->animSheetSize.width();
+ writeTo->animHeight = state->animSheetSize.height();
}
Q_FALLTHROUGH();
case Tabled:
diff --git a/src/particles/qquickimageparticle_p.h b/src/particles/qquickimageparticle_p.h
index 95323c25a6..059cf67019 100644
--- a/src/particles/qquickimageparticle_p.h
+++ b/src/particles/qquickimageparticle_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQuick module of the Qt Toolkit.
@@ -37,8 +37,8 @@
**
****************************************************************************/
-#ifndef ULTRAPARTICLE_H
-#define ULTRAPARTICLE_H
+#ifndef QQUICKIMAGEPARTICLE_P_H
+#define QQUICKIMAGEPARTICLE_P_H
//
// W A R N I N G
@@ -50,21 +50,25 @@
//
// We mean it.
//
+
#include "qquickparticlepainter_p.h"
#include "qquickdirection_p.h"
#include <private/qquickpixmapcache_p.h>
#include <QQmlListProperty>
-#include <QtQuick/qsgsimplematerial.h>
#include <QtGui/qcolor.h>
+#include <QtQuick/qsgmaterial.h>
QT_BEGIN_NAMESPACE
class ImageMaterialData;
class QSGGeometryNode;
+class QSGMaterial;
class QQuickSprite;
class QQuickStochasticEngine;
+class QRhi;
+
struct SimpleVertex {
float x;
float y;
@@ -153,6 +157,12 @@ struct Vertices {
Vertex v4;
};
+class ImageMaterial : public QSGMaterial
+{
+public:
+ virtual ImageMaterialData *state() = 0;
+};
+
class QQuickImageParticle : public QQuickParticlePainter
{
Q_OBJECT
@@ -439,14 +449,17 @@ private:
}
}
- template<class MaterialData>
- static MaterialData* getState(QSGMaterial* m) {
- return static_cast<QSGSimpleMaterial<MaterialData> *>(m)->state();
+ ImageMaterialData *getState(QSGMaterial *m) {
+ return static_cast<ImageMaterial *>(m)->state();
}
+
EntryEffect m_entryEffect;
Status m_status;
int m_startedImageLoading;
+ QRhi *m_rhi;
+ bool m_apiChecked;
};
QT_END_NAMESPACE
-#endif // ULTRAPARTICLE_H
+
+#endif // QQUICKIMAGEPARTICLE_P_H
diff --git a/src/particles/qquickparticlepainter.cpp b/src/particles/qquickparticlepainter.cpp
index e762b3ae1d..78e11fafcf 100644
--- a/src/particles/qquickparticlepainter.cpp
+++ b/src/particles/qquickparticlepainter.cpp
@@ -70,6 +70,7 @@ QQuickParticlePainter::QQuickParticlePainter(QQuickItem *parent)
, m_count(0)
, m_pleaseReset(true)
, m_window(nullptr)
+ , m_windowChanged(false)
, m_groupIdsNeedRecalculation(false)
{
}
@@ -80,6 +81,7 @@ void QQuickParticlePainter::itemChange(ItemChange change, const ItemChangeData &
if (m_window)
disconnect(m_window, SIGNAL(sceneGraphInvalidated()), this, SLOT(sceneGraphInvalidated()));
m_window = data.window;
+ m_windowChanged = true;
if (m_window)
connect(m_window, SIGNAL(sceneGraphInvalidated()), this, SLOT(sceneGraphInvalidated()), Qt::DirectConnection);
}
diff --git a/src/particles/qquickparticlepainter_p.h b/src/particles/qquickparticlepainter_p.h
index ac14a18103..16fc6b6f45 100644
--- a/src/particles/qquickparticlepainter_p.h
+++ b/src/particles/qquickparticlepainter_p.h
@@ -141,6 +141,7 @@ protected:
QPointF m_systemOffset;
QQuickWindow *m_window;
+ bool m_windowChanged;
private: // methods
void recalculateGroupIds() const;
diff --git a/src/particles/shaders_ng/compile.bat b/src/particles/shaders_ng/compile.bat
new file mode 100755
index 0000000000..2376d5bf6d
--- /dev/null
+++ b/src/particles/shaders_ng/compile.bat
@@ -0,0 +1,53 @@
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+::
+:: Copyright (C) 2019 The Qt Company Ltd.
+:: Contact: https://www.qt.io/licensing/
+::
+:: This file is part of the QtQuick module of the Qt Toolkit.
+::
+:: $QT_BEGIN_LICENSE:LGPL$
+:: Commercial License Usage
+:: Licensees holding valid commercial Qt licenses may use this file in
+:: accordance with the commercial license agreement provided with the
+:: Software or, alternatively, in accordance with the terms contained in
+:: a written agreement between you and The Qt Company. For licensing terms
+:: and conditions see https://www.qt.io/terms-conditions. For further
+:: information use the contact form at https://www.qt.io/contact-us.
+::
+:: GNU Lesser General Public License Usage
+:: Alternatively, this file may be used under the terms of the GNU Lesser
+:: General Public License version 3 as published by the Free Software
+:: Foundation and appearing in the file LICENSE.LGPL3 included in the
+:: packaging of this file. Please review the following information to
+:: ensure the GNU Lesser General Public License version 3 requirements
+:: will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+::
+:: GNU General Public License Usage
+:: Alternatively, this file may be used under the terms of the GNU
+:: General Public License version 2.0 or (at your option) the GNU General
+:: Public license version 3 or any later version approved by the KDE Free
+:: Qt Foundation. The licenses are as published by the Free Software
+:: Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+:: included in the packaging of this file. Please review the following
+:: information to ensure the GNU General Public License requirements will
+:: be met: https://www.gnu.org/licenses/gpl-2.0.html and
+:: https://www.gnu.org/licenses/gpl-3.0.html.
+::
+:: $QT_END_LICENSE$
+::
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+
+qsb -b --glsl "150,120,100 es" --hlsl 50 --msl 12 -o imageparticle_simple.vert.qsb imageparticle.vert
+qsb --glsl "150,120,100 es" --hlsl 50 --msl 12 -o imageparticle_simple.frag.qsb imageparticle.frag
+
+qsb -DTABLE -DDEFORM -DCOLOR -b --glsl "150,120,100 es" --hlsl 50 --msl 12 -o imageparticle_tabled.vert.qsb imageparticle.vert
+qsb -DTABLE -DDEFORM -DCOLOR --glsl "150,120,100 es" --hlsl 50 --msl 12 -o imageparticle_tabled.frag.qsb imageparticle.frag
+
+qsb -DDEFORM -DCOLOR -b --glsl "150,120,100 es" --hlsl 50 --msl 12 -o imageparticle_deformed.vert.qsb imageparticle.vert
+qsb -DDEFORM -DCOLOR --glsl "150,120,100 es" --hlsl 50 --msl 12 -o imageparticle_deformed.frag.qsb imageparticle.frag
+
+qsb -DSPRITE -DTABLE -DDEFORM -DCOLOR -b --zorder-loc 8 --glsl "150,120,100 es" --hlsl 50 --msl 12 -o imageparticle_sprite.vert.qsb imageparticle.vert
+qsb -DSPRITE -DTABLE -DDEFORM -DCOLOR --glsl "150,120,100 es" --hlsl 50 --msl 12 -o imageparticle_sprite.frag.qsb imageparticle.frag
+
+qsb -DCOLOR -b --glsl "150,120,100 es" --hlsl 50 --msl 12 -o imageparticle_colored.vert.qsb imageparticle.vert
+qsb -DCOLOR --glsl "150,120,100 es" --hlsl 50 --msl 12 -o imageparticle_colored.frag.qsb imageparticle.frag
diff --git a/src/particles/shaders_ng/imageparticle.frag b/src/particles/shaders_ng/imageparticle.frag
new file mode 100644
index 0000000000..cefb7d2d75
--- /dev/null
+++ b/src/particles/shaders_ng/imageparticle.frag
@@ -0,0 +1,55 @@
+#version 440
+
+#if defined(TABLE)
+layout(location = 0) in vec2 tt;
+#endif
+
+#if defined(SPRITE)
+layout(location = 1) in vec4 fTexS;
+#elif defined(DEFORM)
+layout(location = 1) in vec2 fTex;
+#endif
+
+#if defined(COLOR)
+layout(location = 2) in vec4 fColor;
+#else
+layout(location = 2) in float fFade;
+#endif
+
+layout(location = 0) out vec4 fragColor;
+
+layout(std140, binding = 0) uniform buf {
+ mat4 matrix;
+ float opacity;
+ float entry;
+ float timestamp;
+ float sizetable[64];
+ float opacitytable[64];
+} ubuf;
+
+layout(binding = 1) uniform sampler2D _qt_texture;
+
+#if defined(TABLE) || defined(SPRITE)
+layout(binding = 2) uniform sampler2D colortable;
+#endif
+
+void main()
+{
+#if defined(SPRITE)
+ fragColor = mix(texture(_qt_texture, fTexS.xy), texture(_qt_texture, fTexS.zw), tt.y)
+ * fColor
+ * texture(colortable, tt)
+ * ubuf.opacity;
+#elif defined(TABLE)
+ fragColor = texture(_qt_texture, fTex)
+ * fColor
+ * texture(colortable, tt)
+ * ubuf.opacity;
+#elif defined(DEFORM)
+ fragColor = texture(_qt_texture, fTex) * fColor * ubuf.opacity;
+#elif defined(COLOR)
+ fragColor = texture(_qt_texture, gl_PointCoord) * fColor * ubuf.opacity;
+#else
+ fragColor = texture(_qt_texture, gl_PointCoord) * fFade * ubuf.opacity;
+#endif
+}
diff --git a/src/particles/shaders_ng/imageparticle.vert b/src/particles/shaders_ng/imageparticle.vert
new file mode 100644
index 0000000000..870139452b
--- /dev/null
+++ b/src/particles/shaders_ng/imageparticle.vert
@@ -0,0 +1,145 @@
+#version 440
+
+layout(location = 1) in vec4 vData; // x = time, y = lifeSpan, z = size, w = endSize
+layout(location = 2) in vec4 vVec; // x,y = constant velocity, z,w = acceleration
+
+#if defined(DEFORM)
+layout(location = 0) in vec4 vPosTex;
+#else
+layout(location = 0) in vec2 vPos;
+#endif
+
+#if defined(COLOR)
+layout(location = 3) in vec4 vColor;
+#endif
+
+#if defined(DEFORM)
+layout(location = 4) in vec4 vDeformVec; // x,y x unit vector; z,w = y unit vector
+layout(location = 5) in vec3 vRotation; // x = radians of rotation, y = rotation velocity, z = bool autoRotate
+#endif
+
+#if defined(SPRITE)
+layout(location = 6) in vec3 vAnimData; // w,h(premultiplied of anim), interpolation progress
+layout(location = 7) in vec4 vAnimPos; // x,y, x,y (two frames for interpolation)
+#endif
+
+#if defined(TABLE)
+layout(location = 0) out vec2 tt; //y is progress if Sprite mode
+#endif
+
+#if defined(SPRITE)
+layout(location = 1) out vec4 fTexS;
+#elif defined(DEFORM)
+layout(location = 1) out vec2 fTex;
+#endif
+
+#if defined(COLOR)
+layout(location = 2) out vec4 fColor;
+#else
+layout(location = 2) out float fFade;
+#endif
+
+layout(std140, binding = 0) uniform buf {
+ mat4 matrix;
+ float opacity;
+ float entry;
+ float timestamp;
+ float sizetable[64];
+ float opacitytable[64];
+} ubuf;
+
+out gl_PerVertex { vec4 gl_Position; float gl_PointSize; };
+
+void main()
+{
+ float t = (ubuf.timestamp - vData.x) / vData.y;
+ if (t < 0. || t > 1.) {
+#if defined(DEFORM)
+ gl_Position = ubuf.matrix * vec4(vPosTex.x, vPosTex.y, 0., 1.);
+#else
+ gl_PointSize = 0.;
+#endif
+ } else {
+#if defined(SPRITE)
+ tt.y = vAnimData.z;
+
+ // Calculate frame location in texture
+ fTexS.xy = vAnimPos.xy + vPosTex.zw * vAnimData.xy;
+
+ // Next frame is also passed, for interpolation
+ fTexS.zw = vAnimPos.zw + vPosTex.zw * vAnimData.xy;
+
+#elif defined(DEFORM)
+ fTex = vPosTex.zw;
+#endif
+ float currentSize = mix(vData.z, vData.w, t * t);
+ float fade = 1.;
+ float fadeIn = min(t * 10., 1.);
+ float fadeOut = 1. - clamp((t - 0.75) * 4.,0., 1.);
+
+#if defined(TABLE)
+ currentSize = currentSize * ubuf.sizetable[int(floor(t*64.))];
+ fade = fade * ubuf.opacitytable[int(floor(t*64.))];
+#endif
+
+ if (ubuf.entry == 1.)
+ fade = fade * fadeIn * fadeOut;
+ else if (ubuf.entry == 2.)
+ currentSize = currentSize * fadeIn * fadeOut;
+
+ if (currentSize <= 0.) {
+#if defined(DEFORM)
+ gl_Position = ubuf.matrix * vec4(vPosTex.x, vPosTex.y, 0., 1.);
+#else
+ gl_PointSize = 0.;
+#endif
+ } else {
+ if (currentSize < 3.) // Sizes too small look jittery as they move
+ currentSize = 3.;
+
+ vec2 pos;
+#if defined(DEFORM)
+ float rotation = vRotation.x + vRotation.y * t * vData.y;
+ if (vRotation.z == 1.0) {
+ vec2 curVel = vVec.zw * t * vData.y + vVec.xy;
+ if (length(curVel) > 0.)
+ rotation += atan(curVel.y, curVel.x);
+ }
+ vec2 trigCalcs = vec2(cos(rotation), sin(rotation));
+ vec4 deform = vDeformVec * currentSize * (vPosTex.zzww - 0.5);
+ vec4 rotatedDeform = deform.xxzz * trigCalcs.xyxy;
+ rotatedDeform = rotatedDeform + (deform.yyww * trigCalcs.yxyx * vec4(-1.,1.,-1.,1.));
+ /* The readable version:
+ vec2 xDeform = vDeformVec.xy * currentSize * (vTex.x-0.5);
+ vec2 yDeform = vDeformVec.zw * currentSize * (vTex.y-0.5);
+ vec2 xRotatedDeform;
+ xRotatedDeform.x = trigCalcs.x*xDeform.x - trigCalcs.y*xDeform.y;
+ xRotatedDeform.y = trigCalcs.y*xDeform.x + trigCalcs.x*xDeform.y;
+ vec2 yRotatedDeform;
+ yRotatedDeform.x = trigCalcs.x*yDeform.x - trigCalcs.y*yDeform.y;
+ yRotatedDeform.y = trigCalcs.y*yDeform.x + trigCalcs.x*yDeform.y;
+ */
+ pos = vPosTex.xy
+ + rotatedDeform.xy
+ + rotatedDeform.zw
+ + vVec.xy * t * vData.y // apply velocity
+ + 0.5 * vVec.zw * pow(t * vData.y, 2.); // apply acceleration
+#else
+ pos = vPos
+ + vVec.xy * t * vData.y // apply velocity vector..
+ + 0.5 * vVec.zw * pow(t * vData.y, 2.);
+ gl_PointSize = currentSize;
+#endif
+ gl_Position = ubuf.matrix * vec4(pos.x, pos.y, 0, 1);
+
+#if defined(COLOR)
+ fColor = vColor * fade;
+#else
+ fFade = fade;
+#endif
+#if defined(TABLE)
+ tt.x = t;
+#endif
+ }
+ }
+}
diff --git a/src/particles/shaders_ng/imageparticle_colored.frag.qsb b/src/particles/shaders_ng/imageparticle_colored.frag.qsb
new file mode 100644
index 0000000000..7ae640d224
--- /dev/null
+++ b/src/particles/shaders_ng/imageparticle_colored.frag.qsb
Binary files differ
diff --git a/src/particles/shaders_ng/imageparticle_colored.vert.qsb b/src/particles/shaders_ng/imageparticle_colored.vert.qsb
new file mode 100644
index 0000000000..0e2938b72c
--- /dev/null
+++ b/src/particles/shaders_ng/imageparticle_colored.vert.qsb
Binary files differ
diff --git a/src/particles/shaders_ng/imageparticle_deformed.frag.qsb b/src/particles/shaders_ng/imageparticle_deformed.frag.qsb
new file mode 100644
index 0000000000..fa9d9d35bb
--- /dev/null
+++ b/src/particles/shaders_ng/imageparticle_deformed.frag.qsb
Binary files differ
diff --git a/src/particles/shaders_ng/imageparticle_deformed.vert.qsb b/src/particles/shaders_ng/imageparticle_deformed.vert.qsb
new file mode 100644
index 0000000000..65092d5b26
--- /dev/null
+++ b/src/particles/shaders_ng/imageparticle_deformed.vert.qsb
Binary files differ
diff --git a/src/particles/shaders_ng/imageparticle_simple.frag.qsb b/src/particles/shaders_ng/imageparticle_simple.frag.qsb
new file mode 100644
index 0000000000..a5874cba24
--- /dev/null
+++ b/src/particles/shaders_ng/imageparticle_simple.frag.qsb
Binary files differ
diff --git a/src/particles/shaders_ng/imageparticle_simple.vert.qsb b/src/particles/shaders_ng/imageparticle_simple.vert.qsb
new file mode 100644
index 0000000000..da815d7e19
--- /dev/null
+++ b/src/particles/shaders_ng/imageparticle_simple.vert.qsb
Binary files differ
diff --git a/src/particles/shaders_ng/imageparticle_sprite.frag.qsb b/src/particles/shaders_ng/imageparticle_sprite.frag.qsb
new file mode 100644
index 0000000000..778550344b
--- /dev/null
+++ b/src/particles/shaders_ng/imageparticle_sprite.frag.qsb
Binary files differ
diff --git a/src/particles/shaders_ng/imageparticle_sprite.vert.qsb b/src/particles/shaders_ng/imageparticle_sprite.vert.qsb
new file mode 100644
index 0000000000..45b21ace8a
--- /dev/null
+++ b/src/particles/shaders_ng/imageparticle_sprite.vert.qsb
Binary files differ
diff --git a/src/particles/shaders_ng/imageparticle_tabled.frag.qsb b/src/particles/shaders_ng/imageparticle_tabled.frag.qsb
new file mode 100644
index 0000000000..c5dcc2c68f
--- /dev/null
+++ b/src/particles/shaders_ng/imageparticle_tabled.frag.qsb
Binary files differ
diff --git a/src/particles/shaders_ng/imageparticle_tabled.vert.qsb b/src/particles/shaders_ng/imageparticle_tabled.vert.qsb
new file mode 100644
index 0000000000..ea42607570
--- /dev/null
+++ b/src/particles/shaders_ng/imageparticle_tabled.vert.qsb
Binary files differ
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12threadedrenderloop.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12threadedrenderloop.cpp
index 120a84566f..f505df1e5a 100644
--- a/src/plugins/scenegraph/d3d12/qsgd3d12threadedrenderloop.cpp
+++ b/src/plugins/scenegraph/d3d12/qsgd3d12threadedrenderloop.cpp
@@ -121,10 +121,6 @@ const QEvent::Type WM_Obscure = QEvent::Type(QEvent::User + 1);
// Passed from the RL to RT when GUI has been locked, waiting for sync.
const QEvent::Type WM_RequestSync = QEvent::Type(QEvent::User + 2);
-// Passed by the RT to itself to trigger another render pass. This is typically
-// a result of QQuickWindow::update().
-const QEvent::Type WM_RequestRepaint = QEvent::Type(QEvent::User + 3);
-
// Passed by the RL to the RT to maybe release resource if no windows are
// rendering.
const QEvent::Type WM_TryRelease = QEvent::Type(QEvent::User + 4);
@@ -436,14 +432,6 @@ bool QSGD3D12RenderThread::event(QEvent *e)
return true;
}
- case WM_RequestRepaint:
- if (Q_UNLIKELY(debug_loop()))
- qDebug("RT - WM_RequestPaint");
- // When GUI posts this event, it is followed by a polishAndSync, so we
- // must not exit the event loop yet.
- pendingUpdate |= RepaintRequest;
- break;
-
default:
break;
}
diff --git a/src/qml/doc/src/qmlfunctions.qdoc b/src/qml/doc/src/qmlfunctions.qdoc
index 9c106558fd..c71d18418a 100644
--- a/src/qml/doc/src/qmlfunctions.qdoc
+++ b/src/qml/doc/src/qmlfunctions.qdoc
@@ -274,6 +274,16 @@
*/
/*!
+ \fn int qmlRegisterAnonymousType(const char *uri, int versionMajor)
+
+ This template function registers the C++ type in the QML system. Instances of this type cannot be created from the QML system.
+
+ Use this function when the type will not be referenced by name. Use \a uri and \a versionMajor to indicate to which module the type belongs.
+
+ \sa {Choosing the Correct Integration Method Between C++ and QML}
+*/
+
+/*!
\fn int qmlRegisterType()
\relates QQmlEngine
\overload
diff --git a/src/qml/qml/qqml.h b/src/qml/qml/qqml.h
index bfd1c88b28..a93b012c70 100644
--- a/src/qml/qml/qqml.h
+++ b/src/qml/qml/qqml.h
@@ -102,7 +102,7 @@ class QQmlPropertyValueInterceptor;
void Q_QML_EXPORT qmlClearTypeRegistrations();
template<typename T>
-int qmlRegisterType()
+int qmlRegisterAnonymousType(const char *uri, int versionMajor=1)
{
QML_GETTYPENAMES
@@ -115,7 +115,7 @@ int qmlRegisterType()
nullptr,
QString(),
- nullptr, 0, 0, nullptr, &T::staticMetaObject,
+ uri, versionMajor, 0, nullptr, &T::staticMetaObject,
QQmlPrivate::attachedPropertiesFunc<T>(),
QQmlPrivate::attachedPropertiesMetaObject<T>(),
@@ -133,6 +133,12 @@ int qmlRegisterType()
return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
}
+template<typename T>
+QT_DEPRECATED_VERSION_X_5_14("Use qmlRegisterAnonymousType instead") int qmlRegisterType()
+{
+ return qmlRegisterAnonymousType<T>("");
+}
+
int Q_QML_EXPORT qmlRegisterTypeNotAvailable(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& message);
template<typename T>
diff --git a/src/qml/qml/qqmlapplicationengine.cpp b/src/qml/qml/qqmlapplicationengine.cpp
index e93cfcadb9..d04a89b514 100644
--- a/src/qml/qml/qqmlapplicationengine.cpp
+++ b/src/qml/qml/qqmlapplicationengine.cpp
@@ -131,7 +131,7 @@ void QQmlApplicationEnginePrivate::finishLoad(QQmlComponent *c)
q->objectCreated(nullptr, c->url());
break;
case QQmlComponent::Ready: {
- auto newObj = c->create();
+ auto newObj = initialProperties.empty() ? c->create() : c->createWithInitialProperties(initialProperties);
objects << newObj;
QObject::connect(newObj, &QObject::destroyed, q, [&](QObject *obj) { objects.removeAll(obj); });
q->objectCreated(objects.constLast(), c->url());
@@ -279,6 +279,22 @@ void QQmlApplicationEngine::load(const QString &filePath)
}
/*!
+ Sets the initial properties with which the QML component gets initialized after
+ it gets loaded.
+
+
+ \sa QQmlComponent::setInitialProperties
+ \sa QQmlApplicationEngine::load
+ \sa QQmlApplicationEngine::loadData
+ \since 5.14
+*/
+void QQmlApplicationEngine::setInitialProperties(const QVariantMap &initialProperties)
+{
+ Q_D(QQmlApplicationEngine);
+ d->initialProperties = initialProperties;
+}
+
+/*!
Loads the QML given in \a data. The object tree defined by \a data is
instantiated immediately.
diff --git a/src/qml/qml/qqmlapplicationengine.h b/src/qml/qml/qqmlapplicationengine.h
index bb5d6b5d68..2b4de91154 100644
--- a/src/qml/qml/qqmlapplicationengine.h
+++ b/src/qml/qml/qqmlapplicationengine.h
@@ -66,6 +66,7 @@ public:
public Q_SLOTS:
void load(const QUrl &url);
void load(const QString &filePath);
+ void setInitialProperties(const QVariantMap &initialProperties);
void loadData(const QByteArray &data, const QUrl &url = QUrl());
Q_SIGNALS:
diff --git a/src/qml/qml/qqmlapplicationengine_p.h b/src/qml/qml/qqmlapplicationengine_p.h
index 7a341847bd..1279e400e8 100644
--- a/src/qml/qml/qqmlapplicationengine_p.h
+++ b/src/qml/qml/qqmlapplicationengine_p.h
@@ -73,6 +73,7 @@ public:
void loadTranslations(const QUrl &rootFile);
void finishLoad(QQmlComponent *component);
QList<QObject *> objects;
+ QVariantMap initialProperties;
};
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp
index fefe2bc685..ed8c41a582 100644
--- a/src/qml/qml/qqmlcomponent.cpp
+++ b/src/qml/qml/qqmlcomponent.cpp
@@ -350,6 +350,32 @@ void QQmlComponentPrivate::clear()
compilationUnit = nullptr;
}
+QObject *QQmlComponentPrivate::doBeginCreate(QQmlComponent *q, QQmlContext *context)
+{
+ if (!engine) {
+ // ###Qt6: In Qt 6, it should be impossible for users to create a QQmlComponent without an engine, and we can remove this check
+ qWarning("QQmlComponent: Must provide an engine before calling create");
+ return nullptr;
+ }
+ if (!context)
+ context = engine->rootContext();
+ return q->beginCreate(context);
+}
+
+bool QQmlComponentPrivate::setInitialProperty(QObject *component, const QString& name, const QVariant &value)
+{
+ QQmlProperty prop(component, name);
+ auto privProp = QQmlPropertyPrivate::get(prop);
+ if (!prop.isValid() || !privProp->writeValueProperty(value, nullptr)) {
+ QQmlError error{};
+ error.setUrl(url);
+ error.setDescription(QLatin1String("Could not set property %1").arg(name));
+ state.errors.push_back(error);
+ return false;
+ } else
+ return true;
+}
+
/*!
\internal
*/
@@ -780,18 +806,28 @@ QObject *QQmlComponent::create(QQmlContext *context)
{
Q_D(QQmlComponent);
- if (!d->engine) {
- // ###Qt6: In Qt 6, it should be impossible for users to create a QQmlComponent without an engine, and we can remove this check
- qWarning("QQmlComponent: Must provide an engine before calling create");
- return nullptr;
- }
+ QObject *rv = d->doBeginCreate(this, context);
+ if (rv)
+ completeCreate();
+ return rv;
+}
- if (!context)
- context = d->engine->rootContext();
+/*!
+ Create an object instance of this component, and initialize its toplevel properties according to initalPropertyValues.
- QObject *rv = beginCreate(context);
- if (rv)
+
+ \sa QQmlComponent::create
+ \since 5.14
+*/
+QObject *QQmlComponent::createWithInitialProperties(const QVariantMap& initialProperties, QQmlContext *context)
+{
+ Q_D(QQmlComponent);
+
+ QObject *rv = d->doBeginCreate(this, context);
+ if (rv) {
+ setInitialProperties(rv, initialProperties);
completeCreate();
+ }
return rv;
}
@@ -1067,6 +1103,26 @@ void QQmlComponent::create(QQmlIncubator &incubator, QQmlContext *context,
enginePriv->incubate(incubator, forContextData);
}
+/*!
+ Set toplevel properties of the component.
+
+
+ This method provides advanced control over component instance creation.
+ In general, programmers should use
+ \l QQmlComponent::createWithInitialProperties to create a component.
+
+ Use this method after beginCreate and before completeCreate has been called.
+ If a provided property does not exist, a warning is issued.
+
+ \since 5.14
+*/
+void QQmlComponent::setInitialProperties(QObject *component, const QVariantMap &properties)
+{
+ Q_D(QQmlComponent);
+ for (auto it = properties.constBegin(); it != properties.constEnd(); ++it)
+ d->setInitialProperty(component, it.key(), it.value());
+}
+
/*
This is essentially a copy of QQmlComponent::create(); except it takes the QQmlContextData
arguments instead of QQmlContext which means we don't have to construct the rather weighty
diff --git a/src/qml/qml/qqmlcomponent.h b/src/qml/qml/qqmlcomponent.h
index 39b6d4526f..f259c99b08 100644
--- a/src/qml/qml/qqmlcomponent.h
+++ b/src/qml/qml/qqmlcomponent.h
@@ -100,6 +100,8 @@ public:
QUrl url() const;
virtual QObject *create(QQmlContext *context = nullptr);
+ QObject *createWithInitialProperties(const QVariantMap& initialProperties, QQmlContext *context = nullptr);
+ void setInitialProperties(QObject *component, const QVariantMap &properties);
virtual QObject *beginCreate(QQmlContext *);
virtual void completeCreate();
diff --git a/src/qml/qml/qqmlcomponent_p.h b/src/qml/qml/qqmlcomponent_p.h
index 9a967501c9..2170646b89 100644
--- a/src/qml/qml/qqmlcomponent_p.h
+++ b/src/qml/qml/qqmlcomponent_p.h
@@ -143,6 +143,9 @@ public:
static QQmlComponentPrivate *get(QQmlComponent *c) {
return static_cast<QQmlComponentPrivate *>(QObjectPrivate::get(c));
}
+
+ QObject *doBeginCreate(QQmlComponent *q, QQmlContext *context);
+ bool setInitialProperty(QObject *component, const QString &name, const QVariant& value);
};
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp
index 9c3c9de81e..0fd07ea209 100644
--- a/src/qml/qml/qqmlengine.cpp
+++ b/src/qml/qml/qqmlengine.cpp
@@ -210,14 +210,14 @@ void QQmlEnginePrivate::defineModule()
// TODO: We won't need Connections to be a custom type anymore once we can drop the
// automatic signal handler inference from undeclared properties.
qmlRegisterCustomType<QQmlConnections>(uri, 2, 0, "Connections", new QQmlConnectionsParser);
- qmlRegisterCustomType<QQmlConnections, 1>(uri, 2, 3, "Connections", new QQmlConnectionsParser); // Only available in QtQml >= 2.3
+ qmlRegisterCustomType<QQmlConnections, 3>(uri, 2, 3, "Connections", new QQmlConnectionsParser); // Only available in QtQml >= 2.3
#if QT_CONFIG(qml_animation)
qmlRegisterType<QQmlTimer>(uri, 2, 0, "Timer");
#endif
qmlRegisterType<QQmlLoggingCategory>(uri, 2, 8, "LoggingCategory"); // Only available in >= 2.8
- qmlRegisterType<QQmlLoggingCategory, 1>(uri, 2, 12, "LoggingCategory"); // Only available in >= 2.12
+ qmlRegisterType<QQmlLoggingCategory, 12>(uri, 2, 12, "LoggingCategory"); // Only available in >= 2.12
#if QT_CONFIG(qml_locale)
qmlRegisterUncreatableType<QQmlLocale>(uri, 2, 2, "Locale", QQmlEngine::tr("Locale cannot be instantiated. Use Qt.locale()"));
@@ -236,12 +236,12 @@ void QQmlEnginePrivate::registerQuickTypes()
qmlRegisterType<QQmlBind>(uri, 2, 0, "Binding");
qmlRegisterType<QQmlBind, 8>(uri, 2, 8, "Binding");
qmlRegisterCustomType<QQmlConnections>(uri, 2, 0, "Connections", new QQmlConnectionsParser);
- qmlRegisterCustomType<QQmlConnections, 1>(uri, 2, 7, "Connections", new QQmlConnectionsParser);
+ qmlRegisterCustomType<QQmlConnections, 3>(uri, 2, 7, "Connections", new QQmlConnectionsParser);
#if QT_CONFIG(qml_animation)
qmlRegisterType<QQmlTimer>(uri, 2, 0,"Timer");
#endif
qmlRegisterType<QQmlLoggingCategory>(uri, 2, 8, "LoggingCategory");
- qmlRegisterType<QQmlLoggingCategory, 1>(uri, 2, 12, "LoggingCategory");
+ qmlRegisterType<QQmlLoggingCategory, 12>(uri, 2, 12, "LoggingCategory");
#if QT_CONFIG(qml_locale)
qmlRegisterUncreatableType<QQmlLocale>(uri, 2, 0, "Locale", QQmlEngine::tr("Locale cannot be instantiated. Use Qt.locale()"));
#endif
diff --git a/src/qml/qml/qqmlloggingcategory_p.h b/src/qml/qml/qqmlloggingcategory_p.h
index ece06e04b4..ee5d9af2e7 100644
--- a/src/qml/qml/qqmlloggingcategory_p.h
+++ b/src/qml/qml/qqmlloggingcategory_p.h
@@ -65,7 +65,7 @@ class QQmlLoggingCategory : public QObject, public QQmlParserStatus
Q_INTERFACES(QQmlParserStatus)
Q_PROPERTY(QString name READ name WRITE setName)
- Q_PROPERTY(DefaultLogLevel defaultLogLevel READ defaultLogLevel WRITE setDefaultLogLevel REVISION 1)
+ Q_PROPERTY(DefaultLogLevel defaultLogLevel READ defaultLogLevel WRITE setDefaultLogLevel REVISION 12)
public:
enum DefaultLogLevel {
diff --git a/src/qml/types/qqmlconnections.cpp b/src/qml/types/qqmlconnections.cpp
index f9188b1bb5..1e801641e5 100644
--- a/src/qml/types/qqmlconnections.cpp
+++ b/src/qml/types/qqmlconnections.cpp
@@ -274,8 +274,10 @@ void QQmlConnections::connectSignals()
if (d->bindings.isEmpty()) {
connectSignalsToMethods();
} else {
+#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
qmlWarning(this) << tr("Implicitly defined onFoo properties in Connections are deprecated. "
"Use this syntax instead: function onFoo(<arguments>) { ... }");
+#endif
connectSignalsToBindings();
}
}
diff --git a/src/qml/types/qqmlconnections_p.h b/src/qml/types/qqmlconnections_p.h
index 1acc86239f..5d28e8e8be 100644
--- a/src/qml/types/qqmlconnections_p.h
+++ b/src/qml/types/qqmlconnections_p.h
@@ -69,7 +69,7 @@ class Q_AUTOTEST_EXPORT QQmlConnections : public QObject, public QQmlParserStatu
Q_INTERFACES(QQmlParserStatus)
Q_PROPERTY(QObject *target READ target WRITE setTarget NOTIFY targetChanged)
- Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged REVISION 1)
+ Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged REVISION 3)
Q_PROPERTY(bool ignoreUnknownSignals READ ignoreUnknownSignals WRITE setIgnoreUnknownSignals)
public:
@@ -87,7 +87,7 @@ public:
Q_SIGNALS:
void targetChanged();
- Q_REVISION(1) void enabledChanged();
+ Q_REVISION(3) void enabledChanged();
private:
void connectSignals();
diff --git a/src/qmlmodels/configure.json b/src/qmlmodels/configure.json
index 84eefed261..1ccca5e35e 100644
--- a/src/qmlmodels/configure.json
+++ b/src/qmlmodels/configure.json
@@ -30,7 +30,7 @@
"label": "QML table model",
"purpose": "Provides the TableModel QML type.",
"section": "QML",
- "condition": "features.qml-itemmodel",
+ "condition": "features.qml-itemmodel && features.qml-delegate-model",
"output": [ "privateFeature" ]
}
},
diff --git a/src/qmlmodels/qqmlmodelsmodule.cpp b/src/qmlmodels/qqmlmodelsmodule.cpp
index 2db5dd834f..d569d8e23c 100644
--- a/src/qmlmodels/qqmlmodelsmodule.cpp
+++ b/src/qmlmodels/qqmlmodelsmodule.cpp
@@ -69,7 +69,7 @@ void QQmlModelsModule::registerQmlTypes()
// Don't add anything here. These are only for backwards compatibility.
#if QT_CONFIG(qml_object_model)
qmlRegisterType<QQmlInstantiator>("QtQml", 2, 1, "Instantiator"); // Only available in >= 2.1
- qmlRegisterType<QQmlInstanceModel>();
+ qmlRegisterAnonymousType<QQmlInstanceModel>("QtQml", 2);
#endif
}
@@ -81,7 +81,7 @@ void QQmlModelsModule::registerQuickTypes()
#if QT_CONFIG(qml_object_model)
qmlRegisterType<QQmlInstantiator>(uri, 2, 1, "Instantiator");
- qmlRegisterType<QQmlInstanceModel>();
+ qmlRegisterAnonymousType<QQmlInstanceModel>(uri, 2);
qmlRegisterType<QQmlObjectModel>(uri, 2, 0, "VisualItemModel");
#endif
#if QT_CONFIG(qml_list_model)
@@ -114,7 +114,7 @@ void QQmlModelsModule::defineModule()
qmlRegisterType<QQmlObjectModel>(uri, 2, 1, "ObjectModel");
qmlRegisterType<QQmlObjectModel,3>(uri, 2, 3, "ObjectModel");
qmlRegisterType<QQmlInstantiator>(uri, 2, 14, "Instantiator");
- qmlRegisterType<QQmlInstanceModel>();
+ qmlRegisterAnonymousType<QQmlInstanceModel>(uri, 2);
#endif
#if QT_CONFIG(itemmodel)
qmlRegisterType<QItemSelectionModel>(uri, 2, 2, "ItemSelectionModel");
diff --git a/src/qmltest/quicktestevent.cpp b/src/qmltest/quicktestevent.cpp
index 5b07220c29..1e949615c2 100644
--- a/src/qmltest/quicktestevent.cpp
+++ b/src/qmltest/quicktestevent.cpp
@@ -241,7 +241,8 @@ namespace QtQuickTest
QTEST_ASSERT(stateKey == 0 || stateKey & Qt::KeyboardModifierMask);
stateKey &= static_cast<unsigned int>(Qt::KeyboardModifierMask);
- QWheelEvent we(pos, window->mapToGlobal(pos), QPoint(0, 0), QPoint(xDelta, yDelta), 0, Qt::Vertical, buttons, stateKey);
+ QWheelEvent we(pos, window->mapToGlobal(pos), QPoint(0, 0), QPoint(xDelta, yDelta), buttons,
+ stateKey, Qt::NoScrollPhase, false);
QSpontaneKeyEvent::setSpontaneous(&we); // hmmmm
if (!qApp->notify(window, &we))
diff --git a/src/quick/doc/images/declarative-qtlogo.png b/src/quick/doc/images/declarative-qtlogo.png
index 940d159ae4..b63f1384b1 100644
--- a/src/quick/doc/images/declarative-qtlogo.png
+++ b/src/quick/doc/images/declarative-qtlogo.png
Binary files differ
diff --git a/src/quick/doc/snippets/qml/transitions-list.qml b/src/quick/doc/snippets/qml/transitions-list.qml
index 06b9e39cc8..972d3ee14e 100644
--- a/src/quick/doc/snippets/qml/transitions-list.qml
+++ b/src/quick/doc/snippets/qml/transitions-list.qml
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the documentation of the Qt Toolkit.
@@ -48,52 +48,105 @@
**
****************************************************************************/
-import QtQuick 2.0
+import QtQuick 2.13
Rectangle {
- width: 150; height: 250
+ id: page
+ width: 640
+ height: 500
- Rectangle {
- id: stopLight
- x: 25; y: 15; width: 100; height: 100
- }
- Rectangle {
- id: goLight
- x: 25; y: 135; width: 100; height: 100
- }
+ Image {
+ id: userIcon
+ x: topLeftRect.x
+ y: topLeftRect.y
- states: [
- State {
- name: "stop"
- PropertyChanges { target: stopLight; color: "red" }
- PropertyChanges { target: goLight; color: "black" }
- },
- State {
- name: "go"
- PropertyChanges { target: stopLight; color: "black" }
- PropertyChanges { target: goLight; color: "green" }
+ source: "../../images/declarative-qtlogo.png"
}
- ]
- state: "stop"
+ Rectangle {
+ id: topLeftRect
+ anchors { left: parent.left; top: parent.top; leftMargin: 10; topMargin: 20 }
+ width: 46; height: 54
+ color: "Transparent"; border.color: "Gray"; radius: 6
+ // Clicking here sets state to default state, returning image to initial position
+ TapHandler { onTapped: page.state = 'start' }
+ }
+
+ Rectangle {
+ id: middleRightRect
+ anchors { right: parent.right; verticalCenter: parent.verticalCenter; rightMargin: 20 }
+ width: 46; height: 54
+ color: "Transparent"; border.color: "Gray"; radius: 6
+ // Clicking in here sets the state to 'middleRight'
+ TapHandler { onTapped: page.state = 'middleRight' }
+ }
- MouseArea {
- anchors.fill: parent
- onClicked: parent.state == "stop" ?
- parent.state = "go" : parent.state = "stop"
- }
+ Rectangle {
+ id: bottomLeftRect
+ anchors { left: parent.left; bottom: parent.bottom; leftMargin: 10; bottomMargin: 20 }
+ width: 46; height: 54
+ color: "Transparent"; border.color: "Gray"; radius: 6
+ // Clicking in here sets the state to 'bottomLeft'
+ TapHandler { onTapped: page.state = 'bottomLeft' }
+ }
- //! [list of transitions]
- transitions: [
- Transition {
- from: "stop"; to: "go"
- PropertyAnimation { target: stopLight
- properties: "color"; duration: 1000 }
- },
- Transition {
- from: "go"; to: "stop"
- PropertyAnimation { target: goLight
- properties: "color"; duration: 1000 }
- } ]
- //! [list of transitions]
+ states: [
+ State {
+ name: "start"
+ PropertyChanges {
+ target: userIcon
+ explicit: true
+ x: topLeftRect.x
+ y: topLeftRect.y
+ }
+ },
+ State {
+ name: "middleRight"
+ PropertyChanges {
+ target: userIcon
+ explicit: true
+ x: middleRightRect.x
+ y: middleRightRect.y
+ }
+ },
+ State {
+ name: "bottomLeft"
+ PropertyChanges {
+ target: userIcon
+ explicit: true
+ x: bottomLeftRect.x
+ y: bottomLeftRect.y
+ }
+ }
+ ]
+//! [list of transitions]
+ transitions: [
+ Transition {
+ from: "*"; to: "middleRight"
+ NumberAnimation {
+ properties: "x,y";
+ easing.type: Easing.InOutQuad;
+ duration: 2000;
+ }
+ },
+ Transition {
+ from: "*"; to: "bottomLeft";
+ NumberAnimation {
+ properties: "x,y";
+ easing.type: Easing.InOutQuad;
+ duration: 200;
+ }
+ },
+ //If any other rectangle is clicked, the icon will return
+ //to the start position at a slow speed and bounce.
+ Transition {
+ from: "*"; to: "*";
+ NumberAnimation {
+ easing.type: Easing.OutBounce;
+ properties: "x,y";
+ duration: 4000;
+ }
+ }
+ ]
+//! [list of transitions]
}
diff --git a/src/quick/doc/src/concepts/positioning/righttoleft.qdoc b/src/quick/doc/src/concepts/positioning/righttoleft.qdoc
index 7c8cd735b3..1f3602cde1 100644
--- a/src/quick/doc/src/concepts/positioning/righttoleft.qdoc
+++ b/src/quick/doc/src/concepts/positioning/righttoleft.qdoc
@@ -148,7 +148,7 @@ To define the layout direction for a particular locale, declare the dedicated st
You can do this by first introducing this line
\code
-QT_TRANSLATE_NOOP("QGuiApplication", "QT_LAYOUT_DIRECTION");
+qsTr("QT_LAYOUT_DIRECTION","QGuiApplication");
\endcode
somewhere in your QML source code and calling \c lupdate to generate the translation source file.
diff --git a/src/quick/items/qquickanimatedimage.cpp b/src/quick/items/qquickanimatedimage.cpp
index fe445425e7..bebefc1b22 100644
--- a/src/quick/items/qquickanimatedimage.cpp
+++ b/src/quick/items/qquickanimatedimage.cpp
@@ -67,7 +67,7 @@ QQuickPixmap* QQuickAnimatedImagePrivate::infoForCurrentFrame(QQmlEngine *engine
.arg(current));
}
if (!requestedUrl.isEmpty()) {
- if (QQuickPixmap::isCached(requestedUrl, QSize(), QQuickImageProviderOptions()))
+ if (QQuickPixmap::isCached(requestedUrl, QSize(), 0, QQuickImageProviderOptions()))
pixmap = new QQuickPixmap(engine, requestedUrl);
else
pixmap = new QQuickPixmap(requestedUrl, movie->currentImage());
@@ -139,6 +139,8 @@ QQuickAnimatedImage::QQuickAnimatedImage(QQuickItem *parent)
: QQuickImage(*(new QQuickAnimatedImagePrivate), parent)
{
connect(this, &QQuickImageBase::cacheChanged, this, &QQuickAnimatedImage::onCacheChanged);
+ connect(this, &QQuickImageBase::currentFrameChanged, this, &QQuickAnimatedImage::frameChanged);
+ connect(this, &QQuickImageBase::frameCountChanged, this, &QQuickAnimatedImage::frameCountChanged);
}
QQuickAnimatedImage::~QQuickAnimatedImage()
@@ -464,7 +466,7 @@ void QQuickAnimatedImage::movieUpdate()
if (d->movie) {
d->setPixmap(*d->infoForCurrentFrame(qmlEngine(this)));
- emit frameChanged();
+ emit currentFrameChanged();
}
}
diff --git a/src/quick/items/qquickanimatedimage_p.h b/src/quick/items/qquickanimatedimage_p.h
index 6b5db215bd..ef5af6b387 100644
--- a/src/quick/items/qquickanimatedimage_p.h
+++ b/src/quick/items/qquickanimatedimage_p.h
@@ -85,10 +85,10 @@ public:
bool isPaused() const;
void setPaused(bool pause);
- int currentFrame() const;
- void setCurrentFrame(int frame);
+ int currentFrame() const override;
+ void setCurrentFrame(int frame) override;
- int frameCount() const;
+ int frameCount() const override;
qreal speed() const;
void setSpeed(qreal speed);
diff --git a/src/quick/items/qquickborderimage.cpp b/src/quick/items/qquickborderimage.cpp
index c53a39ca09..430fa1b094 100644
--- a/src/quick/items/qquickborderimage.cpp
+++ b/src/quick/items/qquickborderimage.cpp
@@ -343,7 +343,7 @@ void QQuickBorderImage::load()
QUrl loadUrl = d->url;
resolve2xLocalFile(d->url, targetDevicePixelRatio, &loadUrl, &d->devicePixelRatio);
- d->pix.load(qmlEngine(this), loadUrl, d->sourcesize * d->devicePixelRatio, options);
+ d->pix.load(qmlEngine(this), loadUrl, d->sourcesize * d->devicePixelRatio, options, QQuickImageProviderOptions(), d->currentFrame, d->frameCount);
if (d->pix.isLoading()) {
if (d->progress != 0.0) {
@@ -534,6 +534,10 @@ void QQuickBorderImage::requestFinished()
d->oldSourceSize = sourceSize();
emit sourceSizeChanged();
}
+ if (d->frameCount != d->pix.frameCount()) {
+ d->frameCount = d->pix.frameCount();
+ emit frameCountChanged();
+ }
pixmapChange();
}
@@ -693,6 +697,18 @@ void QQuickBorderImage::pixmapChange()
update();
}
+/*!
+ \qmlproperty int QtQuick::BorderImage::currentFrame
+ \qmlproperty int QtQuick::BorderImage::frameCount
+ \since 5.14
+
+ currentFrame is the frame that is currently visible. The default is \c 0.
+ You can set it to a number between \c 0 and \c {frameCount - 1} to display a
+ different frame, if the image contains multiple frames.
+
+ frameCount is the number of frames in the image. Most images have only one frame.
+*/
+
QT_END_NAMESPACE
#include "moc_qquickborderimage_p.cpp"
diff --git a/src/quick/items/qquickevents.cpp b/src/quick/items/qquickevents.cpp
index 8303c3fed1..161ef17e1f 100644
--- a/src/quick/items/qquickevents.cpp
+++ b/src/quick/items/qquickevents.cpp
@@ -1448,7 +1448,7 @@ QQuickPointerEvent *QQuickPointerScrollEvent::reset(QEvent *event)
m_synthSource = ev->source();
m_inverted = ev->inverted();
- m_point->reset(Qt::TouchPointMoved, ev->posF(), quint64(1) << 24, ev->timestamp()); // mouse has device ID 1
+ m_point->reset(Qt::TouchPointMoved, ev->position(), quint64(1) << 24, ev->timestamp()); // mouse has device ID 1
}
#endif
// TODO else if (event->type() == QEvent::Scroll) ...
diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp
index 7e1f54f07e..cf3cd9f48e 100644
--- a/src/quick/items/qquickflickable.cpp
+++ b/src/quick/items/qquickflickable.cpp
@@ -1489,7 +1489,7 @@ void QQuickFlickable::wheelEvent(QWheelEvent *event)
d->vData.velocity = 0;
d->hData.velocity = 0;
d->timer.start();
- d->maybeBeginDrag(currentTimestamp, event->posF());
+ d->maybeBeginDrag(currentTimestamp, event->position());
break;
case Qt::NoScrollPhase: // default phase with an ordinary wheel mouse
case Qt::ScrollUpdate:
@@ -1571,7 +1571,8 @@ void QQuickFlickable::wheelEvent(QWheelEvent *event)
QVector2D velocity(xDelta / elapsed, yDelta / elapsed);
d->lastPosTime = currentTimestamp;
d->accumulatedWheelPixelDelta += QVector2D(event->pixelDelta());
- d->drag(currentTimestamp, event->type(), event->posF(), d->accumulatedWheelPixelDelta, true, !d->scrollingPhase, true, velocity);
+ d->drag(currentTimestamp, event->type(), event->position(), d->accumulatedWheelPixelDelta,
+ true, !d->scrollingPhase, true, velocity);
event->accept();
}
diff --git a/src/quick/items/qquickimage.cpp b/src/quick/items/qquickimage.cpp
index dfbe271606..87b848b21b 100644
--- a/src/quick/items/qquickimage.cpp
+++ b/src/quick/items/qquickimage.cpp
@@ -889,4 +889,16 @@ void QQuickImage::setMipmap(bool use)
By default, this property is set to false.
*/
+/*!
+ \qmlproperty int QtQuick::Image::currentFrame
+ \qmlproperty int QtQuick::Image::frameCount
+ \since 5.14
+
+ currentFrame is the frame that is currently visible. The default is \c 0.
+ You can set it to a number between \c 0 and \c {frameCount - 1} to display a
+ different frame, if the image contains multiple frames.
+
+ frameCount is the number of frames in the image. Most images have only one frame.
+*/
+
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickimage_p.h b/src/quick/items/qquickimage_p.h
index 7fb4413900..257cde5313 100644
--- a/src/quick/items/qquickimage_p.h
+++ b/src/quick/items/qquickimage_p.h
@@ -66,8 +66,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickImage : public QQuickImageBase
Q_PROPERTY(qreal paintedHeight READ paintedHeight NOTIFY paintedGeometryChanged)
Q_PROPERTY(HAlignment horizontalAlignment READ horizontalAlignment WRITE setHorizontalAlignment NOTIFY horizontalAlignmentChanged)
Q_PROPERTY(VAlignment verticalAlignment READ verticalAlignment WRITE setVerticalAlignment NOTIFY verticalAlignmentChanged)
- Q_PROPERTY(bool mipmap READ mipmap WRITE setMipmap NOTIFY mipmapChanged REVISION 1)
- Q_PROPERTY(bool autoTransform READ autoTransform WRITE setAutoTransform NOTIFY autoTransformChanged REVISION 2)
+ Q_PROPERTY(bool mipmap READ mipmap WRITE setMipmap NOTIFY mipmapChanged REVISION 3)
+ Q_PROPERTY(bool autoTransform READ autoTransform WRITE setAutoTransform NOTIFY autoTransformChanged REVISION 5)
public:
QQuickImage(QQuickItem *parent=nullptr);
@@ -112,8 +112,8 @@ Q_SIGNALS:
void paintedGeometryChanged();
void horizontalAlignmentChanged(HAlignment alignment);
void verticalAlignmentChanged(VAlignment alignment);
- Q_REVISION(1) void mipmapChanged(bool);
- Q_REVISION(2) void autoTransformChanged();
+ Q_REVISION(3) void mipmapChanged(bool);
+ Q_REVISION(5) void autoTransformChanged();
private Q_SLOTS:
void invalidateSceneGraph();
diff --git a/src/quick/items/qquickimagebase.cpp b/src/quick/items/qquickimagebase.cpp
index 729d326625..8bab14bfd1 100644
--- a/src/quick/items/qquickimagebase.cpp
+++ b/src/quick/items/qquickimagebase.cpp
@@ -55,7 +55,7 @@ QT_BEGIN_NAMESPACE
// if they're not happy with our implementation of it.
bool QQuickImageBasePrivate::updateDevicePixelRatio(qreal targetDevicePixelRatio)
{
- // QQuickImageProvider and SVG can generate a high resolution image when
+ // QQuickImageProvider and SVG and PDF can generate a high resolution image when
// sourceSize is set (this function is only called if it's set).
// If sourceSize is not set then the provider default size will be used, as usual.
bool setDevicePixelRatio = false;
@@ -64,7 +64,8 @@ bool QQuickImageBasePrivate::updateDevicePixelRatio(qreal targetDevicePixelRatio
} else {
QString stringUrl = url.path(QUrl::PrettyDecoded);
if (stringUrl.endsWith(QLatin1String("svg")) ||
- stringUrl.endsWith(QLatin1String("svgz"))) {
+ stringUrl.endsWith(QLatin1String("svgz")) ||
+ stringUrl.endsWith(QLatin1String("pdf"))) {
setDevicePixelRatio = true;
}
}
@@ -210,6 +211,36 @@ bool QQuickImageBase::mirror() const
return d->mirror;
}
+void QQuickImageBase::setCurrentFrame(int frame)
+{
+ Q_D(QQuickImageBase);
+ if (frame == d->currentFrame || frame < 0 || (isComponentComplete() && frame >= d->pix.frameCount()))
+ return;
+
+ d->currentFrame = frame;
+
+ if (isComponentComplete()) {
+ if (frame > 0)
+ d->cache = false;
+ load();
+ update();
+ }
+
+ emit currentFrameChanged();
+}
+
+int QQuickImageBase::currentFrame() const
+{
+ Q_D(const QQuickImageBase);
+ return d->currentFrame;
+}
+
+int QQuickImageBase::frameCount() const
+{
+ Q_D(const QQuickImageBase);
+ return d->frameCount;
+}
+
void QQuickImageBase::load()
{
Q_D(QQuickImageBase);
@@ -260,7 +291,7 @@ void QQuickImageBase::load()
resolve2xLocalFile(d->url, targetDevicePixelRatio, &loadUrl, &d->devicePixelRatio);
}
- d->pix.load(qmlEngine(this), loadUrl, d->sourcesize * d->devicePixelRatio, options, d->providerOptions);
+ d->pix.load(qmlEngine(this), loadUrl, d->sourcesize * d->devicePixelRatio, options, d->providerOptions, d->currentFrame, d->frameCount);
if (d->pix.isLoading()) {
if (d->progress != 0.0) {
@@ -319,6 +350,11 @@ void QQuickImageBase::requestFinished()
d->oldAutoTransform = autoTransform();
emitAutoTransformBaseChanged();
}
+ if (d->frameCount != d->pix.frameCount()) {
+ d->frameCount = d->pix.frameCount();
+ emit frameCountChanged();
+ }
+
update();
}
diff --git a/src/quick/items/qquickimagebase_p.h b/src/quick/items/qquickimagebase_p.h
index d8d0be9b8c..8cd59c8cea 100644
--- a/src/quick/items/qquickimagebase_p.h
+++ b/src/quick/items/qquickimagebase_p.h
@@ -68,6 +68,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickImageBase : public QQuickImplicitSizeItem
Q_PROPERTY(bool cache READ cache WRITE setCache NOTIFY cacheChanged)
Q_PROPERTY(QSize sourceSize READ sourceSize WRITE setSourceSize RESET resetSourceSize NOTIFY sourceSizeChanged)
Q_PROPERTY(bool mirror READ mirror WRITE setMirror NOTIFY mirrorChanged)
+ Q_PROPERTY(int currentFrame READ currentFrame WRITE setCurrentFrame NOTIFY currentFrameChanged REVISION 14)
+ Q_PROPERTY(int frameCount READ frameCount NOTIFY frameCountChanged REVISION 14)
public:
QQuickImageBase(QQuickItem *parent=nullptr);
@@ -95,6 +97,11 @@ public:
virtual void setMirror(bool mirror);
bool mirror() const;
+ virtual void setCurrentFrame(int frame);
+ virtual int currentFrame() const;
+
+ virtual int frameCount() const;
+
virtual void setAutoTransform(bool transform);
bool autoTransform() const;
@@ -112,6 +119,8 @@ Q_SIGNALS:
void asynchronousChanged();
void cacheChanged();
void mirrorChanged();
+ Q_REVISION(14) void currentFrameChanged();
+ Q_REVISION(14) void frameCountChanged();
protected:
virtual void load();
diff --git a/src/quick/items/qquickimagebase_p_p.h b/src/quick/items/qquickimagebase_p_p.h
index 1b771166a2..88e18ba32e 100644
--- a/src/quick/items/qquickimagebase_p_p.h
+++ b/src/quick/items/qquickimagebase_p_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQuick module of the Qt Toolkit.
@@ -68,6 +68,8 @@ public:
: status(QQuickImageBase::Null),
progress(0.0),
devicePixelRatio(1.0),
+ currentFrame(0),
+ frameCount(0),
async(false),
cache(true),
mirror(false),
@@ -85,6 +87,8 @@ public:
QSize oldSourceSize;
qreal devicePixelRatio;
QQuickImageProviderOptions providerOptions;
+ int currentFrame;
+ int frameCount;
bool async : 1;
bool cache : 1;
bool mirror: 1;
diff --git a/src/quick/items/qquickitem.h b/src/quick/items/qquickitem.h
index ad9bab2a90..394a5adb8c 100644
--- a/src/quick/items/qquickitem.h
+++ b/src/quick/items/qquickitem.h
@@ -318,7 +318,7 @@ public:
void setKeepTouchGrab(bool);
// implemented in qquickitemgrabresult.cpp
- Q_REVISION(2) Q_INVOKABLE bool grabToImage(const QJSValue &callback, const QSize &targetSize = QSize());
+ Q_REVISION(4) Q_INVOKABLE bool grabToImage(const QJSValue &callback, const QSize &targetSize = QSize());
QSharedPointer<QQuickItemGrabResult> grabToImage(const QSize &targetSize = QSize());
Q_INVOKABLE virtual bool contains(const QPointF &point) const;
diff --git a/src/quick/items/qquickitemsmodule.cpp b/src/quick/items/qquickitemsmodule.cpp
index 33c4fae96d..70a8b08822 100644
--- a/src/quick/items/qquickitemsmodule.cpp
+++ b/src/quick/items/qquickitemsmodule.cpp
@@ -246,28 +246,28 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
qmlRegisterType<QQuickTextEdit,1>(uri,2,1,"TextEdit");
qmlRegisterType<QQuickTextInput>(uri,major,minor,"TextInput");
qmlRegisterType<QQuickTextInput,2>(uri,2,2,"TextInput");
- qmlRegisterType<QQuickTextInput,3>(uri,2,4,"TextInput");
- qmlRegisterType<QQuickItemGrabResult>();
+ qmlRegisterType<QQuickTextInput,4>(uri,2,4,"TextInput");
+ qmlRegisterAnonymousType<QQuickItemGrabResult>(uri, major);
#if QT_CONFIG(quick_shadereffect)
- qmlRegisterType<QQuickItemLayer>();
-#endif
- qmlRegisterType<QQuickAnchors>();
- qmlRegisterType<QQuickKeyEvent>();
- qmlRegisterType<QQuickMouseEvent>();
- qmlRegisterType<QQuickWheelEvent>();
- qmlRegisterType<QQuickCloseEvent>();
- qmlRegisterType<QQuickTransform>();
+ qmlRegisterAnonymousType<QQuickItemLayer>(uri, major);
+#endif
+ qmlRegisterAnonymousType<QQuickAnchors>(uri, major);
+ qmlRegisterAnonymousType<QQuickKeyEvent>(uri, major);
+ qmlRegisterAnonymousType<QQuickMouseEvent>(uri, major);
+ qmlRegisterAnonymousType<QQuickWheelEvent>(uri, major);
+ qmlRegisterAnonymousType<QQuickCloseEvent>(uri, major);
+ qmlRegisterAnonymousType<QQuickTransform>(uri, major);
#if QT_CONFIG(quick_path)
- qmlRegisterType<QQuickPathElement>();
- qmlRegisterType<QQuickCurve>();
+ qmlRegisterAnonymousType<QQuickPathElement>(uri, major);
+ qmlRegisterAnonymousType<QQuickCurve>(uri, major);
#endif
- qmlRegisterType<QQuickScaleGrid>();
- qmlRegisterType<QQuickTextLine>();
- qmlRegisterType<QQuickPen>();
- qmlRegisterType<QQuickFlickableVisibleArea>();
+ qmlRegisterAnonymousType<QQuickScaleGrid>(uri, major);
+ qmlRegisterAnonymousType<QQuickTextLine>(uri, major);
+ qmlRegisterAnonymousType<QQuickPen>(uri, major);
+ qmlRegisterAnonymousType<QQuickFlickableVisibleArea>(uri, major);
qRegisterMetaType<QQuickAnchorLine>("QQuickAnchorLine");
- qmlRegisterType<QQuickTextDocument>();
+ qmlRegisterAnonymousType<QQuickTextDocument>(uri, major);
qmlRegisterUncreatableType<QQuickKeyNavigationAttached>(uri,major,minor,"KeyNavigation",QQuickKeyNavigationAttached::tr("KeyNavigation is only available via attached properties"));
@@ -279,7 +279,7 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
qmlRegisterType<QQuickPinchArea>(uri,major,minor,"PinchArea");
qmlRegisterType<QQuickPinch>(uri,major,minor,"Pinch");
- qmlRegisterType<QQuickPinchEvent>();
+ qmlRegisterAnonymousType<QQuickPinchEvent>(uri, major);
#if QT_CONFIG(quick_shadereffect)
qmlRegisterType<QQuickShaderEffectSource>("QtQuick", 2, 0, "ShaderEffectSource");
@@ -302,7 +302,7 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
qmlRegisterType<QQuickParentChange>(uri, major, minor,"ParentChange");
qmlRegisterType<QQuickAnchorChanges>(uri, major, minor,"AnchorChanges");
- qmlRegisterType<QQuickAnchorSet>();
+ qmlRegisterAnonymousType<QQuickAnchorSet>(uri, major);
qmlRegisterType<QQuickAnchorAnimation>(uri, major, minor,"AnchorAnimation");
qmlRegisterType<QQuickParentAnimation>(uri, major, minor,"ParentAnimation");
#if QT_CONFIG(quick_path)
@@ -312,8 +312,8 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
#if QT_CONFIG(quick_draganddrop)
qmlRegisterType<QQuickDropArea>("QtQuick", 2, 0, "DropArea");
- qmlRegisterType<QQuickDropEvent>();
- qmlRegisterType<QQuickDropAreaDrag>();
+ qmlRegisterAnonymousType<QQuickDropEvent>(uri, 2);
+ qmlRegisterAnonymousType<QQuickDropAreaDrag>(uri, 2);
qmlRegisterUncreatableType<QQuickDrag>("QtQuick", 2, 0, "Drag", QQuickDragAttached::tr("Drag is only available via attached properties"));
#endif
@@ -334,7 +334,7 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
const char *itemViewName = "ItemView";
const QString itemViewMessage = QQuickItemView::tr("ItemView is an abstract base class");
qmlRegisterUncreatableType<QQuickItemView, 1>(uri, 2, 1, itemViewName, itemViewMessage);
- qmlRegisterUncreatableType<QQuickItemView, 2>(uri, 2, 3, itemViewName, itemViewMessage);
+ qmlRegisterUncreatableType<QQuickItemView, 3>(uri, 2, 3, itemViewName, itemViewMessage);
#endif
#if QT_CONFIG(quick_listview)
qmlRegisterType<QQuickListView, 1>(uri, 2, 1, "ListView");
@@ -349,23 +349,23 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
qmlRegisterType<QQuickText, 3>(uri, 2, 3, "Text");
qmlRegisterType<QQuickTextEdit, 3>(uri, 2, 3, "TextEdit");
- qmlRegisterType<QQuickImage, 1>(uri, 2, 3,"Image");
+ qmlRegisterType<QQuickImage, 3>(uri, 2, 3,"Image");
- qmlRegisterType<QQuickItem, 2>(uri, 2, 4, "Item");
+ qmlRegisterType<QQuickItem, 4>(uri, 2, 4, "Item");
#if QT_CONFIG(quick_listview)
- qmlRegisterType<QQuickListView, 2>(uri, 2, 4, "ListView");
+ qmlRegisterType<QQuickListView, 4>(uri, 2, 4, "ListView");
#endif
- qmlRegisterType<QQuickMouseArea, 1>(uri, 2, 4, "MouseArea");
+ qmlRegisterType<QQuickMouseArea, 4>(uri, 2, 4, "MouseArea");
#if QT_CONFIG(quick_shadereffect)
- qmlRegisterType<QQuickShaderEffect, 1>(uri, 2, 4, "ShaderEffect");
+ qmlRegisterType<QQuickShaderEffect, 4>(uri, 2, 4, "ShaderEffect");
#endif
#if QT_CONFIG(opengl)
qmlRegisterUncreatableType<QQuickOpenGLInfo>(uri, 2, 4,"OpenGLInfo", QQuickOpenGLInfo::tr("OpenGLInfo is only available via attached properties"));
#endif
- qmlRegisterType<QQuickPinchArea, 1>(uri, 2, 5,"PinchArea");
- qmlRegisterType<QQuickImage, 2>(uri, 2, 5,"Image");
- qmlRegisterType<QQuickMouseArea, 2>(uri, 2, 5, "MouseArea");
+ qmlRegisterType<QQuickPinchArea, 5>(uri, 2, 5,"PinchArea");
+ qmlRegisterType<QQuickImage, 5>(uri, 2, 5,"Image");
+ qmlRegisterType<QQuickMouseArea, 5>(uri, 2, 5, "MouseArea");
qmlRegisterType<QQuickText, 6>(uri, 2, 6, "Text");
qmlRegisterType<QQuickTextEdit, 6>(uri, 2, 6, "TextEdit");
@@ -381,7 +381,7 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
qmlRegisterUncreatableType<QQuickEnterKeyAttached, 6>(uri, 2, 6, "EnterKey",
QQuickEnterKeyAttached::tr("EnterKey is only available via attached properties"));
#if QT_CONFIG(quick_shadereffect)
- qmlRegisterType<QQuickShaderEffectSource, 1>(uri, 2, 6, "ShaderEffectSource");
+ qmlRegisterType<QQuickShaderEffectSource, 6>(uri, 2, 6, "ShaderEffectSource");
#endif
qmlRegisterType<QQuickItem, 7>(uri, 2, 7, "Item");
@@ -411,7 +411,7 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
qmlRegisterType<QQuickMouseArea, 9>(uri, 2, 9, "MouseArea");
#if QT_CONFIG(quick_path)
- qmlRegisterType<QQuickPathArc, 2>(uri, 2, 9, "PathArc");
+ qmlRegisterType<QQuickPathArc, 9>(uri, 2, 9, "PathArc");
qmlRegisterType<QQuickPathMove>(uri, 2, 9, "PathMove");
#endif
@@ -426,7 +426,7 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
#endif
#if QT_CONFIG(quick_shadereffect)
- qmlRegisterType<QQuickShaderEffectSource, 2>(uri, 2, 9, "ShaderEffectSource");
+ qmlRegisterType<QQuickShaderEffectSource, 9>(uri, 2, 9, "ShaderEffectSource");
#endif
qmlRegisterType<QQuickFlickable, 10>(uri, 2, 10, "Flickable");
@@ -491,6 +491,9 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
#if QT_CONFIG(wheelevent)
qmlRegisterType<QQuickWheelHandler>(uri, 2, 14, "WheelHandler");
#endif
+ qmlRegisterUncreatableType<QQuickImageBase, 14>(uri, 2, 14, "ImageBase",
+ QQuickPointerHandler::tr("ImageBase is an abstract base class"));
+ qmlRegisterType<QQuickImage, 14>(uri, 2, 14, "Image");
}
static void initResources()
diff --git a/src/quick/items/qquickitemview_p.h b/src/quick/items/qquickitemview_p.h
index 0a0da587b4..66e09f9ed1 100644
--- a/src/quick/items/qquickitemview_p.h
+++ b/src/quick/items/qquickitemview_p.h
@@ -81,8 +81,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickItemView : public QQuickFlickable
Q_PROPERTY(bool keyNavigationWraps READ isWrapEnabled WRITE setWrapEnabled NOTIFY keyNavigationWrapsChanged)
Q_PROPERTY(bool keyNavigationEnabled READ isKeyNavigationEnabled WRITE setKeyNavigationEnabled NOTIFY keyNavigationEnabledChanged REVISION 7)
Q_PROPERTY(int cacheBuffer READ cacheBuffer WRITE setCacheBuffer NOTIFY cacheBufferChanged)
- Q_PROPERTY(int displayMarginBeginning READ displayMarginBeginning WRITE setDisplayMarginBeginning NOTIFY displayMarginBeginningChanged REVISION 2)
- Q_PROPERTY(int displayMarginEnd READ displayMarginEnd WRITE setDisplayMarginEnd NOTIFY displayMarginEndChanged REVISION 2)
+ Q_PROPERTY(int displayMarginBeginning READ displayMarginBeginning WRITE setDisplayMarginBeginning NOTIFY displayMarginBeginningChanged REVISION 3)
+ Q_PROPERTY(int displayMarginEnd READ displayMarginEnd WRITE setDisplayMarginEnd NOTIFY displayMarginEndChanged REVISION 3)
Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection NOTIFY layoutDirectionChanged)
Q_PROPERTY(Qt::LayoutDirection effectiveLayoutDirection READ effectiveLayoutDirection NOTIFY effectiveLayoutDirectionChanged)
diff --git a/src/quick/items/qquicklistview_p.h b/src/quick/items/qquicklistview_p.h
index 9a9b325b1e..f2bab9e018 100644
--- a/src/quick/items/qquicklistview_p.h
+++ b/src/quick/items/qquicklistview_p.h
@@ -126,8 +126,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickListView : public QQuickItemView
Q_PROPERTY(SnapMode snapMode READ snapMode WRITE setSnapMode NOTIFY snapModeChanged)
- Q_PROPERTY(HeaderPositioning headerPositioning READ headerPositioning WRITE setHeaderPositioning NOTIFY headerPositioningChanged REVISION 2)
- Q_PROPERTY(FooterPositioning footerPositioning READ footerPositioning WRITE setFooterPositioning NOTIFY footerPositioningChanged REVISION 2)
+ Q_PROPERTY(HeaderPositioning headerPositioning READ headerPositioning WRITE setHeaderPositioning NOTIFY headerPositioningChanged REVISION 4)
+ Q_PROPERTY(FooterPositioning footerPositioning READ footerPositioning WRITE setFooterPositioning NOTIFY footerPositioningChanged REVISION 4)
Q_CLASSINFO("DefaultProperty", "data")
@@ -188,8 +188,8 @@ Q_SIGNALS:
void highlightResizeVelocityChanged();
void highlightResizeDurationChanged();
void snapModeChanged();
- Q_REVISION(2) void headerPositioningChanged();
- Q_REVISION(2) void footerPositioningChanged();
+ Q_REVISION(4) void headerPositioningChanged();
+ Q_REVISION(4) void footerPositioningChanged();
protected:
void viewportMoved(Qt::Orientations orient) override;
diff --git a/src/quick/items/qquickmousearea.cpp b/src/quick/items/qquickmousearea.cpp
index bce7ec718b..a8f09dc8be 100644
--- a/src/quick/items/qquickmousearea.cpp
+++ b/src/quick/items/qquickmousearea.cpp
@@ -899,7 +899,7 @@ void QQuickMouseArea::wheelEvent(QWheelEvent *event)
}
QQuickWheelEvent &we = d->quickWheelEvent;
- we.reset(event->posF().x(), event->posF().y(), event->angleDelta(), event->pixelDelta(),
+ we.reset(event->position().x(), event->position().y(), event->angleDelta(), event->pixelDelta(),
event->buttons(), event->modifiers(), event->inverted());
we.setAccepted(d->isWheelConnected());
emit wheel(&we);
diff --git a/src/quick/items/qquickmousearea_p.h b/src/quick/items/qquickmousearea_p.h
index 76e5c98b35..0e01fa7915 100644
--- a/src/quick/items/qquickmousearea_p.h
+++ b/src/quick/items/qquickmousearea_p.h
@@ -71,7 +71,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickMouseArea : public QQuickItem
Q_PROPERTY(bool containsMouse READ hovered NOTIFY hoveredChanged)
Q_PROPERTY(bool pressed READ pressed NOTIFY pressedChanged)
Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged)
- Q_PROPERTY(bool scrollGestureEnabled READ isScrollGestureEnabled WRITE setScrollGestureEnabled NOTIFY scrollGestureEnabledChanged REVISION 2)
+ Q_PROPERTY(bool scrollGestureEnabled READ isScrollGestureEnabled WRITE setScrollGestureEnabled NOTIFY scrollGestureEnabledChanged REVISION 5)
Q_PROPERTY(Qt::MouseButtons pressedButtons READ pressedButtons NOTIFY pressedButtonsChanged)
Q_PROPERTY(Qt::MouseButtons acceptedButtons READ acceptedButtons WRITE setAcceptedButtons NOTIFY acceptedButtonsChanged)
Q_PROPERTY(bool hoverEnabled READ hoverEnabled WRITE setHoverEnabled NOTIFY hoverEnabledChanged)
@@ -83,7 +83,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickMouseArea : public QQuickItem
#if QT_CONFIG(cursor)
Q_PROPERTY(Qt::CursorShape cursorShape READ cursorShape WRITE setCursorShape RESET unsetCursor NOTIFY cursorShapeChanged)
#endif
- Q_PROPERTY(bool containsPress READ containsPress NOTIFY containsPressChanged REVISION 1)
+ Q_PROPERTY(bool containsPress READ containsPress NOTIFY containsPressChanged REVISION 4)
Q_PROPERTY(int pressAndHoldInterval READ pressAndHoldInterval WRITE setPressAndHoldInterval NOTIFY pressAndHoldIntervalChanged RESET resetPressAndHoldInterval REVISION 9)
public:
@@ -134,7 +134,7 @@ Q_SIGNALS:
void hoveredChanged();
void pressedChanged();
void enabledChanged();
- Q_REVISION(2) void scrollGestureEnabledChanged();
+ Q_REVISION(5) void scrollGestureEnabledChanged();
void pressedButtonsChanged();
void acceptedButtonsChanged();
void hoverEnabledChanged();
@@ -156,7 +156,7 @@ Q_SIGNALS:
void entered();
void exited();
void canceled();
- Q_REVISION(1) void containsPressChanged();
+ Q_REVISION(4) void containsPressChanged();
Q_REVISION(9) void pressAndHoldIntervalChanged();
protected:
diff --git a/src/quick/items/qquickpincharea_p.h b/src/quick/items/qquickpincharea_p.h
index 8eff53e6dc..cf21555823 100644
--- a/src/quick/items/qquickpincharea_p.h
+++ b/src/quick/items/qquickpincharea_p.h
@@ -59,7 +59,7 @@ class Q_AUTOTEST_EXPORT QQuickPinch : public QObject
{
Q_OBJECT
- Q_PROPERTY(QQuickItem *target READ target WRITE setTarget RESET resetTarget)
+ Q_PROPERTY(QQuickItem *target READ target WRITE setTarget RESET resetTarget NOTIFY targetChanged)
Q_PROPERTY(qreal minimumScale READ minimumScale WRITE setMinimumScale NOTIFY minimumScaleChanged)
Q_PROPERTY(qreal maximumScale READ maximumScale WRITE setMaximumScale NOTIFY maximumScaleChanged)
Q_PROPERTY(qreal minimumRotation READ minimumRotation WRITE setMinimumRotation NOTIFY minimumRotationChanged)
@@ -283,7 +283,7 @@ Q_SIGNALS:
void pinchStarted(QQuickPinchEvent *pinch);
void pinchUpdated(QQuickPinchEvent *pinch);
void pinchFinished(QQuickPinchEvent *pinch);
- Q_REVISION(1) void smartZoom(QQuickPinchEvent *pinch);
+ Q_REVISION(5) void smartZoom(QQuickPinchEvent *pinch);
protected:
bool childMouseEventFilter(QQuickItem *i, QEvent *e) override;
diff --git a/src/quick/items/qquickscreen_p.h b/src/quick/items/qquickscreen_p.h
index e9db07d14c..10e524e4a0 100644
--- a/src/quick/items/qquickscreen_p.h
+++ b/src/quick/items/qquickscreen_p.h
@@ -83,8 +83,8 @@ class Q_AUTOTEST_EXPORT QQuickScreenInfo : public QObject
// TODO Qt 6 Remove this orientation -> incomplete device orientation -> better use OrientationSensor
Q_PROPERTY(Qt::ScreenOrientation orientation READ orientation NOTIFY orientationChanged)
- Q_PROPERTY(int virtualX READ virtualX NOTIFY virtualXChanged REVISION 1)
- Q_PROPERTY(int virtualY READ virtualY NOTIFY virtualYChanged REVISION 1)
+ Q_PROPERTY(int virtualX READ virtualX NOTIFY virtualXChanged REVISION 3)
+ Q_PROPERTY(int virtualY READ virtualY NOTIFY virtualYChanged REVISION 3)
public:
QQuickScreenInfo(QObject *parent = nullptr, QScreen *wrappedScreen = nullptr);
@@ -121,8 +121,8 @@ Q_SIGNALS:
void devicePixelRatioChanged();
void primaryOrientationChanged();
void orientationChanged();
- Q_REVISION(1) void virtualXChanged();
- Q_REVISION(1) void virtualYChanged();
+ Q_REVISION(3) void virtualXChanged();
+ Q_REVISION(3) void virtualYChanged();
protected:
QPointer<QScreen> m_screen;
diff --git a/src/quick/items/qquickshadereffect_p.h b/src/quick/items/qquickshadereffect_p.h
index c5bddc40d2..6e2f35882b 100644
--- a/src/quick/items/qquickshadereffect_p.h
+++ b/src/quick/items/qquickshadereffect_p.h
@@ -74,7 +74,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickShaderEffect : public QQuickItem
Q_PROPERTY(CullMode cullMode READ cullMode WRITE setCullMode NOTIFY cullModeChanged)
Q_PROPERTY(QString log READ log NOTIFY logChanged)
Q_PROPERTY(Status status READ status NOTIFY statusChanged)
- Q_PROPERTY(bool supportsAtlasTextures READ supportsAtlasTextures WRITE setSupportsAtlasTextures NOTIFY supportsAtlasTexturesChanged REVISION 1)
+ Q_PROPERTY(bool supportsAtlasTextures READ supportsAtlasTextures WRITE setSupportsAtlasTextures NOTIFY supportsAtlasTexturesChanged REVISION 4)
public:
enum CullMode {
diff --git a/src/quick/items/qquickshadereffectsource_p.h b/src/quick/items/qquickshadereffectsource_p.h
index d5bb33902a..d612d1179f 100644
--- a/src/quick/items/qquickshadereffectsource_p.h
+++ b/src/quick/items/qquickshadereffectsource_p.h
@@ -87,8 +87,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickShaderEffectSource : public QQuickItem, publi
Q_PROPERTY(bool hideSource READ hideSource WRITE setHideSource NOTIFY hideSourceChanged)
Q_PROPERTY(bool mipmap READ mipmap WRITE setMipmap NOTIFY mipmapChanged)
Q_PROPERTY(bool recursive READ recursive WRITE setRecursive NOTIFY recursiveChanged)
- Q_PROPERTY(TextureMirroring textureMirroring READ textureMirroring WRITE setTextureMirroring NOTIFY textureMirroringChanged REVISION 1)
- Q_PROPERTY(int samples READ samples WRITE setSamples NOTIFY samplesChanged REVISION 2)
+ Q_PROPERTY(TextureMirroring textureMirroring READ textureMirroring WRITE setTextureMirroring NOTIFY textureMirroringChanged REVISION 6)
+ Q_PROPERTY(int samples READ samples WRITE setSamples NOTIFY samplesChanged REVISION 9)
public:
enum WrapMode {
diff --git a/src/quick/items/qquicktextinput_p.h b/src/quick/items/qquicktextinput_p.h
index c46a2f8128..92f3aa62ce 100644
--- a/src/quick/items/qquicktextinput_p.h
+++ b/src/quick/items/qquicktextinput_p.h
@@ -93,7 +93,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickTextInput : public QQuickImplicitSizeItem
Q_PROPERTY(EchoMode echoMode READ echoMode WRITE setEchoMode NOTIFY echoModeChanged)
Q_PROPERTY(bool activeFocusOnPress READ focusOnPress WRITE setFocusOnPress NOTIFY activeFocusOnPressChanged)
Q_PROPERTY(QString passwordCharacter READ passwordCharacter WRITE setPasswordCharacter NOTIFY passwordCharacterChanged)
- Q_PROPERTY(int passwordMaskDelay READ passwordMaskDelay WRITE setPasswordMaskDelay RESET resetPasswordMaskDelay NOTIFY passwordMaskDelayChanged REVISION 3)
+ Q_PROPERTY(int passwordMaskDelay READ passwordMaskDelay WRITE setPasswordMaskDelay RESET resetPasswordMaskDelay NOTIFY passwordMaskDelayChanged REVISION 4)
Q_PROPERTY(QString displayText READ displayText NOTIFY displayTextChanged)
Q_PROPERTY(QString preeditText READ preeditText NOTIFY preeditTextChanged REVISION 7)
Q_PROPERTY(bool autoScroll READ autoScroll WRITE setAutoScroll NOTIFY autoScrollChanged)
@@ -268,7 +268,7 @@ public:
#if QT_CONFIG(im)
QVariant inputMethodQuery(Qt::InputMethodQuery property) const override;
- Q_REVISION(3) Q_INVOKABLE QVariant inputMethodQuery(Qt::InputMethodQuery query, QVariant argument) const;
+ Q_REVISION(4) Q_INVOKABLE QVariant inputMethodQuery(Qt::InputMethodQuery query, QVariant argument) const;
#endif
QRectF boundingRect() const override;
@@ -336,7 +336,7 @@ Q_SIGNALS:
void inputMaskChanged(const QString &inputMask);
void echoModeChanged(QQuickTextInput::EchoMode echoMode);
void passwordCharacterChanged();
- Q_REVISION(3) void passwordMaskDelayChanged(int delay);
+ Q_REVISION(4) void passwordMaskDelayChanged(int delay);
void displayTextChanged();
Q_REVISION(7) void preeditTextChanged();
void activeFocusOnPressChanged(bool activeFocusOnPress);
@@ -399,7 +399,7 @@ public Q_SLOTS:
void redo();
void insert(int position, const QString &text);
void remove(int start, int end);
- Q_REVISION(3) void ensureVisible(int position);
+ Q_REVISION(4) void ensureVisible(int position);
Q_REVISION(7) void clear();
private Q_SLOTS:
diff --git a/src/quick/items/qquicktextnodeengine.cpp b/src/quick/items/qquicktextnodeengine.cpp
index 32478ba375..c4a8370f34 100644
--- a/src/quick/items/qquicktextnodeengine.cpp
+++ b/src/quick/items/qquicktextnodeengine.cpp
@@ -477,7 +477,7 @@ void QQuickTextNodeEngine::addTextObject(const QTextBlock &block, const QPointF
}
qreal ascent;
- QTextLine line = block.layout()->lineForTextPosition(pos);
+ QTextLine line = block.layout()->lineForTextPosition(pos - block.position());
switch (format.verticalAlignment())
{
case QTextCharFormat::AlignTop:
diff --git a/src/quick/items/qquickview.cpp b/src/quick/items/qquickview.cpp
index 61477360bf..17fc16d44b 100644
--- a/src/quick/items/qquickview.cpp
+++ b/src/quick/items/qquickview.cpp
@@ -240,6 +240,22 @@ void QQuickView::setSource(const QUrl& url)
}
/*!
+ Sets the initial properties with which the QML component gets initialized after
+ calling \l QQuickView::setSource.
+
+
+ Note that you can only use this function to initialize toplevel properties.
+
+ \sa QQmlComponent::createWithInitialProperties
+ \since 5.14
+*/
+void QQuickView::setInitialProperties(const QVariantMap &initialProperties)
+{
+ Q_D(QQuickView);
+ d->initialProperties = initialProperties;
+}
+
+/*!
\internal
Set the source \a url, \a component and content \a item (root of the QML object hierarchy) directly.
@@ -471,7 +487,7 @@ void QQuickView::continueExecute()
return;
}
- QObject *obj = d->component->create();
+ QObject *obj = d->initialProperties.empty() ? d->component->create() : d->component->createWithInitialProperties(d->initialProperties);
if (d->component->isError()) {
const QList<QQmlError> errorList = d->component->errors();
diff --git a/src/quick/items/qquickview.h b/src/quick/items/qquickview.h
index ecae25e90b..4122fcac79 100644
--- a/src/quick/items/qquickview.h
+++ b/src/quick/items/qquickview.h
@@ -88,6 +88,7 @@ public:
public Q_SLOTS:
void setSource(const QUrl&);
+ void setInitialProperties(const QVariantMap &initialProperties);
void setContent(const QUrl& url, QQmlComponent *component, QObject *item);
Q_SIGNALS:
diff --git a/src/quick/items/qquickview_p.h b/src/quick/items/qquickview_p.h
index 3f284c0519..b1ab8d8e8c 100644
--- a/src/quick/items/qquickview_p.h
+++ b/src/quick/items/qquickview_p.h
@@ -108,6 +108,8 @@ public:
QQuickView::ResizeMode resizeMode;
QSize initialSize;
QElapsedTimer frameTimer;
+
+ QVariantMap initialProperties;
};
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index 88a731b229..8b5e2a012a 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -4666,6 +4666,11 @@ const QQuickWindow::GraphicsStateInfo *QQuickWindow::graphicsStateInfo()
beginExternalCommands() and endExternalCommands() together provide a
replacement for resetOpenGLState().
+ Calling this function and endExternalCommands() is not necessary within the
+ \l{QSGRenderNode::render()}{render()} implementation of a QSGRenderNode
+ because the scene graph performs the necessary steps implicitly for render
+ nodes.
+
\note This function has no effect when the scene graph is using OpenGL
directly and the RHI graphics abstraction layer is not in use. Refer to
resetOpenGLState() in that case.
@@ -4704,6 +4709,11 @@ void QQuickWindow::beginExternalCommands()
beginExternalCommands() and endExternalCommands() together provide a
replacement for resetOpenGLState().
+ Calling this function and beginExternalCommands() is not necessary within the
+ \l{QSGRenderNode::render()}{render()} implementation of a QSGRenderNode
+ because the scene graph performs the necessary steps implicitly for render
+ nodes.
+
\note This function has no effect when the scene graph is using OpenGL
directly and the RHI graphics abstraction layer is not in use. Refer to
resetOpenGLState() in that case.
diff --git a/src/quick/items/qquickwindowmodule.cpp b/src/quick/items/qquickwindowmodule.cpp
index 7b3874dbfe..4b2b8f498d 100644
--- a/src/quick/items/qquickwindowmodule.cpp
+++ b/src/quick/items/qquickwindowmodule.cpp
@@ -205,11 +205,11 @@ void QQuickWindowModule::defineModule()
qmlRegisterRevision<QQuickWindow,1>(uri, 2, 1);//Type moved to a subclass, but also has new members
qmlRegisterRevision<QQuickWindow,2>(uri, 2, 2);
qmlRegisterType<QQuickWindowQmlImpl>(uri, 2, 1, "Window");
- qmlRegisterType<QQuickWindowQmlImpl,1>(uri, 2, 2, "Window");
- qmlRegisterType<QQuickWindowQmlImpl,2>(uri, 2, 3, "Window");
+ qmlRegisterType<QQuickWindowQmlImpl,2>(uri, 2, 2, "Window");
+ qmlRegisterType<QQuickWindowQmlImpl,3>(uri, 2, 3, "Window");
qmlRegisterUncreatableType<QQuickScreen>(uri, 2, 0, "Screen", QStringLiteral("Screen can only be used via the attached property."));
- qmlRegisterUncreatableType<QQuickScreen,1>(uri, 2, 3, "Screen", QStringLiteral("Screen can only be used via the attached property."));
- qmlRegisterUncreatableType<QQuickScreenInfo,2>(uri, 2, 3, "ScreenInfo", QStringLiteral("ScreenInfo can only be used via the attached property."));
+ qmlRegisterUncreatableType<QQuickScreen,3>(uri, 2, 3, "Screen", QStringLiteral("Screen can only be used via the attached property."));
+ qmlRegisterUncreatableType<QQuickScreenInfo,3>(uri, 2, 3, "ScreenInfo", QStringLiteral("ScreenInfo can only be used via the attached property."));
qmlRegisterUncreatableType<QQuickScreenInfo,10>(uri, 2, 10, "ScreenInfo", QStringLiteral("ScreenInfo can only be used via the attached property."));
qmlRegisterRevision<QWindow,13>(uri, 2, 13);
qmlRegisterRevision<QQuickWindow,13>(uri, 2, 13);
diff --git a/src/quick/items/qquickwindowmodule_p.h b/src/quick/items/qquickwindowmodule_p.h
index e7033e9b8d..1dcf1a1021 100644
--- a/src/quick/items/qquickwindowmodule_p.h
+++ b/src/quick/items/qquickwindowmodule_p.h
@@ -67,7 +67,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickWindowQmlImpl : public QQuickWindow, public Q
Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged)
Q_PROPERTY(Visibility visibility READ visibility WRITE setVisibility NOTIFY visibilityChanged)
- Q_PROPERTY(QObject *screen READ screen WRITE setScreen NOTIFY screenChanged REVISION 2)
+ Q_PROPERTY(QObject *screen READ screen WRITE setScreen NOTIFY screenChanged REVISION 3)
public:
QQuickWindowQmlImpl(QWindow *parent = nullptr);
@@ -83,7 +83,7 @@ public:
Q_SIGNALS:
void visibleChanged(bool arg);
void visibilityChanged(QWindow::Visibility visibility);
- Q_REVISION(2) void screenChanged();
+ Q_REVISION(3) void screenChanged();
protected:
void classBegin() override;
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp
index f8973af2fb..2d4dcd928d 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp
@@ -69,10 +69,6 @@ const QEvent::Type WM_Obscure = QEvent::Type(QEvent::User + 1);
// Passed from the RL to RT when GUI has been locked, waiting for sync.
const QEvent::Type WM_RequestSync = QEvent::Type(QEvent::User + 2);
-// Passed by the RT to itself to trigger another render pass. This is typically
-// a result of QQuickWindow::update().
-const QEvent::Type WM_RequestRepaint = QEvent::Type(QEvent::User + 3);
-
// Passed by the RL to the RT to maybe release resource if no windows are
// rendering.
const QEvent::Type WM_TryRelease = QEvent::Type(QEvent::User + 4);
@@ -353,13 +349,6 @@ bool QSGSoftwareRenderThread::event(QEvent *e)
return true;
}
- case WM_RequestRepaint:
- qCDebug(QSG_RASTER_LOG_RENDERLOOP, "RT - WM_RequestPaint");
- // When GUI posts this event, it is followed by a polishAndSync, so we
- // must not exit the event loop yet.
- pendingUpdate |= RepaintRequest;
- break;
-
default:
break;
}
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
index 3d8e3291b2..2441e14fda 100644
--- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
+++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
@@ -2665,7 +2665,8 @@ void Renderer::updateClipState(const QSGClipNode *clipList, Batch *batch) // RHI
{
// Note: No use of the clip-related speparate m_current* vars is allowed
// here. All stored in batch->clipState instead. To collect state during
- // renderBatches(), m_currentClipState is used.
+ // the prepare steps, m_currentClipState is used. It should not be used in
+ // the render steps afterwards.
// The stenciling logic is slightly different from the legacy GL path as we
// cannot just randomly clear the stencil buffer. We now put all clip
@@ -4089,7 +4090,7 @@ void Renderer::renderBatches()
if (b->merged)
ok = prepareRenderMergedBatch(b, &renderBatch);
else if (b->isRenderNode)
- ok = false; // ###
+ ok = prepareRhiRenderNode(b, &renderBatch);
else
ok = prepareRenderUnmergedBatch(b, &renderBatch);
if (ok)
@@ -4120,7 +4121,7 @@ void Renderer::renderBatches()
if (renderBatch->batch->merged)
renderMergedBatch(renderBatch);
else if (renderBatch->batch->isRenderNode)
- Q_UNREACHABLE(); // ###
+ renderRhiRenderNode(renderBatch->batch);
else
renderUnmergedBatch(renderBatch);
}
@@ -4359,7 +4360,7 @@ struct RenderNodeState : public QSGRenderNode::RenderState
bool m_stencilEnabled;
};
-void Renderer::renderRenderNode(Batch *batch)
+void Renderer::renderRenderNode(Batch *batch) // legacy (GL-only)
{
if (Q_UNLIKELY(debug_render()))
qDebug() << " -" << batch << "rendernode";
@@ -4475,6 +4476,108 @@ void Renderer::renderRenderNode(Batch *batch)
glBindFramebuffer(GL_FRAMEBUFFER, prevFbo);
}
+bool Renderer::prepareRhiRenderNode(Batch *batch, PreparedRenderBatch *renderBatch) // split prepare-render (RHI only)
+{
+ if (Q_UNLIKELY(debug_render()))
+ qDebug() << " -" << batch << "rendernode";
+
+ Q_ASSERT(batch->first->isRenderNode);
+ RenderNodeElement *e = static_cast<RenderNodeElement *>(batch->first);
+
+ setActiveRhiShader(nullptr, nullptr);
+
+ QSGNode *clip = e->renderNode->parent();
+ QSGRenderNodePrivate *rd = QSGRenderNodePrivate::get(e->renderNode);
+ rd->m_clip_list = nullptr;
+ while (clip != rootNode()) {
+ if (clip->type() == QSGNode::ClipNodeType) {
+ rd->m_clip_list = static_cast<QSGClipNode *>(clip);
+ break;
+ }
+ clip = clip->parent();
+ }
+
+ updateClipState(rd->m_clip_list, batch);
+
+ renderBatch->batch = batch;
+ renderBatch->sms = nullptr;
+
+ return true;
+}
+
+void Renderer::renderRhiRenderNode(const Batch *batch) // split prepare-render (RHI only)
+{
+ if (batch->clipState.type & ClipState::StencilClip)
+ enqueueStencilDraw(batch);
+
+ RenderNodeElement *e = static_cast<RenderNodeElement *>(batch->first);
+ QSGRenderNodePrivate *rd = QSGRenderNodePrivate::get(e->renderNode);
+
+ QMatrix4x4 pm = projectionMatrix();
+ if (m_useDepthBuffer) {
+ pm(2, 2) = m_zRange;
+ pm(2, 3) = 1.0f - e->order * m_zRange;
+ }
+
+ RenderNodeState state;
+ state.m_projectionMatrix = &pm;
+ const std::array<int, 4> scissor = batch->clipState.scissor.scissor();
+ state.m_scissorRect = QRect(scissor[0], scissor[1], scissor[2], scissor[3]);
+ state.m_stencilValue = batch->clipState.stencilRef;
+ state.m_scissorEnabled = batch->clipState.type & ClipState::ScissorClip;
+ state.m_stencilEnabled = batch->clipState.type & ClipState::StencilClip;
+
+ QSGNode *xform = e->renderNode->parent();
+ QMatrix4x4 matrix;
+ QSGNode *root = rootNode();
+ if (e->root) {
+ matrix = qsg_matrixForRoot(e->root);
+ root = e->root->sgNode;
+ }
+ while (xform != root) {
+ if (xform->type() == QSGNode::TransformNodeType) {
+ matrix = matrix * static_cast<QSGTransformNode *>(xform)->combinedMatrix();
+ break;
+ }
+ xform = xform->parent();
+ }
+ rd->m_matrix = &matrix;
+
+ QSGNode *opacity = e->renderNode->parent();
+ rd->m_opacity = 1.0;
+ while (opacity != rootNode()) {
+ if (opacity->type() == QSGNode::OpacityNodeType) {
+ rd->m_opacity = static_cast<QSGOpacityNode *>(opacity)->combinedOpacity();
+ break;
+ }
+ opacity = opacity->parent();
+ }
+
+ const QSGRenderNode::StateFlags changes = e->renderNode->changedStates();
+
+ QRhiCommandBuffer *cb = commandBuffer();
+ cb->beginExternal();
+ e->renderNode->render(&state);
+ cb->endExternal();
+
+ rd->m_matrix = nullptr;
+ rd->m_clip_list = nullptr;
+
+ if ((changes & QSGRenderNode::ViewportState)
+ || (changes & QSGRenderNode::ScissorState))
+ {
+ // Reset both flags if either is reported as changed, since with the rhi
+ // it could be setViewport() that will record the resetting of the scissor.
+ m_pstate.viewportSet = false;
+ m_pstate.scissorSet = false;
+ }
+
+ // Do not bother with RenderTargetState. Where applicable, endExternal()
+ // ensures the correct target is rebound. For others (like Vulkan) it makes
+ // no sense since render() could not possibly do that on our command buffer
+ // which is in renderpass recording state.
+}
+
void Renderer::setCustomRenderMode(const QByteArray &mode)
{
if (mode.isEmpty())
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
index ea9dab244f..4e374522d4 100644
--- a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
+++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
@@ -817,6 +817,8 @@ private:
void enqueueStencilDraw(const Batch *batch);
const QMatrix4x4 &matrixForRoot(Node *node);
void renderRenderNode(Batch *batch);
+ bool prepareRhiRenderNode(Batch *batch, PreparedRenderBatch *renderBatch);
+ void renderRhiRenderNode(const Batch *batch);
void setActiveShader(QSGMaterialShader *program, ShaderManager::Shader *shader);
void setActiveRhiShader(QSGMaterialRhiShader *program, ShaderManager::Shader *shader);
diff --git a/src/quick/scenegraph/coreapi/qsgrendernode.cpp b/src/quick/scenegraph/coreapi/qsgrendernode.cpp
index df3fa16a32..2892f2f966 100644
--- a/src/quick/scenegraph/coreapi/qsgrendernode.cpp
+++ b/src/quick/scenegraph/coreapi/qsgrendernode.cpp
@@ -81,8 +81,10 @@ QSGRenderNodePrivate::QSGRenderNodePrivate()
}
/*!
- This function should return a mask where each bit represents graphics states changed by
- the \l render() function:
+ When the underlying rendering API is OpenGL, this function should return a
+ mask where each bit represents graphics states changed by the \l render()
+ function:
+
\list
\li DepthState - depth write mask, depth test enabled, depth comparison function
\li StencilState - stencil write masks, stencil test enabled, stencil operations,
@@ -95,6 +97,29 @@ QSGRenderNodePrivate::QSGRenderNodePrivate()
\li RenderTargetState - render target
\endlist
+ With APIs other than OpenGL, the only relevant values are the ones that
+ correspond to dynamic state changes recorded on the command list/buffer.
+ For example, RSSetViewports, RSSetScissorRects, OMSetBlendFactor,
+ OMSetStencilRef in case of D3D12, or vkCmdSetViewport, vkCmdSetScissor,
+ vkCmdSetBlendConstants, vkCmdSetStencilRef in case of Vulkan, and only when
+ such commands were added to the scenegraph's command list queried via the
+ QSGRendererInterface::CommandList resource enum. States set in pipeline
+ state objects do not need to be reported here. Similarly, draw call related
+ settings (pipeline states, descriptor sets, vertex or index buffer
+ bindings, root signature, descriptor heaps, etc.) are always set again by
+ the scenegraph so render() can freely change them.
+
+ \note RenderTargetState is no longer supported with APIs like Vulkan. This
+ is by nature. render() is invoked while the Qt Quick scenegraph's main
+ command buffer is recording a renderpass, so there is no possibility of
+ changing the target and starting another renderpass (on that command buffer
+ at least). Therefore returning a value with RenderTargetState set is not
+ sensible.
+
+ The software backend exposes its QPainter and saves and restores before and
+ after invoking render(). Therefore reporting any changed states from here
+ is not necessary.
+
The function is called by the renderer so it can reset the states after
rendering this node. This makes the implementation of render() simpler
since it does not have to query and restore these states.
@@ -102,19 +127,6 @@ QSGRenderNodePrivate::QSGRenderNodePrivate()
The default implementation returns 0, meaning no relevant state was changed
in render().
- With APIs other than OpenGL the relevant states are only those that are set
- via the command list (for example, OMSetRenderTargets, RSSetViewports,
- RSSetScissorRects, OMSetBlendFactor, OMSetStencilRef in case of D3D12), and
- only when such commands were added to the scenegraph's command list queried
- via the QSGRendererInterface::CommandList resource enum. States set in
- pipeline state objects do not need to be reported here. Similarly, draw
- call related settings (root signature, descriptor heaps, etc.) are always
- set again by the scenegraph so render() can freely change them.
-
- The software backend exposes its QPainter and saves and restores before and
- after invoking render(). Therefore reporting any changed states from here
- is not necessary.
-
\note This function may be called before render().
*/
QSGRenderNode::StateFlags QSGRenderNode::changedStates() const
@@ -149,18 +161,31 @@ QSGRenderNode::StateFlags QSGRenderNode::changedStates() const
QQuickFramebufferObject, QQuickWindow::beforeRendering(), or the
equivalents of those for APIs other than OpenGL.
- Clip information is calculated before the function is called, it is however
- not enabled. Implementations wishing to take clipping into account can set
- up scissoring or stencil based on the information in \a state. Some
- scenegraph backends, software in particular, use no scissor or stencil.
- There the clip region is provided as an ordinary QRegion.
+ \note QSGRenderNode can perform significantly better than texture-based
+ approaches (such as, QQuickFramebufferObject), especially on systems where
+ the fragment processing power is limited. This is because it avoids
+ rendering to a texture and then drawing a textured quad. Rather,
+ QSGRenderNode allows recording draw calls in line with the scenegraph's
+ other commands, avoiding an additional render target and the potentially
+ expensive texturing and blending.
+
+ Clip information is calculated before the function is called.
+ Implementations wishing to take clipping into account can set up scissoring
+ or stencil based on the information in \a state. The stencil buffer is
+ filled with the necessary clip shapes, but it is up to the implementation
+ to enable stencil testing.
+
+ Some scenegraph backends, software in particular, use no scissor or
+ stencil. There the clip region is provided as an ordinary QRegion.
+
+ With the legacy, direct OpenGL based renderer, the following states are set
+ on the render thread's context before this function is called:
- For OpenGL the following states are set on the render thread's context
- before this function is called:
\list
+ \li glColorMask(true, true, true, true)
\li glDepthMask(false)
\li glDisable(GL_DEPTH_TEST)
- \li glStencilFunc(GL_EQUAL, state.stencilValue, 0xff) depending on clip
+ \li glStencilFunc(GL_EQUAL, state.stencilValue, 0xff); glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP) depending on clip
\li glScissor(state.scissorRect.x(), state.scissorRect.y(),
state.scissorRect.width(), state.scissorRect.height()) depending on clip
\li glEnable(GL_BLEND)
@@ -168,23 +193,42 @@ QSGRenderNode::StateFlags QSGRenderNode::changedStates() const
\li glDisable(GL_CULL_FACE)
\endlist
- States that are not listed above, but are included in \l StateFlags, can
+ States that are not listed above, but are covered by \l StateFlags, can
have arbitrary values.
+ \note There is no state set with other graphics APIs, considering that many
+ of them do not have a concept of the traditional OpenGL state machine.
+ Rather, it is up to the implementation to create pipeline state objects
+ with the desired blending, scissor, and stencil tests enabled. Note that
+ this also includes OpenGL via the RHI. New QSGRenderNode implementations
+ are recommended to set all scissor, stencil and blend state explicitly (as
+ shown in the above list), even if they are targeting OpenGL.
+
\l changedStates() should return which states this function changes. If a
state is not covered by \l StateFlags, the state should be set to the
default value according to the OpenGL specification. For other APIs, see
the documentation for changedStates() for more information.
- \note Depth writes are disabled when this function is called (for example,
- glDepthMask(false) in case of OpenGL). Enabling depth writes can lead to
- unexpected results, depending on the scenegraph backend in use, so nodes
- should avoid this.
+ \note Depth writes are disabled when this function is called
+ (glDepthMask(false) with OpenGL). Enabling depth writes can lead to
+ unexpected results, depending on the scenegraph backend in use and the
+ content in the scene, so exercise caution with this.
For APIs other than OpenGL, it will likely be necessary to query certain
API-specific resources (for example, the graphics device or the command
list/buffer to add the commands to). This is done via QSGRendererInterface.
+ Assume nothing about the pipelines and dynamic states bound on the command
+ list/buffer when this function is called.
+
+ With some graphics APIs it can be necessary to also connect to the
+ QQuickWindow::beforeRendering() signal, because that is emitted before
+ recording the beginning of a renderpass on the command buffer
+ (vkCmdBeginRenderPass with Vulkan, or starting to encode via
+ MTLRenderCommandEncoder in case of Metal). Recording copy operations cannot
+ be done inside render() with such APIs. Rather, do it in the slot connected
+ (with DirectConnection) to the beforeRendering signal.
+
\sa QSGRendererInterface, QQuickWindow::rendererInterface()
*/
@@ -335,7 +379,8 @@ QSGRenderNode::RenderState::~RenderState()
/*!
\fn const QMatrix4x4 *QSGRenderNode::RenderState::scissorRect() const
- \return the current scissor rectangle when clipping is active.
+ \return the current scissor rectangle when clipping is active. x and y are
+ the bottom left coordinates.
\note Be aware of the differences between graphics APIs: for some the
scissor rect is only active when scissoring is enabled (for example,
diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp
index d1258cf903..9e34a2b201 100644
--- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp
+++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp
@@ -147,10 +147,6 @@ const QEvent::Type WM_Obscure = QEvent::Type(QEvent::User + 1);
// (updatePaintNode())
const QEvent::Type WM_RequestSync = QEvent::Type(QEvent::User + 2);
-// Passed by the RT to itself to trigger another render pass. This is
-// typically a result of QQuickWindow::update().
-const QEvent::Type WM_RequestRepaint = QEvent::Type(QEvent::User + 3);
-
// Passed by the RL to the RT to free up maybe release SG and GL contexts
// if no windows are rendering.
const QEvent::Type WM_TryRelease = QEvent::Type(QEvent::User + 4);
@@ -510,13 +506,6 @@ bool QSGRenderThread::event(QEvent *e)
return true;
}
- case WM_RequestRepaint:
- qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "WM_RequestPaint");
- // When GUI posts this event, it is followed by a polishAndSync, so we mustn't
- // exit the event loop yet.
- pendingUpdate |= RepaintRequest;
- break;
-
default:
break;
}
diff --git a/src/quick/util/qquickpath_p.h b/src/quick/util/qquickpath_p.h
index aa3425ff6c..92607a6c1e 100644
--- a/src/quick/util/qquickpath_p.h
+++ b/src/quick/util/qquickpath_p.h
@@ -290,7 +290,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathArc : public QQuickCurve
Q_PROPERTY(qreal radiusY READ radiusY WRITE setRadiusY NOTIFY radiusYChanged)
Q_PROPERTY(bool useLargeArc READ useLargeArc WRITE setUseLargeArc NOTIFY useLargeArcChanged)
Q_PROPERTY(ArcDirection direction READ direction WRITE setDirection NOTIFY directionChanged)
- Q_PROPERTY(qreal xAxisRotation READ xAxisRotation WRITE setXAxisRotation NOTIFY xAxisRotationChanged REVISION 2)
+ Q_PROPERTY(qreal xAxisRotation READ xAxisRotation WRITE setXAxisRotation NOTIFY xAxisRotationChanged REVISION 9)
public:
QQuickPathArc(QObject *parent=nullptr)
@@ -321,7 +321,7 @@ Q_SIGNALS:
void radiusYChanged();
void useLargeArcChanged();
void directionChanged();
- Q_REVISION(2) void xAxisRotationChanged();
+ Q_REVISION(9) void xAxisRotationChanged();
private:
qreal _radiusX = 0;
diff --git a/src/quick/util/qquickpixmapcache.cpp b/src/quick/util/qquickpixmapcache.cpp
index 78a4e5b998..56ad8ebf0b 100644
--- a/src/quick/util/qquickpixmapcache.cpp
+++ b/src/quick/util/qquickpixmapcache.cpp
@@ -241,7 +241,7 @@ class QQuickPixmapData
{
public:
QQuickPixmapData(QQuickPixmap *pixmap, const QUrl &u, const QSize &s, const QQuickImageProviderOptions &po, const QString &e)
- : refCount(1), inCache(false), pixmapStatus(QQuickPixmap::Error),
+ : refCount(1), frameCount(1), frame(0), inCache(false), pixmapStatus(QQuickPixmap::Error),
url(u), errorString(e), requestSize(s),
providerOptions(po), appliedTransform(QQuickImageProviderOptions::UsePluginDefaultTransform),
textureFactory(nullptr), reply(nullptr), prevUnreferenced(nullptr),
@@ -250,8 +250,8 @@ public:
declarativePixmaps.insert(pixmap);
}
- QQuickPixmapData(QQuickPixmap *pixmap, const QUrl &u, const QSize &r, const QQuickImageProviderOptions &po, QQuickImageProviderOptions::AutoTransform aTransform)
- : refCount(1), inCache(false), pixmapStatus(QQuickPixmap::Loading),
+ QQuickPixmapData(QQuickPixmap *pixmap, const QUrl &u, const QSize &r, const QQuickImageProviderOptions &po, QQuickImageProviderOptions::AutoTransform aTransform, int frame=0, int frameCount=1)
+ : refCount(1), frameCount(frameCount), frame(frame), inCache(false), pixmapStatus(QQuickPixmap::Loading),
url(u), requestSize(r),
providerOptions(po), appliedTransform(aTransform),
textureFactory(nullptr), reply(nullptr), prevUnreferenced(nullptr), prevUnreferencedPtr(nullptr),
@@ -261,8 +261,8 @@ public:
}
QQuickPixmapData(QQuickPixmap *pixmap, const QUrl &u, QQuickTextureFactory *texture,
- const QSize &s, const QSize &r, const QQuickImageProviderOptions &po, QQuickImageProviderOptions::AutoTransform aTransform)
- : refCount(1), inCache(false), pixmapStatus(QQuickPixmap::Ready),
+ const QSize &s, const QSize &r, const QQuickImageProviderOptions &po, QQuickImageProviderOptions::AutoTransform aTransform, int frame=0, int frameCount=1)
+ : refCount(1), frameCount(frameCount), frame(frame), inCache(false), pixmapStatus(QQuickPixmap::Ready),
url(u), implicitSize(s), requestSize(r),
providerOptions(po), appliedTransform(aTransform),
textureFactory(texture), reply(nullptr), prevUnreferenced(nullptr),
@@ -272,7 +272,7 @@ public:
}
QQuickPixmapData(QQuickPixmap *pixmap, QQuickTextureFactory *texture)
- : refCount(1), inCache(false), pixmapStatus(QQuickPixmap::Ready),
+ : refCount(1), frameCount(1), frame(0), inCache(false), pixmapStatus(QQuickPixmap::Ready),
appliedTransform(QQuickImageProviderOptions::UsePluginDefaultTransform),
textureFactory(texture), reply(nullptr), prevUnreferenced(nullptr),
prevUnreferencedPtr(nullptr), nextUnreferenced(nullptr)
@@ -299,6 +299,8 @@ public:
void removeFromCache();
uint refCount;
+ int frameCount;
+ int frame;
bool inCache:1;
@@ -396,9 +398,9 @@ static void maybeRemoveAlpha(QImage *image)
}
}
-static bool readImage(const QUrl& url, QIODevice *dev, QImage *image, QString *errorString, QSize *impsize,
+static bool readImage(const QUrl& url, QIODevice *dev, QImage *image, QString *errorString, QSize *impsize, int *frameCount,
const QSize &requestSize, const QQuickImageProviderOptions &providerOptions,
- QQuickImageProviderOptions::AutoTransform *appliedTransform = nullptr)
+ QQuickImageProviderOptions::AutoTransform *appliedTransform = nullptr, int frame = 0)
{
QImageReader imgio(dev);
if (providerOptions.autoTransform() != QQuickImageProviderOptions::UsePluginDefaultTransform)
@@ -406,6 +408,12 @@ static bool readImage(const QUrl& url, QIODevice *dev, QImage *image, QString *e
else if (appliedTransform)
*appliedTransform = imgio.autoTransform() ? QQuickImageProviderOptions::ApplyTransform : QQuickImageProviderOptions::DoNotApplyTransform;
+ if (frame < imgio.imageCount())
+ imgio.jumpToImage(frame);
+
+ if (frameCount)
+ *frameCount = imgio.imageCount();
+
QSize scSize = QQuickImageProviderWithOptions::loadSize(imgio.size(), requestSize, imgio.format(), providerOptions);
if (scSize.isValid())
imgio.setScaledSize(scSize);
@@ -558,9 +566,12 @@ void QQuickPixmapReader::networkRequestDone(QNetworkReply *reply)
QByteArray all = reply->readAll();
QBuffer buff(&all);
buff.open(QIODevice::ReadOnly);
- if (!readImage(reply->url(), &buff, &image, &errorString, &readSize, job->requestSize, job->providerOptions))
+ int frameCount;
+ if (!readImage(reply->url(), &buff, &image, &errorString, &readSize, &frameCount, job->requestSize, job->providerOptions, nullptr, job->data->frame))
error = QQuickPixmapReply::Decoding;
- }
+ else
+ job->data->frameCount = frameCount;
+ }
// send completion event to the QQuickPixmapReply
mutex.lock();
if (!cancelled.contains(job))
@@ -870,10 +881,13 @@ void QQuickPixmapReader::processJob(QQuickPixmapReply *runningJob, const QUrl &u
mutex.unlock();
return;
} else {
- if (!readImage(url, &f, &image, &errorStr, &readSize, runningJob->requestSize, runningJob->providerOptions)) {
+ int frameCount;
+ if (!readImage(url, &f, &image, &errorStr, &readSize, &frameCount, runningJob->requestSize, runningJob->providerOptions, nullptr, runningJob->data->frame)) {
errorCode = QQuickPixmapReply::Loading;
if (f.fileName() != localFile)
errorStr += QString::fromLatin1(" (%1)").arg(f.fileName());
+ } else if (runningJob->data) {
+ runningJob->data->frameCount = frameCount;
}
}
} else {
@@ -982,17 +996,18 @@ class QQuickPixmapKey
public:
const QUrl *url;
const QSize *size;
+ int frame;
QQuickImageProviderOptions options;
};
inline bool operator==(const QQuickPixmapKey &lhs, const QQuickPixmapKey &rhs)
{
- return *lhs.size == *rhs.size && *lhs.url == *rhs.url && lhs.options == rhs.options;
+ return *lhs.size == *rhs.size && *lhs.url == *rhs.url && lhs.options == rhs.options && lhs.frame == rhs.frame;
}
inline uint qHash(const QQuickPixmapKey &key)
{
- return qHash(*key.url) ^ (key.size->width()*7) ^ (key.size->height()*17) ^ (key.options.autoTransform() * 0x5c5c5c5c);
+ return qHash(*key.url) ^ (key.size->width()*7) ^ (key.size->height()*17) ^ (key.frame*23) ^ (key.options.autoTransform() * 0x5c5c5c5c);
}
class QQuickPixmapStore : public QObject
@@ -1254,7 +1269,7 @@ void QQuickPixmapData::release()
void QQuickPixmapData::addToCache()
{
if (!inCache) {
- QQuickPixmapKey key = { &url, &requestSize, providerOptions };
+ QQuickPixmapKey key = { &url, &requestSize, frame, providerOptions };
pixmapStore()->m_cache.insert(key, this);
inCache = true;
PIXMAP_PROFILE(pixmapCountChanged<QQuickProfiler::PixmapCacheCountChanged>(
@@ -1265,7 +1280,7 @@ void QQuickPixmapData::addToCache()
void QQuickPixmapData::removeFromCache()
{
if (inCache) {
- QQuickPixmapKey key = { &url, &requestSize, providerOptions };
+ QQuickPixmapKey key = { &url, &requestSize, frame, providerOptions };
pixmapStore()->m_cache.remove(key);
inCache = false;
PIXMAP_PROFILE(pixmapCountChanged<QQuickProfiler::PixmapCacheCountChanged>(
@@ -1273,7 +1288,7 @@ void QQuickPixmapData::removeFromCache()
}
}
-static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, QQmlEngine *engine, const QUrl &url, const QSize &requestSize, const QQuickImageProviderOptions &providerOptions, bool *ok)
+static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, QQmlEngine *engine, const QUrl &url, const QSize &requestSize, const QQuickImageProviderOptions &providerOptions, int frame, bool *ok)
{
if (url.scheme() == QLatin1String("image")) {
QSize readSize;
@@ -1296,7 +1311,7 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q
: provider->requestTexture(imageId(url), &readSize, requestSize);
if (texture) {
*ok = true;
- return new QQuickPixmapData(declarativePixmap, url, texture, readSize, requestSize, providerOptions, QQuickImageProviderOptions::UsePluginDefaultTransform);
+ return new QQuickPixmapData(declarativePixmap, url, texture, readSize, requestSize, providerOptions, QQuickImageProviderOptions::UsePluginDefaultTransform, frame);
}
break;
}
@@ -1307,7 +1322,7 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q
: provider->requestImage(imageId(url), &readSize, requestSize);
if (!image.isNull()) {
*ok = true;
- return new QQuickPixmapData(declarativePixmap, url, QQuickTextureFactory::textureFactoryForImage(image), readSize, requestSize, providerOptions, QQuickImageProviderOptions::UsePluginDefaultTransform);
+ return new QQuickPixmapData(declarativePixmap, url, QQuickTextureFactory::textureFactoryForImage(image), readSize, requestSize, providerOptions, QQuickImageProviderOptions::UsePluginDefaultTransform, frame);
}
break;
}
@@ -1317,7 +1332,7 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q
: provider->requestPixmap(imageId(url), &readSize, requestSize);
if (!pixmap.isNull()) {
*ok = true;
- return new QQuickPixmapData(declarativePixmap, url, QQuickTextureFactory::textureFactoryForImage(pixmap.toImage()), readSize, requestSize, providerOptions, QQuickImageProviderOptions::UsePluginDefaultTransform);
+ return new QQuickPixmapData(declarativePixmap, url, QQuickTextureFactory::textureFactoryForImage(pixmap.toImage()), readSize, requestSize, providerOptions, QQuickImageProviderOptions::UsePluginDefaultTransform, frame);
}
break;
}
@@ -1347,7 +1362,7 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q
QQuickTextureFactory *factory = texReader.read();
if (factory) {
*ok = true;
- return new QQuickPixmapData(declarativePixmap, url, factory, factory->textureSize(), requestSize, providerOptions, QQuickImageProviderOptions::UsePluginDefaultTransform);
+ return new QQuickPixmapData(declarativePixmap, url, factory, factory->textureSize(), requestSize, providerOptions, QQuickImageProviderOptions::UsePluginDefaultTransform, frame);
} else {
errorString = QQuickPixmap::tr("Error decoding: %1").arg(url.toString());
if (f.fileName() != localFile)
@@ -1356,9 +1371,10 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q
} else {
QImage image;
QQuickImageProviderOptions::AutoTransform appliedTransform = providerOptions.autoTransform();
- if (readImage(url, &f, &image, &errorString, &readSize, requestSize, providerOptions, &appliedTransform)) {
+ int frameCount;
+ if (readImage(url, &f, &image, &errorString, &readSize, &frameCount, requestSize, providerOptions, &appliedTransform, frame)) {
*ok = true;
- return new QQuickPixmapData(declarativePixmap, url, QQuickTextureFactory::textureFactoryForImage(image), readSize, requestSize, providerOptions, appliedTransform);
+ return new QQuickPixmapData(declarativePixmap, url, QQuickTextureFactory::textureFactoryForImage(image), readSize, requestSize, providerOptions, appliedTransform, frame, frameCount);
} else if (f.fileName() != localFile) {
errorString += QString::fromLatin1(" (%1)").arg(f.fileName());
}
@@ -1476,6 +1492,13 @@ QQuickImageProviderOptions::AutoTransform QQuickPixmap::autoTransform() const
return QQuickImageProviderOptions::UsePluginDefaultTransform;
}
+int QQuickPixmap::frameCount() const
+{
+ if (d)
+ return d->frameCount;
+ return 0;
+}
+
QQuickTextureFactory *QQuickPixmap::textureFactory() const
{
if (d)
@@ -1554,7 +1577,7 @@ void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QSize &reques
load(engine, url, requestSize, options, QQuickImageProviderOptions());
}
-void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QSize &requestSize, QQuickPixmap::Options options, const QQuickImageProviderOptions &providerOptions)
+void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QSize &requestSize, QQuickPixmap::Options options, const QQuickImageProviderOptions &providerOptions, int frame, int frameCount)
{
if (d) {
d->declarativePixmaps.remove(this);
@@ -1562,7 +1585,7 @@ void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QSize &reques
d = nullptr;
}
- QQuickPixmapKey key = { &url, &requestSize, providerOptions };
+ QQuickPixmapKey key = { &url, &requestSize, frame, providerOptions };
QQuickPixmapStore *store = pixmapStore();
QHash<QQuickPixmapKey, QQuickPixmapData *>::Iterator iter = store->m_cache.end();
@@ -1574,7 +1597,7 @@ void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QSize &reques
QSize dummy;
if (requestSize != dummy)
qWarning() << "Ignoring sourceSize request for image url that came from grabToImage. Use the targetSize parameter of the grabToImage() function instead.";
- const QQuickPixmapKey grabberKey = { &url, &dummy, QQuickImageProviderOptions() };
+ const QQuickPixmapKey grabberKey = { &url, &dummy, 0, QQuickImageProviderOptions() };
iter = store->m_cache.find(grabberKey);
} else if (options & QQuickPixmap::Cache)
iter = store->m_cache.find(key);
@@ -1596,7 +1619,7 @@ void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QSize &reques
if (!(options & QQuickPixmap::Asynchronous)) {
bool ok = false;
PIXMAP_PROFILE(pixmapStateChanged<QQuickProfiler::PixmapLoadingStarted>(url));
- d = createPixmapDataSync(this, engine, url, requestSize, providerOptions, &ok);
+ d = createPixmapDataSync(this, engine, url, requestSize, providerOptions, frame, &ok);
if (ok) {
PIXMAP_PROFILE(pixmapLoadingFinished(url, QSize(width(), height())));
if (options & QQuickPixmap::Cache)
@@ -1613,7 +1636,7 @@ void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QSize &reques
return;
- d = new QQuickPixmapData(this, url, requestSize, providerOptions, QQuickImageProviderOptions::UsePluginDefaultTransform);
+ d = new QQuickPixmapData(this, url, requestSize, providerOptions, QQuickImageProviderOptions::UsePluginDefaultTransform, frame, frameCount);
if (options & QQuickPixmap::Cache)
d->addToCache();
@@ -1647,9 +1670,9 @@ void QQuickPixmap::clear(QObject *obj)
}
}
-bool QQuickPixmap::isCached(const QUrl &url, const QSize &requestSize, const QQuickImageProviderOptions &options)
+bool QQuickPixmap::isCached(const QUrl &url, const QSize &requestSize, const int frame, const QQuickImageProviderOptions &options)
{
- QQuickPixmapKey key = { &url, &requestSize, options };
+ QQuickPixmapKey key = { &url, &requestSize, frame, options };
QQuickPixmapStore *store = pixmapStore();
return store->m_cache.contains(key);
diff --git a/src/quick/util/qquickpixmapcache_p.h b/src/quick/util/qquickpixmapcache_p.h
index 91fb1ed3bb..ab5d391fa2 100644
--- a/src/quick/util/qquickpixmapcache_p.h
+++ b/src/quick/util/qquickpixmapcache_p.h
@@ -150,6 +150,7 @@ public:
const QSize &implicitSize() const;
const QSize &requestSize() const;
QQuickImageProviderOptions::AutoTransform autoTransform() const;
+ int frameCount() const;
QImage image() const;
void setImage(const QImage &);
void setPixmap(const QQuickPixmap &other);
@@ -164,7 +165,7 @@ public:
void load(QQmlEngine *, const QUrl &, QQuickPixmap::Options options);
void load(QQmlEngine *, const QUrl &, const QSize &);
void load(QQmlEngine *, const QUrl &, const QSize &, QQuickPixmap::Options options);
- void load(QQmlEngine *, const QUrl &, const QSize &, QQuickPixmap::Options options, const QQuickImageProviderOptions &providerOptions);
+ void load(QQmlEngine *, const QUrl &, const QSize &, QQuickPixmap::Options options, const QQuickImageProviderOptions &providerOptions, int frame = 0, int frameCount = 1);
void clear();
void clear(QObject *);
@@ -175,7 +176,7 @@ public:
bool connectDownloadProgress(QObject *, int);
static void purgeCache();
- static bool isCached(const QUrl &url, const QSize &requestSize, const QQuickImageProviderOptions &options);
+ static bool isCached(const QUrl &url, const QSize &requestSize, const int frame, const QQuickImageProviderOptions &options);
static const QLatin1String itemGrabberScheme;
diff --git a/src/quick/util/qquickshortcut_p.h b/src/quick/util/qquickshortcut_p.h
index c5d5501cb7..712cca7696 100644
--- a/src/quick/util/qquickshortcut_p.h
+++ b/src/quick/util/qquickshortcut_p.h
@@ -67,8 +67,8 @@ class QQuickShortcut : public QObject, public QQmlParserStatus
Q_INTERFACES(QQmlParserStatus)
Q_PROPERTY(QVariant sequence READ sequence WRITE setSequence NOTIFY sequenceChanged FINAL)
Q_PROPERTY(QVariantList sequences READ sequences WRITE setSequences NOTIFY sequencesChanged FINAL REVISION 9)
- Q_PROPERTY(QString nativeText READ nativeText NOTIFY sequenceChanged FINAL REVISION 1)
- Q_PROPERTY(QString portableText READ portableText NOTIFY sequenceChanged FINAL REVISION 1)
+ Q_PROPERTY(QString nativeText READ nativeText NOTIFY sequenceChanged FINAL REVISION 6)
+ Q_PROPERTY(QString portableText READ portableText NOTIFY sequenceChanged FINAL REVISION 6)
Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged FINAL)
Q_PROPERTY(bool autoRepeat READ autoRepeat WRITE setAutoRepeat NOTIFY autoRepeatChanged FINAL)
Q_PROPERTY(Qt::ShortcutContext context READ context WRITE setContext NOTIFY contextChanged FINAL)
diff --git a/src/quick/util/qquicktransition.cpp b/src/quick/util/qquicktransition.cpp
index c8699426f2..b973309212 100644
--- a/src/quick/util/qquicktransition.cpp
+++ b/src/quick/util/qquicktransition.cpp
@@ -82,13 +82,15 @@ QT_BEGIN_NAMESPACE
values can be set to restrict the animations to only be applied when changing
from one particular state to another.
- To define multiple transitions, specify \l Item::transitions as a list:
+ To define multiple Transitions, specify \l Item::transitions as a list:
\snippet qml/transitions-list.qml list of transitions
- If multiple Transitions are specified, only a single (best-matching) Transition will be applied for any particular
- state change. In the example above, when changing to \c state1, the first transition will be used, rather
- than the more generic second transition.
+ If multiple Transitions are specified, only a single (best-matching)
+ Transition will be applied for any particular state change. In the
+ example above, if the Rectangle enters a state other than \c "middleRight"
+ or \c "bottomLeft", the third Transition will be carried out, meaning the
+ icon will be moved to the starting point.
If a state change has a Transition that matches the same property as a
\l Behavior, the Transition animation overrides the \l Behavior for that
@@ -298,10 +300,11 @@ QQuickTransitionInstance *QQuickTransition::prepare(QQuickStateOperation::Action
\snippet qml/transition-from-to-modified.qml modified transition
- The animation would only be applied when changing from the default state to
- the "brighter" state (i.e. when the mouse is pressed, but not on release).
+ The animation would only be applied when changing from the default state
+ to the "brighter" state (i.e. when the mouse is pressed, but not on release).
- Multiple \c to and \c from values can be set by using a comma-separated string.
+ Multiple \c to and \c from values can be set by using a comma-separated
+ string.
\sa reversible
*/
@@ -323,7 +326,8 @@ void QQuickTransition::setFromState(const QString &f)
/*!
\qmlproperty bool QtQuick::Transition::reversible
- This property holds whether the transition should be automatically reversed when the conditions that triggered this transition are reversed.
+ This property holds whether the transition should be automatically
+ reversed when the conditions that triggered this transition are reversed.
The default value is false.
diff --git a/src/quick/util/qquickutilmodule.cpp b/src/quick/util/qquickutilmodule.cpp
index d222a0c0be..93b6599506 100644
--- a/src/quick/util/qquickutilmodule.cpp
+++ b/src/quick/util/qquickutilmodule.cpp
@@ -99,7 +99,7 @@ void QQuickUtilModule::defineModule()
qmlRegisterType<QQuickVector3dAnimation>("QtQuick",2,0,"Vector3dAnimation");
#if QT_CONFIG(validator)
- qmlRegisterType<QValidator>();
+ qmlRegisterAnonymousType<QValidator>("QtQuick", 2);
qmlRegisterType<QQuickIntValidator>("QtQuick",2,0,"IntValidator");
qmlRegisterType<QQuickDoubleValidator>("QtQuick",2,0,"DoubleValidator");
qmlRegisterType<QRegExpValidator>("QtQuick",2,0,"RegExpValidator");
@@ -117,7 +117,7 @@ void QQuickUtilModule::defineModule()
#if QT_CONFIG(quick_shadereffect) && QT_CONFIG(opengl)
qmlRegisterType<QQuickUniformAnimator>("QtQuick", 2, 2, "UniformAnimator");
#endif
- qmlRegisterType<QQuickStateOperation>();
+ qmlRegisterAnonymousType<QQuickStateOperation>("QtQuick", 2);
qmlRegisterCustomType<QQuickPropertyChanges>("QtQuick",2,0,"PropertyChanges", new QQuickPropertyChangesParser);
@@ -131,7 +131,7 @@ void QQuickUtilModule::defineModule()
#if QT_CONFIG(shortcut)
qmlRegisterType<QQuickShortcut>("QtQuick", 2, 5, "Shortcut");
- qmlRegisterType<QQuickShortcut,1>("QtQuick", 2, 6, "Shortcut");
+ qmlRegisterType<QQuickShortcut,6>("QtQuick", 2, 6, "Shortcut");
qmlRegisterType<QQuickShortcut,9>("QtQuick", 2, 9, "Shortcut");
#endif
diff --git a/src/quickshapes/qquickshape.cpp b/src/quickshapes/qquickshape.cpp
index 04e8de5aa0..c1deb0dced 100644
--- a/src/quickshapes/qquickshape.cpp
+++ b/src/quickshapes/qquickshape.cpp
@@ -201,7 +201,7 @@ void QQuickShapePath::setStrokeColor(const QColor &color)
}
/*!
- \qmlproperty color QtQuick.Shapes::ShapePath::strokeWidth
+ \qmlproperty real QtQuick.Shapes::ShapePath::strokeWidth
This property holds the stroke width.
diff --git a/tests/auto/qml/bindingdependencyapi/dummy_imports.qml b/tests/auto/qml/bindingdependencyapi/dummy_imports.qml
new file mode 100644
index 0000000000..b9a196e188
--- /dev/null
+++ b/tests/auto/qml/bindingdependencyapi/dummy_imports.qml
@@ -0,0 +1,8 @@
+// This file exists for the sole purpose for qmlimportscanner to find
+// which modules it needs to extract for deployment.
+// Otherwise, it fails to find the imports that are expressed in C++
+// code in tst_parserstress.cpp
+
+import QtQuick 2.0
+
+QtObject { } // This is needed in order to keep importscanner happy
diff --git a/tests/auto/qml/qjsengine/dummy_imports.qml b/tests/auto/qml/qjsengine/dummy_imports.qml
new file mode 100644
index 0000000000..8d86f3583b
--- /dev/null
+++ b/tests/auto/qml/qjsengine/dummy_imports.qml
@@ -0,0 +1,8 @@
+// This file exists for the sole purpose for qmlimportscanner to find
+// which modules it needs to extract for deployment.
+// Otherwise, it fails to find the imports that are expressed in C++
+// code in tst_parserstress.cpp
+
+import QtQml 2.0
+
+QtObject { } // This is needed in order to keep importscanner happy
diff --git a/tests/auto/qml/qjsengine/tst_qjsengine.cpp b/tests/auto/qml/qjsengine/tst_qjsengine.cpp
index 0ccb8210bc..1c895eb793 100644
--- a/tests/auto/qml/qjsengine/tst_qjsengine.cpp
+++ b/tests/auto/qml/qjsengine/tst_qjsengine.cpp
@@ -201,7 +201,9 @@ private slots:
void engineForObject();
void intConversion_QTBUG43309();
+#ifdef QT_DEPRECATED
void toFixed();
+#endif
void argumentEvaluationOrder();
@@ -4323,7 +4325,10 @@ void tst_QJSEngine::engineForObject()
QVERIFY(!qjsEngine(&object));
QJSValue wrapper = engine.newQObject(&object);
QQmlEngine::setObjectOwnership(&object, QQmlEngine::CppOwnership);
+ QVERIFY(qjsEngine(&object));
+#ifdef QT_DEPRECATED
QCOMPARE(qjsEngine(&object), wrapper.engine());
+#endif
}
QVERIFY(!qjsEngine(&object));
}
@@ -4338,6 +4343,7 @@ void tst_QJSEngine::intConversion_QTBUG43309()
QCOMPARE(result.toNumber(), 25.0);
}
+#ifdef QT_DEPRECATED
// QTBUG-44039 and QTBUG-43885:
void tst_QJSEngine::toFixed()
{
@@ -4349,6 +4355,7 @@ void tst_QJSEngine::toFixed()
QVERIFY(result.isString());
QCOMPARE(result.toString(), QStringLiteral("12.1"));
}
+#endif
void tst_QJSEngine::argumentEvaluationOrder()
{
diff --git a/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp b/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp
index 4de72ae7a1..37d0ea4dea 100644
--- a/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp
+++ b/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp
@@ -52,7 +52,9 @@ void tst_QJSValue::ctor_invalid()
{
QJSValue v;
QVERIFY(v.isUndefined());
+#ifdef QT_DEPRECATED
QCOMPARE(v.engine(), (QJSEngine *)nullptr);
+#endif
}
}
@@ -63,7 +65,9 @@ void tst_QJSValue::ctor_undefinedWithEngine()
QJSValue v = eng.toScriptValue(QVariant());
QVERIFY(v.isUndefined());
QCOMPARE(v.isObject(), false);
+#ifdef QT_DEPRECATED
QCOMPARE(v.engine(), &eng);
+#endif
}
}
@@ -75,7 +79,9 @@ void tst_QJSValue::ctor_nullWithEngine()
QVERIFY(!v.isUndefined());
QCOMPARE(v.isNull(), true);
QCOMPARE(v.isObject(), false);
+#ifdef QT_DEPRECATED
QCOMPARE(v.engine(), &eng);
+#endif
}
}
@@ -88,7 +94,9 @@ void tst_QJSValue::ctor_boolWithEngine()
QCOMPARE(v.isBool(), true);
QCOMPARE(v.isObject(), false);
QCOMPARE(v.toBool(), false);
+#ifdef QT_DEPRECATED
QCOMPARE(v.engine(), &eng);
+#endif
}
}
@@ -101,7 +109,9 @@ void tst_QJSValue::ctor_intWithEngine()
QCOMPARE(v.isNumber(), true);
QCOMPARE(v.isObject(), false);
QCOMPARE(v.toNumber(), 1.0);
+#ifdef QT_DEPRECATED
QCOMPARE(v.engine(), &eng);
+#endif
}
}
@@ -118,7 +128,9 @@ void tst_QJSValue::ctor_int()
QCOMPARE(v.isNumber(), true);
QCOMPARE(v.isObject(), false);
QCOMPARE(v.toNumber(), 1.0);
+#ifdef QT_DEPRECATED
QCOMPARE(v.engine(), (QJSEngine *)nullptr);
+#endif
}
}
@@ -131,7 +143,9 @@ void tst_QJSValue::ctor_uintWithEngine()
QCOMPARE(v.isNumber(), true);
QCOMPARE(v.isObject(), false);
QCOMPARE(v.toNumber(), 1.0);
+#ifdef QT_DEPRECATED
QCOMPARE(v.engine(), &eng);
+#endif
}
}
@@ -148,7 +162,9 @@ void tst_QJSValue::ctor_uint()
QCOMPARE(v.isNumber(), true);
QCOMPARE(v.isObject(), false);
QCOMPARE(v.toNumber(), 1.0);
+#ifdef QT_DEPRECATED
QCOMPARE(v.engine(), (QJSEngine *)nullptr);
+#endif
}
}
@@ -161,7 +177,9 @@ void tst_QJSValue::ctor_floatWithEngine()
QCOMPARE(v.isNumber(), true);
QCOMPARE(v.isObject(), false);
QCOMPARE(v.toNumber(), 1.0);
+#ifdef QT_DEPRECATED
QCOMPARE(v.engine(), &eng);
+#endif
}
}
@@ -178,7 +196,9 @@ void tst_QJSValue::ctor_float()
QCOMPARE(v.isNumber(), true);
QCOMPARE(v.isObject(), false);
QCOMPARE(v.toNumber(), 1.0);
+#ifdef QT_DEPRECATED
QCOMPARE(v.engine(), (QJSEngine *)nullptr);
+#endif
}
}
@@ -191,7 +211,9 @@ void tst_QJSValue::ctor_stringWithEngine()
QCOMPARE(v.isString(), true);
QCOMPARE(v.isObject(), false);
QCOMPARE(v.toString(), QLatin1String("ciao"));
+#ifdef QT_DEPRECATED
QCOMPARE(v.engine(), &eng);
+#endif
}
}
@@ -203,7 +225,9 @@ void tst_QJSValue::ctor_string()
QCOMPARE(v.isString(), true);
QCOMPARE(v.isObject(), false);
QCOMPARE(v.toString(), QLatin1String("ciao"));
+#ifdef QT_DEPRECATED
QCOMPARE(v.engine(), (QJSEngine *)nullptr);
+#endif
}
{
QJSValue v("ciao");
@@ -211,7 +235,9 @@ void tst_QJSValue::ctor_string()
QCOMPARE(v.isString(), true);
QCOMPARE(v.isObject(), false);
QCOMPARE(v.toString(), QLatin1String("ciao"));
+#ifdef QT_DEPRECATED
QCOMPARE(v.engine(), (QJSEngine *)nullptr);
+#endif
}
}
@@ -223,12 +249,16 @@ void tst_QJSValue::ctor_copyAndAssignWithEngine()
QJSValue v = eng.toScriptValue(1.0);
QJSValue v2(v);
QCOMPARE(v2.strictlyEquals(v), true);
+#ifdef QT_DEPRECATED
QCOMPARE(v2.engine(), &eng);
+#endif
QJSValue v3(v);
QCOMPARE(v3.strictlyEquals(v), true);
QCOMPARE(v3.strictlyEquals(v2), true);
+#ifdef QT_DEPRECATED
QCOMPARE(v3.engine(), &eng);
+#endif
QJSValue v4 = eng.toScriptValue(2.0);
QCOMPARE(v4.strictlyEquals(v), false);
@@ -253,7 +283,9 @@ void tst_QJSValue::ctor_undefined()
QJSValue v(QJSValue::UndefinedValue);
QVERIFY(v.isUndefined());
QCOMPARE(v.isObject(), false);
+#ifdef QT_DEPRECATED
QCOMPARE(v.engine(), (QJSEngine *)nullptr);
+#endif
}
void tst_QJSValue::ctor_null()
@@ -262,7 +294,9 @@ void tst_QJSValue::ctor_null()
QVERIFY(!v.isUndefined());
QCOMPARE(v.isNull(), true);
QCOMPARE(v.isObject(), false);
+#ifdef QT_DEPRECATED
QCOMPARE(v.engine(), (QJSEngine *)nullptr);
+#endif
}
void tst_QJSValue::ctor_bool()
@@ -273,7 +307,9 @@ void tst_QJSValue::ctor_bool()
QCOMPARE(v.isBool(), true);
QCOMPARE(v.isObject(), false);
QCOMPARE(v.toBool(), false);
+#ifdef QT_DEPRECATED
QCOMPARE(v.engine(), (QJSEngine *)nullptr);
+#endif
}
void tst_QJSValue::ctor_copyAndAssign()
@@ -281,12 +317,16 @@ void tst_QJSValue::ctor_copyAndAssign()
QJSValue v(1.0);
QJSValue v2(v);
QCOMPARE(v2.strictlyEquals(v), true);
+#ifdef QT_DEPRECATED
QCOMPARE(v2.engine(), (QJSEngine *)nullptr);
+#endif
QJSValue v3(v);
QCOMPARE(v3.strictlyEquals(v), true);
QCOMPARE(v3.strictlyEquals(v2), true);
+#ifdef QT_DEPRECATED
QCOMPARE(v3.engine(), (QJSEngine *)nullptr);
+#endif
QJSValue v4(2.0);
QCOMPARE(v4.strictlyEquals(v), false);
@@ -423,7 +463,9 @@ void tst_QJSValue::toString()
QCOMPARE(o.toString(), QStringLiteral("[object Object]"));
o = createUnboundValue(o);
+#ifdef QT_DEPRECATED
QVERIFY(!o.engine());
+#endif
QCOMPARE(o.toString(), QStringLiteral("[object Object]"));
}
@@ -435,7 +477,9 @@ void tst_QJSValue::toString()
QCOMPARE(o.toString(), QStringLiteral("1,2,3"));
o = createUnboundValue(o);
+#ifdef QT_DEPRECATED
QVERIFY(!o.engine());
+#endif
QCOMPARE(o.toString(), QStringLiteral("1,2,3"));
}
@@ -1641,10 +1685,14 @@ void tst_QJSValue::getSetProperty()
QCOMPARE(object.property("baz").toNumber(), num.toNumber());
QJSValue strstr = QJSValue("bar");
+#ifdef QT_DEPRECATED
QCOMPARE(strstr.engine(), (QJSEngine *)nullptr);
+#endif
object.setProperty("foo", strstr);
QCOMPARE(object.property("foo").toString(), strstr.toString());
+#ifdef QT_DEPRECATED
QCOMPARE(strstr.engine(), &eng); // the value has been bound to the engine
+#endif
QJSValue numnum = QJSValue(123.0);
object.setProperty("baz", numnum);
@@ -2536,15 +2584,18 @@ void tst_QJSValue::engineDeleted()
delete eng;
QVERIFY(v1.isUndefined());
- QVERIFY(!v1.engine());
QVERIFY(v2.isUndefined());
- QVERIFY(!v2.engine());
QVERIFY(v3.isUndefined());
- QVERIFY(!v3.engine());
QVERIFY(v4.isUndefined());
- QVERIFY(!v4.engine());
QVERIFY(v5.isString()); // was not bound to engine
+
+#ifdef QT_DEPRECATED
+ QVERIFY(!v1.engine());
+ QVERIFY(!v2.engine());
+ QVERIFY(!v3.engine());
+ QVERIFY(!v4.engine());
QVERIFY(!v5.engine());
+#endif
QVERIFY(v3.property("foo").isUndefined());
}
diff --git a/tests/auto/qml/qmldiskcache/dummy_imports.qml b/tests/auto/qml/qmldiskcache/dummy_imports.qml
new file mode 100644
index 0000000000..b9a196e188
--- /dev/null
+++ b/tests/auto/qml/qmldiskcache/dummy_imports.qml
@@ -0,0 +1,8 @@
+// This file exists for the sole purpose for qmlimportscanner to find
+// which modules it needs to extract for deployment.
+// Otherwise, it fails to find the imports that are expressed in C++
+// code in tst_parserstress.cpp
+
+import QtQuick 2.0
+
+QtObject { } // This is needed in order to keep importscanner happy
diff --git a/tests/auto/qml/qmllint/qmllint.pro b/tests/auto/qml/qmllint/qmllint.pro
index b53a6f6877..95470b4085 100644
--- a/tests/auto/qml/qmllint/qmllint.pro
+++ b/tests/auto/qml/qmllint/qmllint.pro
@@ -1,6 +1,11 @@
-TEMPLATE = app
-TARGET = testqmllint
-INCLUDEPATH += .
+CONFIG += testcase
+TARGET = tst_qmllint
+macos:CONFIG -= app_bundle
+
+SOURCES += tst_qmllint.cpp
+
+include (../../shared/util.pri)
+
+TESTDATA = data/*
-SOURCES += main.cpp
QT += testlib
diff --git a/tests/auto/qml/qmllint/main.cpp b/tests/auto/qml/qmllint/tst_qmllint.cpp
index 87b34d83bd..582f146dca 100644
--- a/tests/auto/qml/qmllint/main.cpp
+++ b/tests/auto/qml/qmllint/tst_qmllint.cpp
@@ -30,12 +30,14 @@
#include <QProcess>
#include <QString>
-class TestQmllint: public QObject
+#include <util.h>
+
+class TestQmllint: public QQmlDataTest
{
Q_OBJECT
private Q_SLOTS:
- void initTestCase();
+ void initTestCase() override;
void test();
void test_data();
void testUnqualified();
@@ -48,6 +50,7 @@ private:
void TestQmllint::initTestCase()
{
+ QQmlDataTest::initTestCase();
m_qmllintPath = QLibraryInfo::location(QLibraryInfo::BinariesPath) + QLatin1String("/qmllint");
#ifdef Q_OS_WIN
m_qmllintPath += QLatin1String(".exe");
@@ -80,9 +83,8 @@ void TestQmllint::testUnqualified()
QFETCH(QString, warningMessage);
QFETCH(int, warningLine);
QFETCH(int, warningColumn);
- filename.prepend(QStringLiteral("data/"));
QStringList args;
- args << QStringLiteral("-U") << filename << QStringLiteral("-I") << qmlImportDir;
+ args << QStringLiteral("-U") << testFile(filename) << QStringLiteral("-I") << qmlImportDir;
QProcess process;
process.start(m_qmllintPath, args);
@@ -122,8 +124,7 @@ void TestQmllint::testUnqualifiedNoSpuriousParentWarning()
{
auto qmlImportDir = QLibraryInfo::location(QLibraryInfo::Qml2ImportsPath);
{
- QString filename = QLatin1String("spuriousParentWarning.qml");
- filename.prepend(QStringLiteral("data/"));
+ QString filename = testFile("spuriousParentWarning.qml");
QStringList args;
args << QStringLiteral("-U") << filename << QStringLiteral("-I") << qmlImportDir;
QProcess process;
@@ -133,8 +134,7 @@ void TestQmllint::testUnqualifiedNoSpuriousParentWarning()
QVERIFY(process.exitCode() == 0);
}
{
- QString filename = QLatin1String("nonSpuriousParentWarning.qml");
- filename.prepend(QStringLiteral("data/"));
+ QString filename = testFile("nonSpuriousParentWarning.qml");
QStringList args;
args << QStringLiteral("-U") << filename << QStringLiteral("-I") << qmlImportDir;
QProcess process;
@@ -163,13 +163,12 @@ void TestQmllint::test()
{
QFETCH(QString, filename);
QFETCH(bool, isValid);
- filename = QStringLiteral("data/") + filename;
QStringList args;
- args << QStringLiteral("--silent") << filename;
+ args << QStringLiteral("--silent") << testFile(filename);
bool success = QProcess::execute(m_qmllintPath, args) == 0;
QCOMPARE(success, isValid);
}
QTEST_MAIN(TestQmllint)
-#include "main.moc"
+#include "tst_qmllint.moc"
diff --git a/tests/auto/qml/qqmlapplicationengine/tst_qqmlapplicationengine.cpp b/tests/auto/qml/qqmlapplicationengine/tst_qqmlapplicationengine.cpp
index 8787a43884..0f5eea8b95 100644
--- a/tests/auto/qml/qqmlapplicationengine/tst_qqmlapplicationengine.cpp
+++ b/tests/auto/qml/qqmlapplicationengine/tst_qqmlapplicationengine.cpp
@@ -52,6 +52,7 @@ private slots:
void removeObjectsWhenDestroyed();
void loadTranslation_data();
void loadTranslation();
+ void setInitialProperties();
private:
QString buildDir;
@@ -275,6 +276,23 @@ void tst_qqmlapplicationengine::loadTranslation()
QCOMPARE(rootObject->property("translation").toString(), translation);
}
+void tst_qqmlapplicationengine::setInitialProperties()
+{
+ QQmlApplicationEngine test {};
+ {
+ test.setInitialProperties(QVariantMap{{"success", false}});
+ test.load(testFileUrl("basicTest.qml"));
+ QVERIFY(!test.rootObjects().empty());
+ QCOMPARE(test.rootObjects().first()->property("success").toBool(), false);
+ }
+ {
+ test.setInitialProperties({{"success", true}});
+ test.load(testFileUrl("basicTest.qml"));
+ QCOMPARE(test.rootObjects().size(), 2);
+ QCOMPARE(test.rootObjects().at(1)->property("success").toBool(), true);
+ }
+}
+
QTEST_MAIN(tst_qqmlapplicationengine)
#include "tst_qqmlapplicationengine.moc"
diff --git a/tests/auto/qml/qqmlcomponent/data/allJSONTypes.qml b/tests/auto/qml/qqmlcomponent/data/allJSONTypes.qml
new file mode 100644
index 0000000000..0541c9b104
--- /dev/null
+++ b/tests/auto/qml/qqmlcomponent/data/allJSONTypes.qml
@@ -0,0 +1,9 @@
+import QtQuick 2.14
+
+Item {
+ property int i
+ property bool b
+ property double d
+ property string s
+ property var nothing
+}
diff --git a/tests/auto/qml/qqmlcomponent/data/variantBasedInitialization.qml b/tests/auto/qml/qqmlcomponent/data/variantBasedInitialization.qml
new file mode 100644
index 0000000000..acf08e94d2
--- /dev/null
+++ b/tests/auto/qml/qqmlcomponent/data/variantBasedInitialization.qml
@@ -0,0 +1,21 @@
+import QtQuick 2.14
+
+Item {
+ property int i
+ property bool b
+ property double d
+ property string s
+ property var nothing
+ property url myurl
+ property color c
+ property font myfont
+ property date mydate
+ property point mypoint
+ property size mysize
+ property rect myrect
+ property matrix4x4 matrix
+ property quaternion quat
+ property vector2d vec2
+ property vector3d vec3
+ property vector4d vec4
+}
diff --git a/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp b/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp
index 71d3e8fe5f..79ec507388 100644
--- a/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp
+++ b/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp
@@ -121,6 +121,7 @@ private slots:
void relativeUrl_data();
void relativeUrl();
void setDataNoEngineNoSegfault();
+ void testSetInitialProperties();
private:
QQmlEngine engine;
@@ -667,6 +668,101 @@ void tst_qqmlcomponent::setDataNoEngineNoSegfault()
QVERIFY(!c);
}
+void tst_qqmlcomponent::testSetInitialProperties()
+{
+ QQmlEngine eng;
+ {
+ // JSON based initialization
+ QQmlComponent comp(&eng);
+ comp.loadUrl(testFileUrl("allJSONTypes.qml"));
+ QScopedPointer<QObject> obj { comp.beginCreate(eng.rootContext()) };
+ QVERIFY(obj);
+ comp.setInitialProperties(obj.get(), QVariantMap {
+ {QLatin1String("i"), 42},
+ {QLatin1String("b"), true},
+ {QLatin1String("d"), 3.1416},
+ {QLatin1String("s"), QLatin1String("hello world")},
+ {QLatin1String("nothing"), QVariant::fromValue(nullptr)}
+ });
+ comp.completeCreate();
+ if (!comp.errors().empty())
+ qDebug() << comp.errorString() << comp.errors();
+ QVERIFY(comp.errors().empty());
+ QCOMPARE(obj->property("i"), 42);
+ QCOMPARE(obj->property("b"), true);
+ QCOMPARE(obj->property("d"), 3.1416);
+ QCOMPARE(obj->property("s"), QLatin1String("hello world"));
+ QCOMPARE(obj->property("nothing"), QVariant::fromValue(nullptr));
+ }
+ {
+ // QVariant
+ QQmlComponent comp(&eng);
+ comp.loadUrl(testFileUrl("variantBasedInitialization.qml"));
+ QScopedPointer<QObject> obj { comp.beginCreate(eng.rootContext()) };
+ QVERIFY(obj);
+ QUrl myurl = comp.url();
+ QFont myfont;
+ QDateTime mydate = QDateTime::currentDateTime();
+ QPoint mypoint {1,2};
+ QSizeF mysize {0.5, 0.3};
+ QMatrix4x4 matrix {};
+ QQuaternion quat {5.0f, 0.3f, 0.2f, 0.1f};
+ QVector2D vec2 {2.0f, 3.1f};
+ QVector3D vec3 {1.0f, 2.0, 3.0f};
+ QVector4D vec4 {1.0f, 2.0f, 3.0f, 4.0f};
+#define ASJSON(NAME) {QLatin1String(#NAME), NAME}
+ comp.setInitialProperties(obj.get(), QVariantMap {
+ {QLatin1String("i"), 42},
+ {QLatin1String("b"), true},
+ {QLatin1String("d"), 3.1416},
+ {QLatin1String("s"), QLatin1String("hello world")},
+ {QLatin1String("nothing"), QVariant::fromValue( nullptr)},
+ ASJSON(myurl),
+ ASJSON(myfont),
+ ASJSON(mydate),
+ ASJSON(mypoint),
+ ASJSON(mysize),
+ ASJSON(matrix),
+ ASJSON(quat),
+ ASJSON(vec2), ASJSON(vec3), ASJSON(vec4)
+ });
+#undef ASJSON
+ comp.completeCreate();
+ if (!comp.errors().empty())
+ qDebug() << comp.errorString() << comp.errors();
+ QVERIFY(comp.errors().empty());
+ QCOMPARE(obj->property("i"), 42);
+ QCOMPARE(obj->property("b"), true);
+ QCOMPARE(obj->property("d"), 3.1416);
+ QCOMPARE(obj->property("s"), QLatin1String("hello world"));
+ QCOMPARE(obj->property("nothing"), QVariant::fromValue(nullptr));
+#define COMPARE(NAME) QCOMPARE(obj->property(#NAME), NAME)
+ COMPARE(myurl);
+ COMPARE(myfont);
+ COMPARE(mydate);
+ COMPARE(mypoint);
+ COMPARE(mysize);
+ COMPARE(matrix);
+ COMPARE(quat);
+ COMPARE(vec2);
+ COMPARE(vec3);
+ COMPARE(vec4);
+#undef COMPARE
+
+ }
+ {
+ // createWithInitialProperties: setting a nonexistent property
+ QQmlComponent comp(&eng);
+ comp.loadUrl(testFileUrl("allJSONTypes.qml"));
+ QScopedPointer<QObject> obj {
+ comp.createWithInitialProperties(QVariantMap { {"notThePropertiesYoureLookingFor", 42} })
+ };
+ qDebug() << comp.errorString();
+ QVERIFY(obj);
+ QVERIFY(comp.errorString().contains("Could not set property notThePropertiesYoureLookingFor"));
+ }
+}
+
QTEST_MAIN(tst_qqmlcomponent)
#include "tst_qqmlcomponent.moc"
diff --git a/tests/auto/qml/qv4mm/tst_qv4mm.cpp b/tests/auto/qml/qv4mm/tst_qv4mm.cpp
index 1e34b79954..5d635aa63b 100644
--- a/tests/auto/qml/qv4mm/tst_qv4mm.cpp
+++ b/tests/auto/qml/qv4mm/tst_qv4mm.cpp
@@ -136,7 +136,7 @@ void tst_qv4mm::clearICParent()
// to change this test.
for (uint i = 0; i < 16 * 1024; ++i) {
QV4::Scope scope(&engine);
- QV4::ScopedString s(scope, identifiers->getIndexed(i));
+ QV4::ScopedString s(scope, identifiers->get(i));
QV4::Scoped<QV4::InternalClass> ic(scope, object->internalClass());
QVERIFY(ic->d()->parent != nullptr);
object->deleteProperty(s->toPropertyKey());
diff --git a/tests/auto/quick/qquickborderimage/data/multi.ico b/tests/auto/quick/qquickborderimage/data/multi.ico
new file mode 100644
index 0000000000..b748ceaa29
--- /dev/null
+++ b/tests/auto/quick/qquickborderimage/data/multi.ico
Binary files differ
diff --git a/tests/auto/quick/qquickborderimage/data/multiframe.qml b/tests/auto/quick/qquickborderimage/data/multiframe.qml
new file mode 100644
index 0000000000..8bd32da5a6
--- /dev/null
+++ b/tests/auto/quick/qquickborderimage/data/multiframe.qml
@@ -0,0 +1,8 @@
+import QtQuick 2.14
+
+BorderImage {
+ source: "multi.ico"
+ border { left: 19; top: 19; right: 19; bottom: 19 }
+ width: 160; height: 160
+ horizontalTileMode: BorderImage.Stretch
+}
diff --git a/tests/auto/quick/qquickborderimage/data/multiframeAsync.qml b/tests/auto/quick/qquickborderimage/data/multiframeAsync.qml
new file mode 100644
index 0000000000..059e4becf3
--- /dev/null
+++ b/tests/auto/quick/qquickborderimage/data/multiframeAsync.qml
@@ -0,0 +1,9 @@
+import QtQuick 2.14
+
+BorderImage {
+ source: "multi.ico"
+ asynchronous: true
+ border { left: 19; top: 19; right: 19; bottom: 19 }
+ width: 160; height: 160
+ horizontalTileMode: BorderImage.Stretch
+}
diff --git a/tests/auto/quick/qquickborderimage/tst_qquickborderimage.cpp b/tests/auto/quick/qquickborderimage/tst_qquickborderimage.cpp
index 9292e1886a..dc3a783600 100644
--- a/tests/auto/quick/qquickborderimage/tst_qquickborderimage.cpp
+++ b/tests/auto/quick/qquickborderimage/tst_qquickborderimage.cpp
@@ -46,6 +46,8 @@
#include "../../shared/util.h"
#include "../shared/visualtestutil.h"
+Q_LOGGING_CATEGORY(lcTests, "qt.quick.tests")
+
Q_DECLARE_METATYPE(QQuickImageBase::Status)
class tst_qquickborderimage : public QQmlDataTest
@@ -79,6 +81,8 @@ private slots:
#if QT_CONFIG(opengl)
void borderImageMesh();
#endif
+ void multiFrame_data();
+ void multiFrame();
private:
QQmlEngine engine;
@@ -601,6 +605,67 @@ void tst_qquickborderimage::borderImageMesh()
qPrintable(errorMessage));
}
#endif
+
+void tst_qquickborderimage::multiFrame_data()
+{
+ QTest::addColumn<QString>("qmlfile");
+ QTest::addColumn<bool>("asynchronous");
+
+ QTest::addRow("default") << "multiframe.qml" << false;
+ QTest::addRow("async") << "multiframeAsync.qml" << true;
+}
+
+void tst_qquickborderimage::multiFrame()
+{
+ if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
+ || (QGuiApplication::platformName() == QLatin1String("minimal")))
+ QSKIP("Skipping due to grabWindow not functional on offscreen/minimimal platforms");
+
+ QFETCH(QString, qmlfile);
+ QFETCH(bool, asynchronous);
+ Q_UNUSED(asynchronous)
+
+ QQuickView view(testFileUrl(qmlfile));
+ QQuickBorderImage *image = qobject_cast<QQuickBorderImage*>(view.rootObject());
+ QVERIFY(image);
+ QSignalSpy countSpy(image, SIGNAL(frameCountChanged()));
+ QSignalSpy currentSpy(image, SIGNAL(currentFrameChanged()));
+ if (asynchronous) {
+ QCOMPARE(image->frameCount(), 0);
+ QTRY_COMPARE(image->frameCount(), 4);
+ QCOMPARE(countSpy.count(), 1);
+ } else {
+ QCOMPARE(image->frameCount(), 4);
+ }
+ QCOMPARE(image->currentFrame(), 0);
+ view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+ QCoreApplication::processEvents(); // Process all queued events
+
+ QImage contents = view.grabWindow();
+ if (contents.width() < 160)
+ QSKIP("Skipping due to grabWindow not functional");
+
+ // The middle of the first frame looks blue, approximately qRgba(0x43, 0x7e, 0xd6, 0xff)
+ QColor color = contents.pixelColor(60, 60);
+ qCDebug(lcTests) << "expected bluish color, got" << color;
+ QVERIFY(color.redF() < 0.75);
+ QVERIFY(color.greenF() < 0.75);
+ QVERIFY(color.blueF() > 0.75);
+
+ image->setCurrentFrame(1);
+ QTRY_COMPARE(image->status(), QQuickImageBase::Ready);
+ QCOMPARE(currentSpy.count(), 1);
+ QCOMPARE(image->currentFrame(), 1);
+ contents = view.grabWindow();
+ // The middle of the second frame looks green, approximately qRgba(0x3a, 0xd2, 0x31, 0xff)
+ color = contents.pixelColor(60, 60);
+ qCDebug(lcTests) << "expected greenish color, got" << color;
+ QVERIFY(color.redF() < 0.75);
+ QVERIFY(color.green() > 0.75);
+ QVERIFY(color.blueF() < 0.75);
+}
+
QTEST_MAIN(tst_qquickborderimage)
#include "tst_qquickborderimage.moc"
diff --git a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
index 2314b82e8c..c104eecbcd 100644
--- a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
+++ b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
@@ -874,7 +874,8 @@ void tst_qquickflickable::wheel()
// test a vertical flick
{
QPoint pos(200, 200);
- QWheelEvent event(pos, window->mapToGlobal(pos), QPoint(), QPoint(0,-120), -120, Qt::Vertical, Qt::NoButton, Qt::NoModifier);
+ QWheelEvent event(pos, window->mapToGlobal(pos), QPoint(), QPoint(0,-120),
+ Qt::NoButton, Qt::NoModifier, Qt::NoScrollPhase, false);
event.setAccepted(false);
QGuiApplication::sendEvent(window.data(), &event);
}
@@ -897,7 +898,8 @@ void tst_qquickflickable::wheel()
// test a horizontal flick
{
QPoint pos(200, 200);
- QWheelEvent event(pos, window->mapToGlobal(pos), QPoint(), QPoint(-120,0), -120, Qt::Horizontal, Qt::NoButton, Qt::NoModifier);
+ QWheelEvent event(pos, window->mapToGlobal(pos), QPoint(), QPoint(-120,0),
+ Qt::NoButton, Qt::NoModifier, Qt::NoScrollPhase, false);
event.setAccepted(false);
QGuiApplication::sendEvent(window.data(), &event);
@@ -926,7 +928,8 @@ void tst_qquickflickable::trackpad()
QPoint pos(200, 200);
{
- QWheelEvent event(pos, window->mapToGlobal(pos), QPoint(0,-100), QPoint(0,-120), -120, Qt::Vertical, Qt::NoButton, Qt::NoModifier, Qt::ScrollBegin);
+ QWheelEvent event(pos, window->mapToGlobal(pos), QPoint(0,-100), QPoint(0,-120),
+ Qt::NoButton, Qt::NoModifier, Qt::ScrollBegin, false);
event.setAccepted(false);
QGuiApplication::sendEvent(window.data(), &event);
}
@@ -938,7 +941,8 @@ void tst_qquickflickable::trackpad()
QCOMPARE(flick->contentY(), qreal(0));
{
- QWheelEvent event(pos, window->mapToGlobal(pos), QPoint(-100,0), QPoint(-120,0), -120, Qt::Horizontal, Qt::NoButton, Qt::NoModifier, Qt::ScrollUpdate);
+ QWheelEvent event(pos, window->mapToGlobal(pos), QPoint(-100,0), QPoint(-120,0),
+ Qt::NoButton, Qt::NoModifier, Qt::ScrollUpdate, false);
event.setAccepted(false);
QGuiApplication::sendEvent(window.data(), &event);
}
@@ -947,7 +951,8 @@ void tst_qquickflickable::trackpad()
QCOMPARE(flick->contentY(), qreal(0));
{
- QWheelEvent event(pos, window->mapToGlobal(pos), QPoint(0,0), QPoint(0,0), 0, Qt::Horizontal, Qt::NoButton, Qt::NoModifier, Qt::ScrollEnd);
+ QWheelEvent event(pos, window->mapToGlobal(pos), QPoint(0,0), QPoint(0,0),
+ Qt::NoButton, Qt::NoModifier, Qt::ScrollEnd, false);
event.setAccepted(false);
QGuiApplication::sendEvent(window.data(), &event);
}
diff --git a/tests/auto/quick/qquickimage/data/multi.ico b/tests/auto/quick/qquickimage/data/multi.ico
new file mode 100644
index 0000000000..b748ceaa29
--- /dev/null
+++ b/tests/auto/quick/qquickimage/data/multi.ico
Binary files differ
diff --git a/tests/auto/quick/qquickimage/data/multiframe.qml b/tests/auto/quick/qquickimage/data/multiframe.qml
new file mode 100644
index 0000000000..df70bc784c
--- /dev/null
+++ b/tests/auto/quick/qquickimage/data/multiframe.qml
@@ -0,0 +1,5 @@
+import QtQuick 2.14
+
+Image {
+ source: "multi.ico"
+}
diff --git a/tests/auto/quick/qquickimage/data/multiframeAsync.qml b/tests/auto/quick/qquickimage/data/multiframeAsync.qml
new file mode 100644
index 0000000000..167b4a3e57
--- /dev/null
+++ b/tests/auto/quick/qquickimage/data/multiframeAsync.qml
@@ -0,0 +1,6 @@
+import QtQuick 2.14
+
+Image {
+ source: "multi.ico"
+ asynchronous: true
+}
diff --git a/tests/auto/quick/qquickimage/tst_qquickimage.cpp b/tests/auto/quick/qquickimage/tst_qquickimage.cpp
index 34c18aa64b..abc7cd86bd 100644
--- a/tests/auto/quick/qquickimage/tst_qquickimage.cpp
+++ b/tests/auto/quick/qquickimage/tst_qquickimage.cpp
@@ -97,6 +97,8 @@ private slots:
void highDpiFillModesAndSizes();
void hugeImages();
void urlInterceptor();
+ void multiFrame_data();
+ void multiFrame();
private:
QQmlEngine engine;
@@ -1132,6 +1134,62 @@ void tst_qquickimage::urlInterceptor()
QTRY_COMPARE(object->progress(), 1.0);
}
+void tst_qquickimage::multiFrame_data()
+{
+ QTest::addColumn<QString>("qmlfile");
+ QTest::addColumn<bool>("asynchronous");
+
+ QTest::addRow("default") << "multiframe.qml" << false;
+ QTest::addRow("async") << "multiframeAsync.qml" << true;
+}
+
+void tst_qquickimage::multiFrame()
+{
+ if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
+ || (QGuiApplication::platformName() == QLatin1String("minimal")))
+ QSKIP("Skipping due to grabWindow not functional on offscreen/minimimal platforms");
+
+ QFETCH(QString, qmlfile);
+ QFETCH(bool, asynchronous);
+ Q_UNUSED(asynchronous)
+
+ QQuickView view(testFileUrl(qmlfile));
+ QQuickImage *image = qobject_cast<QQuickImage*>(view.rootObject());
+ QVERIFY(image);
+ QSignalSpy countSpy(image, SIGNAL(frameCountChanged()));
+ QSignalSpy currentSpy(image, SIGNAL(currentFrameChanged()));
+ if (asynchronous) {
+ QCOMPARE(image->frameCount(), 0);
+ QTRY_COMPARE(image->frameCount(), 4);
+ QCOMPARE(countSpy.count(), 1);
+ } else {
+ QCOMPARE(image->frameCount(), 4);
+ }
+ QCOMPARE(image->currentFrame(), 0);
+ view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+
+ QImage contents = view.grabWindow();
+ if (contents.width() < 40)
+ QSKIP("Skipping due to grabWindow not functional");
+ // The first frame is a blue ball, approximately qRgba(0x33, 0x6d, 0xcc, 0xff)
+ QRgb color = contents.pixel(16, 16);
+ QVERIFY(qRed(color) < 0xc0);
+ QVERIFY(qGreen(color) < 0xc0);
+ QVERIFY(qBlue(color) > 0xc0);
+
+ image->setCurrentFrame(1);
+ QTRY_COMPARE(image->status(), QQuickImageBase::Ready);
+ QCOMPARE(currentSpy.count(), 1);
+ QCOMPARE(image->currentFrame(), 1);
+ contents = view.grabWindow();
+ // The second frame is a green ball, approximately qRgba(0x27, 0xc8, 0x22, 0xff)
+ color = contents.pixel(16, 16);
+ QVERIFY(qRed(color) < 0xc0);
+ QVERIFY(qGreen(color) > 0xc0);
+ QVERIFY(qBlue(color) < 0xc0);
+}
+
QTEST_MAIN(tst_qquickimage)
#include "tst_qquickimage.moc"
diff --git a/tests/auto/quick/qquickitem/tst_qquickitem.cpp b/tests/auto/quick/qquickitem/tst_qquickitem.cpp
index 7e132f97b6..b6e40d5117 100644
--- a/tests/auto/quick/qquickitem/tst_qquickitem.cpp
+++ b/tests/auto/quick/qquickitem/tst_qquickitem.cpp
@@ -83,8 +83,8 @@ protected:
event->accept();
++wheelCount;
timestamp = event->timestamp();
- lastWheelEventPos = event->pos();
- lastWheelEventGlobalPos = event->globalPos();
+ lastWheelEventPos = event->position().toPoint();
+ lastWheelEventGlobalPos = event->globalPosition().toPoint();
}
};
@@ -1462,7 +1462,8 @@ void tst_qquickitem::wheelEvent()
QPoint localPoint(width / 2, height / 2);
QPoint globalPoint = window.mapToGlobal(localPoint);
- QWheelEvent event(localPoint, globalPoint, -120, Qt::NoButton, Qt::NoModifier, Qt::Vertical);
+ QWheelEvent event(localPoint, globalPoint, QPoint(0, 0), QPoint(0, -120),
+ Qt::NoButton, Qt::NoModifier, Qt::NoScrollPhase, false);
event.setTimestamp(123456UL);
event.setAccepted(false);
QGuiApplication::sendEvent(&window, &event);
diff --git a/tests/auto/quick/qquicklistview/data/addoncompleted.qml b/tests/auto/quick/qquicklistview/data/addoncompleted.qml
index 57265cb2c0..2341295868 100644
--- a/tests/auto/quick/qquicklistview/data/addoncompleted.qml
+++ b/tests/auto/quick/qquicklistview/data/addoncompleted.qml
@@ -73,6 +73,9 @@ Rectangle {
anchors.fill: parent
model: listModel
objectName: "view"
+ // buffered delegates are created asynchronously
+ // therefore we disable buffering
+ cacheBuffer: 0
delegate: Rectangle {
height: 15
diff --git a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
index bab2ec34f8..08149a1786 100644
--- a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
+++ b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
@@ -8958,6 +8958,7 @@ void tst_QQuickListView::addOnCompleted()
y = 9999999;
} else {
const qreal newY = item->y();
+ QVERIFY(newY != 9999999); // once we could not find an item, we shouldn' find any further ones
QVERIFY2(newY > y, objName.toUtf8().constData());
y = newY;
}
diff --git a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp
index 4215017db3..5844720aa4 100644
--- a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp
+++ b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp
@@ -1519,7 +1519,7 @@ void tst_QQuickMouseArea::onWheel()
QVERIFY(root != nullptr);
QWheelEvent wheelEvent(QPoint(10, 32), QPoint(10, 32), QPoint(60, 20), QPoint(0, 120),
- 0, Qt::Vertical,Qt::NoButton, Qt::ControlModifier);
+ Qt::NoButton, Qt::ControlModifier, Qt::NoScrollPhase, false);
QGuiApplication::sendEvent(&window, &wheelEvent);
QCOMPARE(root->property("angleDeltaY").toInt(), 120);
diff --git a/tests/auto/quick/qquicktext/data/verticallyAlignedImageInTable.qml b/tests/auto/quick/qquicktext/data/verticallyAlignedImageInTable.qml
new file mode 100644
index 0000000000..4c00362d15
--- /dev/null
+++ b/tests/auto/quick/qquicktext/data/verticallyAlignedImageInTable.qml
@@ -0,0 +1,14 @@
+import QtQuick 2.0
+
+Item {
+ width: 320
+ height: 480
+
+ Text {
+ anchors.centerIn: parent
+ font.family: "Arial"
+ font.pixelSize: 16
+ textFormat: Text.RichText
+ text: "<table><tr><td/><td valign=\"top\"><img src=\"images/face-sad.png\"></td></tr></table>"
+ }
+}
diff --git a/tests/auto/quick/qquicktext/tst_qquicktext.cpp b/tests/auto/quick/qquicktext/tst_qquicktext.cpp
index fd0ba0f49b..97107694bd 100644
--- a/tests/auto/quick/qquicktext/tst_qquicktext.cpp
+++ b/tests/auto/quick/qquicktext/tst_qquicktext.cpp
@@ -162,6 +162,8 @@ private slots:
void initialContentHeight();
+ void verticallyAlignedImageInTable();
+
private:
QStringList standard;
QStringList richText;
@@ -4415,6 +4417,18 @@ void tst_qquicktext::implicitSizeChangeRewrap()
QVERIFY(text->contentWidth() < window->width());
}
+void tst_qquicktext::verticallyAlignedImageInTable()
+{
+ QScopedPointer<QQuickView> window(new QQuickView);
+ window->setSource(testFileUrl("verticallyAlignedImageInTable.qml"));
+ QTRY_COMPARE(window->status(), QQuickView::Ready);
+
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window.data()));
+
+ // Don't crash
+}
+
QTEST_MAIN(tst_qquicktext)
#include "tst_qquicktext.moc"
diff --git a/tests/auto/quick/qquickview/tst_qquickview.cpp b/tests/auto/quick/qquickview/tst_qquickview.cpp
index e259ed1ae7..dbce0d308c 100644
--- a/tests/auto/quick/qquickview/tst_qquickview.cpp
+++ b/tests/auto/quick/qquickview/tst_qquickview.cpp
@@ -49,6 +49,7 @@ private slots:
void errors();
void engine();
void findChild();
+ void setInitialProperties();
};
@@ -283,6 +284,17 @@ void tst_QQuickView::findChild()
QVERIFY(!view.rootObject()->findChild<QObject *>("rootObject")); // self
}
+void tst_QQuickView::setInitialProperties()
+{
+ QQuickView view;
+ view.setInitialProperties({{"z", 4}, {"width", 100}});
+ view.setSource(testFileUrl("resizemodeitem.qml"));
+ QObject *rootObject = view.rootObject();
+ QVERIFY(rootObject);
+ QCOMPARE(rootObject->property("z").toInt(), 4);
+ QCOMPARE(rootObject->property("width").toInt(), 100);
+}
+
QTEST_MAIN(tst_QQuickView)
#include "tst_qquickview.moc"
diff --git a/tests/benchmarks/qml/js/qjsengine/tst_qjsengine.cpp b/tests/benchmarks/qml/js/qjsengine/tst_qjsengine.cpp
index d13751385c..cb23d6edbd 100644
--- a/tests/benchmarks/qml/js/qjsengine/tst_qjsengine.cpp
+++ b/tests/benchmarks/qml/js/qjsengine/tst_qjsengine.cpp
@@ -452,7 +452,7 @@ void tst_QJSEngine::installTranslatorFunctions()
{
newEngine();
QBENCHMARK {
- m_engine->installTranslatorFunctions();
+ m_engine->installExtensions(QJSEngine::TranslationExtension);
}
}
@@ -471,7 +471,7 @@ void tst_QJSEngine::translation()
QFETCH(QString, text);
QFETCH(QString, fileName);
newEngine();
- m_engine->installTranslatorFunctions();
+ m_engine->installExtensions(QJSEngine::TranslationExtension);
QBENCHMARK {
(void)m_engine->evaluate(text, fileName);
diff --git a/tests/benchmarks/qml/painting/paintbenchmark.cpp b/tests/benchmarks/qml/painting/paintbenchmark.cpp
index d195675ab8..1500f39c9a 100644
--- a/tests/benchmarks/qml/painting/paintbenchmark.cpp
+++ b/tests/benchmarks/qml/painting/paintbenchmark.cpp
@@ -34,7 +34,7 @@
#include <QGLWidget>
#include <QTextLayout>
#include <QVBoxLayout>
-#include <QTime>
+#include <QElapsedTimer>
#include <QDebug>
#include <QRandomGenerator>
#include <QStaticText>
@@ -328,20 +328,20 @@ public:
}
void paintEvent(QPaintEvent *) {
- static int last = 0;
+ static qint64 last = 0;
static bool firstRun = true;
if (firstRun) {
timer.start();
firstRun = false;
} else {
- int elapsed = timer.elapsed();
+ qint64 elapsed = timer.elapsed();
qDebug() << "frame elapsed:" << elapsed - last;
last = elapsed;
}
QPainter p(this);
p.fillRect(rect(), Qt::white);
p.setPen(Qt::black);
- QTime drawTimer;
+ QElapsedTimer drawTimer;
drawTimer.start();
testFunc(p);
qDebug() << "draw time" << drawTimer.elapsed();
@@ -351,7 +351,7 @@ public:
qApp->quit();
}
- QTime timer;
+ QElapsedTimer timer;
int frames;
};
diff --git a/tests/manual/scenegraph_lancelot/data/text/text_table_vertically_aligned_image.qml b/tests/manual/scenegraph_lancelot/data/text/text_table_vertically_aligned_image.qml
new file mode 100644
index 0000000000..d712f94572
--- /dev/null
+++ b/tests/manual/scenegraph_lancelot/data/text/text_table_vertically_aligned_image.qml
@@ -0,0 +1,14 @@
+import QtQuick 2.0
+
+Item {
+ width: 320
+ height: 480
+
+ Text {
+ anchors.centerIn: parent
+ font.family: "Arial"
+ font.pixelSize: 16
+ textFormat: Text.RichText
+ text: "<table><tr><td/><td valign=\"top\"><img src=\"data/logo.png\"></td></tr></table>"
+ }
+}
diff --git a/tools/qmlcachegen/generateloader.cpp b/tools/qmlcachegen/generateloader.cpp
index 74208a25e2..1c8a5a016a 100644
--- a/tools/qmlcachegen/generateloader.cpp
+++ b/tools/qmlcachegen/generateloader.cpp
@@ -434,7 +434,11 @@ bool generateLoader(const QStringList &compiledFiles, const QStringList &sortedR
}
}
+#if QT_CONFIG(temporaryfile)
QSaveFile f(outputFileName);
+#else
+ QFile f(outputFileName);
+#endif
if (!f.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
*errorString = f.errorString();
return false;
@@ -445,10 +449,12 @@ bool generateLoader(const QStringList &compiledFiles, const QStringList &sortedR
return false;
}
+#if QT_CONFIG(temporaryfile)
if (!f.commit()) {
*errorString = f.errorString();
return false;
}
+#endif
return true;
}
diff --git a/tools/qmlcachegen/qmlcachegen.cpp b/tools/qmlcachegen/qmlcachegen.cpp
index cfbd1cd87d..ac9cf039d3 100644
--- a/tools/qmlcachegen/qmlcachegen.cpp
+++ b/tools/qmlcachegen/qmlcachegen.cpp
@@ -334,7 +334,11 @@ static bool saveUnitAsCpp(const QString &inputFileName, const QString &outputFil
const QV4::CompiledData::SaveableUnitPointer &unit,
QString *errorString)
{
+#if QT_CONFIG(temporaryfile)
QSaveFile f(outputFileName);
+#else
+ QFile f(outputFileName);
+#endif
if (!f.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
*errorString = f.errorString();
return false;
@@ -392,10 +396,12 @@ static bool saveUnitAsCpp(const QString &inputFileName, const QString &outputFil
if (!writeStr("};\n}\n}\n"))
return false;
+#if QT_CONFIG(temporaryfile)
if (!f.commit()) {
*errorString = f.errorString();
return false;
}
+#endif
return true;
}
diff --git a/tools/qmlcachegen/qtquickcompiler.prf b/tools/qmlcachegen/qtquickcompiler.prf
index 24cbe7f2e5..2f98aadefe 100644
--- a/tools/qmlcachegen/qtquickcompiler.prf
+++ b/tools/qmlcachegen/qtquickcompiler.prf
@@ -1,15 +1,5 @@
if(qtc_run|lupdate_run): return()
-!contains(QT, qml) {
- qt_modules = \
- $$replace(QT, -private$, _private) \
- $$replace(QT_PRIVATE, -private$, _private)
- qt_modules = $$resolve_depends(qt_modules, "QT.", ".depends" ".run_depends")
- !contains(qt_modules, qml): \
- error("The qtquickcompiler feature cannot be used without the QML module.")
- unset(qt_modules)
-}
-
qtPrepareTool(QML_CACHEGEN, qmlcachegen, _FILTER)
qtPrepareTool(QMAKE_RCC, rcc, _DEP)
diff --git a/tools/qmlplugindump/main.cpp b/tools/qmlplugindump/main.cpp
index 464f3e8a6b..f0ed1f8ebe 100644
--- a/tools/qmlplugindump/main.cpp
+++ b/tools/qmlplugindump/main.cpp
@@ -100,21 +100,45 @@ static QString enquote(const QString &string)
.replace(QLatin1Char('"'),QLatin1String("\\\"")));
}
-void collectReachableMetaObjects(const QMetaObject *meta, QSet<const QMetaObject *> *metas, bool extended = false)
+struct QmlVersionInfo
{
+ QString pluginImportUri;
+ int majorVersion;
+ int minorVersion;
+};
+
+static bool matchingImportUri(const QQmlType &ty, const QmlVersionInfo& versionInfo) {
+ return (versionInfo.pluginImportUri == ty.module()
+ && (ty.majorVersion() == versionInfo.majorVersion || ty.majorVersion() == -1))
+ || ty.module().isEmpty();
+}
+
+void collectReachableMetaObjects(const QMetaObject *meta, QSet<const QMetaObject *> *metas, const QmlVersionInfo &info, bool extended = false, bool alreadyChangedModule = false)
+{
+ auto ty = QQmlMetaType::qmlType(meta);
if (! meta || metas->contains(meta))
return;
- // dynamic meta objects can break things badly
- // but extended types are usually fine
- const QMetaObjectPrivate *mop = reinterpret_cast<const QMetaObjectPrivate *>(meta->d.data);
- if (extended || !(mop->flags & DynamicMetaObject))
- metas->insert(meta);
+ if (matchingImportUri(ty, info)) {
+ if (!alreadyChangedModule) {
+ // dynamic meta objects can break things badly
+ // but extended types are usually fine
+ const QMetaObjectPrivate *mop = reinterpret_cast<const QMetaObjectPrivate *>(meta->d.data);
+ if (extended || !(mop->flags & DynamicMetaObject))
+ metas->insert(meta);
+ } else if (!ty.module().isEmpty()) { // empty module (e.g. from an attached property) would cause a (false) match; do not warn about them
+ qWarning() << "Circular module dependency cannot be expressed in plugin.qmltypes file"
+ << "Object was:" << meta->className()
+ << ty.module() << info.pluginImportUri;
+ }
+ } else if (!ty.module().isEmpty()) {
+ alreadyChangedModule = true;
+ }
- collectReachableMetaObjects(meta->superClass(), metas);
+ collectReachableMetaObjects(meta->superClass(), metas, info, /*extended=*/ false, alreadyChangedModule);
}
-void collectReachableMetaObjects(QObject *object, QSet<const QMetaObject *> *metas)
+void collectReachableMetaObjects(QObject *object, QSet<const QMetaObject *> *metas, const QmlVersionInfo &info)
{
if (! object)
return;
@@ -122,7 +146,7 @@ void collectReachableMetaObjects(QObject *object, QSet<const QMetaObject *> *met
const QMetaObject *meta = object->metaObject();
if (verbose)
std::cerr << "Processing object " << qPrintable( meta->className() ) << std::endl;
- collectReachableMetaObjects(meta, metas);
+ collectReachableMetaObjects(meta, metas, info);
for (int index = 0; index < meta->propertyCount(); ++index) {
QMetaProperty prop = meta->property(index);
@@ -135,17 +159,18 @@ void collectReachableMetaObjects(QObject *object, QSet<const QMetaObject *> *met
// accessing a member of oo is going to cause a segmentation fault
QObject *oo = QQmlMetaType::toQObject(prop.read(object));
if (oo && !metas->contains(oo->metaObject()))
- collectReachableMetaObjects(oo, metas);
+ collectReachableMetaObjects(oo, metas, info);
currentProperty.clear();
}
}
}
-void collectReachableMetaObjects(QQmlEnginePrivate *engine, const QQmlType &ty, QSet<const QMetaObject *> *metas)
+void collectReachableMetaObjects(QQmlEnginePrivate *engine, const QQmlType &ty, QSet<const QMetaObject *> *metas, const QmlVersionInfo& info)
{
- collectReachableMetaObjects(ty.baseMetaObject(), metas, ty.isExtendedType());
- if (ty.attachedPropertiesType(engine))
- collectReachableMetaObjects(ty.attachedPropertiesType(engine), metas);
+ collectReachableMetaObjects(ty.baseMetaObject(), metas, info, ty.isExtendedType());
+ if (ty.attachedPropertiesType(engine) && matchingImportUri(ty, info)) {
+ collectReachableMetaObjects(ty.attachedPropertiesType(engine), metas, info);
+ }
}
/* We want to add the MetaObject for 'Qt' to the list, this is a
@@ -205,13 +230,13 @@ QByteArray convertToId(const QMetaObject *mo)
// Collect all metaobjects for types registered with qmlRegisterType() without parameters
void collectReachableMetaObjectsWithoutQmlName(QQmlEnginePrivate *engine, QSet<const QMetaObject *>& metas,
- QMap<QString, QSet<QQmlType>> &compositeTypes) {
+ QMap<QString, QSet<QQmlType>> &compositeTypes, const QmlVersionInfo &info) {
const auto qmlAllTypes = QQmlMetaType::qmlAllTypes();
for (const QQmlType &ty : qmlAllTypes) {
if (!metas.contains(ty.baseMetaObject())) {
if (!ty.isComposite()) {
- collectReachableMetaObjects(engine, ty, &metas);
- } else {
+ collectReachableMetaObjects(engine, ty, &metas, info);
+ } else if (matchingImportUri(ty, info)) {
compositeTypes[ty.elementName()].insert(ty);
}
}
@@ -222,20 +247,24 @@ QSet<const QMetaObject *> collectReachableMetaObjects(QQmlEngine *engine,
QSet<const QMetaObject *> &noncreatables,
QSet<const QMetaObject *> &singletons,
QMap<QString, QSet<QQmlType>> &compositeTypes,
- const QList<QQmlType> &skip = QList<QQmlType>())
+ const QmlVersionInfo &info,
+ const QList<QQmlType> &skip = QList<QQmlType>()
+ )
{
QSet<const QMetaObject *> metas;
metas.insert(FriendlyQObject::qtMeta());
const auto qmlTypes = QQmlMetaType::qmlTypes();
for (const QQmlType &ty : qmlTypes) {
+ if (!matchingImportUri(ty,info))
+ continue;
if (!ty.isCreatable())
noncreatables.insert(ty.baseMetaObject());
if (ty.isSingleton())
singletons.insert(ty.baseMetaObject());
if (!ty.isComposite()) {
qmlTypesByCppName[ty.baseMetaObject()->className()].insert(ty);
- collectReachableMetaObjects(QQmlEnginePrivate::get(engine), ty, &metas);
+ collectReachableMetaObjects(QQmlEnginePrivate::get(engine), ty, &metas, info);
} else {
compositeTypes[ty.elementName()].insert(ty);
}
@@ -245,6 +274,8 @@ QSet<const QMetaObject *> collectReachableMetaObjects(QQmlEngine *engine,
// find even more QMetaObjects by instantiating QML types and running
// over the instances
for (const QQmlType &ty : qmlTypes) {
+ if (!matchingImportUri(ty, info))
+ continue;
if (skip.contains(ty))
continue;
if (ty.isExtendedType())
@@ -274,7 +305,7 @@ QSet<const QMetaObject *> collectReachableMetaObjects(QQmlEngine *engine,
if (verbose)
std::cerr << "Trying to get singleton for " << qPrintable(tyName)
<< " (" << qPrintable( siinfo->typeName ) << ")" << std::endl;
- collectReachableMetaObjects(object, &metas);
+ collectReachableMetaObjects(object, &metas, info);
object = QQmlEnginePrivate::get(engine)->singletonInstance<QObject*>(ty);
} else {
inObjectInstantiation.clear();
@@ -293,7 +324,7 @@ QSet<const QMetaObject *> collectReachableMetaObjects(QQmlEngine *engine,
if (verbose)
std::cerr << "Got " << qPrintable( tyName )
<< " (" << qPrintable( QString::fromUtf8(ty.typeName()) ) << ")" << std::endl;
- collectReachableMetaObjects(object, &metas);
+ collectReachableMetaObjects(object, &metas, info);
object->deleteLater();
} else {
std::cerr << "Could not create " << qPrintable(tyName) << std::endl;
@@ -301,7 +332,7 @@ QSet<const QMetaObject *> collectReachableMetaObjects(QQmlEngine *engine,
}
}
- collectReachableMetaObjectsWithoutQmlName(QQmlEnginePrivate::get(engine), metas, compositeTypes);
+ collectReachableMetaObjectsWithoutQmlName(QQmlEnginePrivate::get(engine), metas, compositeTypes, info);
return metas;
}
@@ -1186,11 +1217,7 @@ int main(int argc, char *argv[])
QSet<const QMetaObject *> uncreatableMetas;
QSet<const QMetaObject *> singletonMetas;
QMap<QString, QSet<QQmlType>> defaultCompositeTypes;
- QSet<const QMetaObject *> defaultReachable = collectReachableMetaObjects(&engine, uncreatableMetas, singletonMetas, defaultCompositeTypes);
- QList<QQmlType> defaultTypes = QQmlMetaType::qmlTypes();
- // add some otherwise unreachable QMetaObjects
- defaultReachable.insert(&QQuickMouseEvent::staticMetaObject);
// QQuickKeyEvent, QQuickPinchEvent, QQuickDropEvent are not exported
QSet<QByteArray> defaultReachableNames;
@@ -1200,35 +1227,25 @@ int main(int argc, char *argv[])
// composite types we want to dump information of
QMap<QString, QSet<QQmlType>> compositeTypes;
+ int majorVersion = qtQmlMajorVersion, minorVersion = qtQmlMinorVersion;
if (action == Builtins) {
- for (const QMetaObject *m : qAsConst(defaultReachable)) {
- if (m->className() == QLatin1String("Qt")) {
- metas.insert(m);
- break;
- }
- }
- } else if (pluginImportUri == QLatin1String("QtQml")) {
- bool ok = false;
- const uint major = pluginImportVersion.splitRef('.').at(0).toUInt(&ok, 10);
- if (!ok) {
- std::cerr << "Malformed version string \""<< qPrintable(pluginImportVersion) << "\"."
- << std::endl;
- return EXIT_INVALIDARGUMENTS;
- }
- if (major != qtQmlMajorVersion) {
- std::cerr << "Unsupported version \"" << qPrintable(pluginImportVersion)
- << "\": Major version number must be \"" << qtQmlMajorVersion << "\"."
- << std::endl;
- return EXIT_INVALIDARGUMENTS;
- }
- metas = defaultReachable;
- for (const QMetaObject *m : qAsConst(defaultReachable)) {
- if (m->className() == QLatin1String("Qt")) {
- metas.remove(m);
- break;
- }
- }
+ QSet<const QMetaObject *> builtins = collectReachableMetaObjects(&engine, uncreatableMetas, singletonMetas, defaultCompositeTypes, {QLatin1String("Qt"), majorVersion, minorVersion});
+ Q_ASSERT(builtins.size() == 1);
+ metas.insert(*builtins.begin());
} else {
+ auto versionSplitted = pluginImportVersion.split(".");
+ bool ok = versionSplitted.size() == 2;
+ if (!ok)
+ qCritical("Invalid version number");
+ else {
+ majorVersion = versionSplitted.at(0).toInt(&ok);
+ if (!ok)
+ qCritical("Invalid major version");
+ minorVersion = versionSplitted.at(1).toInt(&ok);
+ if (!ok)
+ qCritical("Invalid minor version");
+ }
+ QList<QQmlType> defaultTypes = QQmlMetaType::qmlTypes();
// find a valid QtQuick import
QByteArray importCode;
QQmlType qtObjectType = QQmlMetaType::qmlType(&QObject::staticMetaObject);
@@ -1273,8 +1290,7 @@ int main(int argc, char *argv[])
}
}
- QSet<const QMetaObject *> candidates = collectReachableMetaObjects(&engine, uncreatableMetas, singletonMetas, compositeTypes, defaultTypes);
- candidates.subtract(defaultReachable);
+ QSet<const QMetaObject *> candidates = collectReachableMetaObjects(&engine, uncreatableMetas, singletonMetas, compositeTypes, {pluginImportUri, majorVersion, minorVersion}, defaultTypes);
for (QString iter: compositeTypes.keys()) {
if (defaultCompositeTypes.contains(iter)) {
@@ -1284,13 +1300,8 @@ int main(int argc, char *argv[])
}
}
- // Also eliminate meta objects with the same classname.
- // This is required because extended objects seem not to share
- // a single meta object instance.
- for (const QMetaObject *mo : qAsConst(defaultReachable))
- defaultReachableNames.insert(QByteArray(mo->className()));
for (const QMetaObject *mo : qAsConst(candidates)) {
- if (!defaultReachableNames.contains(mo->className()))
+ if (mo->className() != QLatin1String("Qt"))
metas.insert(mo);
}
}