aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick
diff options
context:
space:
mode:
authorMorten Johan Sørvig <morten.sorvig@qt.io>2018-05-11 10:24:18 +0200
committerMorten Johan Sørvig <morten.sorvig@qt.io>2018-05-11 11:13:04 +0200
commit809d305f938177cfb8488dc7fbfc28bc8eef9d20 (patch)
treed43688a9a3ef61af95c91bae3de8b00e6466c817 /src/quick
parentb742bf9415b42c6e34fab91d2f407eb23dc8e0da (diff)
parent1e82f11629e5572783e5bfc36f24ad10c235ca53 (diff)
Merge remote-tracking branch 'origin/5.11.0' into wip/webassembly
Diffstat (limited to 'src/quick')
-rw-r--r--src/quick/configure.json8
-rw-r--r--src/quick/designer/qquickdesignercustomobjectdata.cpp12
-rw-r--r--src/quick/designer/qquickdesignersupportitems.cpp13
-rw-r--r--src/quick/designer/qquickdesignersupportproperties.cpp11
-rw-r--r--src/quick/doc/QtQuickDoc2
-rw-r--r--src/quick/doc/images/qtquickcontrols2-gallery-welcome.pngbin0 -> 20138 bytes
-rw-r--r--src/quick/doc/qtquick.qdocconf4
-rw-r--r--src/quick/doc/snippets/qml/image-ext.qml68
-rw-r--r--src/quick/doc/src/concepts/effects/particles.qdoc6
-rw-r--r--src/quick/doc/src/concepts/effects/sprites.qdoc60
-rw-r--r--src/quick/doc/src/concepts/layouts/qtquicklayouts-index.qdoc9
-rw-r--r--src/quick/doc/src/concepts/layouts/qtquicklayouts-overview.qdoc2
-rw-r--r--src/quick/doc/src/concepts/layouts/qtquicklayouts.qdoc4
-rw-r--r--src/quick/doc/src/guidelines/qtquick-bestpractices.qdoc428
-rw-r--r--src/quick/doc/src/guidelines/qtquick-toolsnutilities.qdoc113
-rw-r--r--src/quick/doc/src/qmltypereference.qdoc10
-rw-r--r--src/quick/doc/src/qtquick.qdoc1
-rw-r--r--src/quick/handlers/qquickpointerhandler.cpp10
-rw-r--r--src/quick/handlers/qquickpointerhandler_p.h8
-rw-r--r--src/quick/items/qquickanimatedsprite.cpp32
-rw-r--r--src/quick/items/qquickevents_p_p.h1
-rw-r--r--src/quick/items/qquickflickable.cpp10
-rw-r--r--src/quick/items/qquickimage.cpp46
-rw-r--r--src/quick/items/qquickitemgrabresult.cpp2
-rw-r--r--src/quick/items/qquickloader.cpp9
-rw-r--r--src/quick/items/qquicksprite.cpp4
-rw-r--r--src/quick/items/qquickspritesequence.cpp24
-rw-r--r--src/quick/items/qquicktext.cpp4
-rw-r--r--src/quick/items/qquickwindow.cpp12
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode.cpp14
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode_p.h1
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarelayer.cpp4
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer.cpp2
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp2
-rw-r--r--src/quick/scenegraph/qsgdefaultglyphnode_p.cpp4
-rw-r--r--src/quick/scenegraph/qsgrenderloop.cpp5
-rw-r--r--src/quick/util/qquickimageprovider.cpp9
37 files changed, 848 insertions, 106 deletions
diff --git a/src/quick/configure.json b/src/quick/configure.json
index 7004ea7f7b..b77ea863b3 100644
--- a/src/quick/configure.json
+++ b/src/quick/configure.json
@@ -79,6 +79,7 @@
"label": "GridView item",
"purpose": "Provides the GridView item.",
"section": "Qt Quick",
+ "condition": "features.qml-delegate-model",
"output": [
"privateFeature"
]
@@ -101,6 +102,7 @@
"label": "ListView item",
"purpose": "Provides the ListView item.",
"section": "Qt Quick",
+ "condition": "features.qml-delegate-model",
"output": [
"privateFeature"
]
@@ -126,7 +128,10 @@
"label": "PathView item",
"purpose": "Provides the PathView item.",
"section": "Qt Quick",
- "condition": "features.quick-path",
+ "condition": [
+ "features.qml-delegate-model",
+ "features.quick-path"
+ ],
"output": [
"privateFeature"
]
@@ -143,6 +148,7 @@
"label": "Repeater item",
"purpose": "Provides the Repeater item.",
"section": "Qt Quick",
+ "condition": "features.qml-delegate-model",
"output": [
"privateFeature"
]
diff --git a/src/quick/designer/qquickdesignercustomobjectdata.cpp b/src/quick/designer/qquickdesignercustomobjectdata.cpp
index 59e086b5a3..8989de711e 100644
--- a/src/quick/designer/qquickdesignercustomobjectdata.cpp
+++ b/src/quick/designer/qquickdesignercustomobjectdata.cpp
@@ -148,7 +148,19 @@ void QQuickDesignerCustomObjectData::populateResetHashes()
const QQuickDesignerSupport::PropertyNameList propertyNameList =
QQuickDesignerSupportProperties::propertyNameListForWritableProperties(object());
+ const QMetaObject *mo = object()->metaObject();
+ QByteArrayList deferredPropertyNames;
+ const int namesIndex = mo->indexOfClassInfo("DeferredPropertyNames");
+ if (namesIndex != -1) {
+ QMetaClassInfo classInfo = mo->classInfo(namesIndex);
+ deferredPropertyNames = QByteArray(classInfo.value()).split(',');
+ }
+
for (const QQuickDesignerSupport::PropertyName &propertyName : propertyNameList) {
+
+ if (deferredPropertyNames.contains(propertyName))
+ continue;
+
QQmlProperty property(object(), QString::fromUtf8(propertyName), QQmlEngine::contextForObject(object()));
QQmlAbstractBinding::Ptr binding = QQmlAbstractBinding::Ptr(QQmlPropertyPrivate::binding(property));
diff --git a/src/quick/designer/qquickdesignersupportitems.cpp b/src/quick/designer/qquickdesignersupportitems.cpp
index 9fadbb2122..1c338fa79d 100644
--- a/src/quick/designer/qquickdesignersupportitems.cpp
+++ b/src/quick/designer/qquickdesignersupportitems.cpp
@@ -94,11 +94,24 @@ static void allSubObjects(QObject *object, QObjectList &objectList)
objectList.append(object);
+ const QMetaObject *mo = object->metaObject();
+
+ QByteArrayList deferredPropertyNames;
+ const int namesIndex = mo->indexOfClassInfo("DeferredPropertyNames");
+ if (namesIndex != -1) {
+ QMetaClassInfo classInfo = mo->classInfo(namesIndex);
+ deferredPropertyNames = QByteArray(classInfo.value()).split(',');
+ }
+
for (int index = QObject::staticMetaObject.propertyOffset();
index < object->metaObject()->propertyCount();
index++) {
+
QMetaProperty metaProperty = object->metaObject()->property(index);
+ if (deferredPropertyNames.contains(metaProperty.name()))
+ continue;
+
// search recursive in property objects
if (metaProperty.isReadable()
&& metaProperty.isWritable()
diff --git a/src/quick/designer/qquickdesignersupportproperties.cpp b/src/quick/designer/qquickdesignersupportproperties.cpp
index 674f811f8f..c746f55daa 100644
--- a/src/quick/designer/qquickdesignersupportproperties.cpp
+++ b/src/quick/designer/qquickdesignersupportproperties.cpp
@@ -202,11 +202,20 @@ QQuickDesignerSupport::PropertyNameList QQuickDesignerSupportProperties::allProp
const QMetaObject *metaObject = object->metaObject();
+
+ QStringList deferredPropertyNames;
+ const int namesIndex = metaObject->indexOfClassInfo("DeferredPropertyNames");
+ if (namesIndex != -1) {
+ QMetaClassInfo classInfo = metaObject->classInfo(namesIndex);
+ deferredPropertyNames = QString::fromUtf8(classInfo.value()).split(QLatin1Char(','));
+ }
+
for (int index = 0; index < metaObject->propertyCount(); ++index) {
QMetaProperty metaProperty = metaObject->property(index);
QQmlProperty declarativeProperty(object, QString::fromUtf8(metaProperty.name()));
if (declarativeProperty.isValid() && declarativeProperty.propertyTypeCategory() == QQmlProperty::Object) {
- if (declarativeProperty.name() != QLatin1String("parent")) {
+ if (declarativeProperty.name() != QLatin1String("parent")
+ && !deferredPropertyNames.contains(declarativeProperty.name())) {
QObject *childObject = QQmlMetaType::toQObject(declarativeProperty.read());
if (childObject)
propertyNameList.append(allPropertyNames(childObject,
diff --git a/src/quick/doc/QtQuickDoc b/src/quick/doc/QtQuickDoc
new file mode 100644
index 0000000000..6c151f2ebd
--- /dev/null
+++ b/src/quick/doc/QtQuickDoc
@@ -0,0 +1,2 @@
+#include <QtQuick/QtQuick>
+#include <QtQuickWidgets/QtQuickWidgets>
diff --git a/src/quick/doc/images/qtquickcontrols2-gallery-welcome.png b/src/quick/doc/images/qtquickcontrols2-gallery-welcome.png
new file mode 100644
index 0000000000..e69e7e46a7
--- /dev/null
+++ b/src/quick/doc/images/qtquickcontrols2-gallery-welcome.png
Binary files differ
diff --git a/src/quick/doc/qtquick.qdocconf b/src/quick/doc/qtquick.qdocconf
index 7ce0dfcf09..c137d1d2c8 100644
--- a/src/quick/doc/qtquick.qdocconf
+++ b/src/quick/doc/qtquick.qdocconf
@@ -6,6 +6,10 @@ version = $QT_VERSION
examplesinstallpath = quick
+# Custom module header that pulls in also QtQuickWidgets
+moduleheader = QtQuickDoc
+includepaths = -I .
+
qhp.projects = QtQuick
qhp.QtQuick.file = qtquick.qhp
diff --git a/src/quick/doc/snippets/qml/image-ext.qml b/src/quick/doc/snippets/qml/image-ext.qml
new file mode 100644
index 0000000000..5e95f2b4cf
--- /dev/null
+++ b/src/quick/doc/snippets/qml/image-ext.qml
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation 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$
+**
+****************************************************************************/
+
+//! [ext]
+// Assuming the "pics" directory contains the following files:
+// dog.jpg
+// cat.png
+// cat.pkm
+
+Image {
+ source: "pics/cat.png" // loads cat.png
+}
+
+Image {
+ source: "pics/dog" // loads dog.jpg
+}
+
+Image {
+ source: "pics/cat" // normally loads cat.pkm, but if no OpenGL, loads cat.png instead.
+}
+//! [ext]
diff --git a/src/quick/doc/src/concepts/effects/particles.qdoc b/src/quick/doc/src/concepts/effects/particles.qdoc
index 0de0aa93ad..59f9c0db83 100644
--- a/src/quick/doc/src/concepts/effects/particles.qdoc
+++ b/src/quick/doc/src/concepts/effects/particles.qdoc
@@ -26,14 +26,14 @@
****************************************************************************/
/*!
- \qmlmodule QtQuick.Particles 2
+ \qmlmodule QtQuick.Particles 2.11
\title Qt Quick Particles QML Types
\ingroup qmlmodules
\brief Provides QML types for particle effects
This QML module contains a particle system for Qt Quick. To use these types, import the module with the following line:
\code
- import QtQuick.Particles 2.0
+ import QtQuick.Particles 2.11
\endcode
For a simple overview of how the system can be used, see \l{Using the Qt Quick Particle System}.
@@ -50,7 +50,7 @@
Note that to use types from the particles module, you will need to import the types with the following line:
\code
- import QtQuick.Particles 2.0
+ import QtQuick.Particles 2.11
\endcode
\section1 The ParticleSystem
diff --git a/src/quick/doc/src/concepts/effects/sprites.qdoc b/src/quick/doc/src/concepts/effects/sprites.qdoc
index cb4d7e2ac6..004db90eb3 100644
--- a/src/quick/doc/src/concepts/effects/sprites.qdoc
+++ b/src/quick/doc/src/concepts/effects/sprites.qdoc
@@ -52,38 +52,38 @@ This allows you to easily insert a transitional animation between two different
\image spriteenginegraph.png
As an example, consider the above diagram which illustrates the sprites for a hypothetical 2D
-platform game character. The character starts by displaying the standing state. From this state,
-barring external input, he will transition to either the waiting animation, the walking animation,
-or play the standing animation again. Because the weights for those transitions are one, zero and three
-respectively, he has a one in four chance of playing the waiting animation when the standing animation
-finishes, and a three in four chance of playing the standing animation again. This allows for a character
+platform game character. The character starts by displaying the \e standing state. From this state,
+barring external input, he will transition to either the \e waiting animation, the \e walking animation,
+or play the \e standing animation again. Because the weights for those transitions are one, zero and three
+respectively, he has a one in four chance of playing the \e waiting animation when the \e standing animation
+finishes, and a three in four chance of playing the \e standing animation again. This allows for a character
who has a slightly animated and variable behavior while waiting.
-Because there is a zero weight transition to the walking animation, the standing animation will not normally
-transition there. But if you set the goal animation to be the walking animation, it would play the walking
-animation when it finished the standing animation. If it was previously in the waiting animation, it would
-finish playing that, then play the standing animation, then play the walking animation. It would then continue to
-play the walking animation until the goal animation is unset, at which point it would switch to the standing
-animation after finishing the walking animation.
-
-If you set the goal state then to the jumping animation, it would finish the walking animation before
-playing the jumping animation. Because the jumping animation does not transition to other states, it will still
-keep playing the jumping animation until the state is forced to change. In this example, you could set it back to
-walking and change to goal animation to walking or to nothing (which would lead it to play the standing animation
-after the walking animation). Note that by forcibly setting the animation, you can start playing the animation
+Because there is a zero weight transition to the \e walking animation, the \e standing animation will not normally
+transition there. But if you set the goal animation to be the \e walking animation, it would play the \e walking
+animation when it finished the \e standing animation. If it was previously in the \e waiting animation, it would
+finish playing that, then play the \e standing animation, then play the \e walking animation. It would then continue to
+play the \e walking animation until the goal animation is unset, at which point it would switch to the \e standing
+animation after finishing the \e walking animation.
+
+If you then set the goal state to the \e jumping animation, it would finish the \e walking animation before
+playing the \e jumping animation. Because the \e jumping animation does not transition to other states, it will still
+keep playing the \e jumping animation until the state is forced to change. In this example, you could set it back to
+\e walking and change the goal animation to \e walking or to nothing (which would lead it to play the \e standing animation
+after the \e walking animation). Note that by forcibly setting the animation, you can start playing the animation
immediately.
\section2 Input Format
-The file formats accepted by the sprite engine is the same as the file formats accepted by other QML types,
-such as \l Image. In order to animate the image however, the sprite engine requires the image file to contain
+The file formats accepted by the sprite engine are the same as the file formats accepted by other QML types,
+such as \l Image. In order to animate the image, however, the sprite engine requires the image file to contain
all of the frames of the animation. They should be arranged in a contiguous line, which may wrap from the right
edge of the file to a lower row starting from the left edge of the file (and which is placed directly below the
previous row).
\image spritecutting.png
-As an example, take the above image. For now just consider the black numbers, and assume the squares are 40x40 pixels.
+As an example, take the above image. For now, just consider the black numbers, and assume the squares are 40x40 pixels.
Normally, the image is read from the top-left corner. If you specified the frame size as 40x40 pixels, and a frame count
of 8, then it would read in the frames as they are numbered. The frame in the top left would be the first frame, the frame
in the top right would be the fifth frame, and then it would wrap to the next row (at pixel location 0,40 in the file) to read
@@ -97,9 +97,9 @@ The first 120x40 of the image will not be used, as it starts reading 40x40 block
When it reaches the end of the file at 160,0, it then starts to read the next row from 0,40.
The blue numbers show the frame numbers if you tried to load two frames of that size, starting from 40,40. Note
-that it is possible to load multiple sprites out of the one image file. The red, blue and black numbers can all
+that it is possible to load multiple sprites from one image file. The red, blue and black numbers can all
be loaded as separate animations to the same sprite engine. The following code loads the animations as per the image.
-It also specifies that animations are to played at 20 frames per second.
+It also specifies that animations are to be played at 20 frames per second.
\code
Sprite {
@@ -131,17 +131,17 @@ Sprite {
}
\endcode
-Frames within one animation must be the same size, however multiple animations within the same file
-do not. Sprites without a frameCount specified assume that they take the entire file, and you must specify
+Frames within one animation must be the same size. However, multiple animations within the same file
+do not. Sprites without a \l {Sprite::}{frameCount} specified assume that they take the entire file, and you must specify
the frame size. Sprites without a frame size assume that they are square and take the entire file without wrapping,
and you must specify a frame count.
-The sprite engine internally copies and cuts up images to fit in an easier to read internal format, which leads
+The sprite engine internally copies and cuts up images to fit in an easier-to-read internal format, which leads
to some graphics memory limitations. Because it requires all the sprites for a single engine to be in the same
texture, attempting to load many different animations can run into texture memory limits on embedded devices. In
these situations, a warning will be output to the console containing the maximum texture size.
-There are several tools to help turn a set of images into sprite sheets, here are some examples:
+There are several tools to help turn a set of images into sprite sheets. Here are some examples:
\list
\li Photoshop plugin: \l http://www.johnwordsworth.com/projects/photoshop-sprite-sheet-generator-script
\li Gimp plugin: \l http://registry.gimp.org/node/20943
@@ -150,23 +150,23 @@ There are several tools to help turn a set of images into sprite sheets, here ar
\section2 QML Types Using the Sprite Engine
-Sprites for the sprite engine can be defined using the \l Sprite type. This type includes the input parameters
+Sprites for the sprite engine can be defined using the \l Sprite type. This type includes the input parameters,
as well as the length of the animation and weighted transitions to other animations. It is purely a data class, and
does not render anything.
\l SpriteSequence is a type which uses a sprite engine to draw the sprites defined in it. It is a single and
self-contained sprite engine, and does not interact with other sprite engines. \l Sprite types can be shared between
-sprite engine using types, but this is not done automatically. So if you have defined a sprite in one \l SpriteSequence
+sprite engine-using types, but this is not done automatically. So, if you have defined a sprite in one \l SpriteSequence
you will need to redefine it (or reference the same \l Sprite type) in the sprites property of another \l SpriteSequence
in order to transition to that animation.
Additionally, \l ImageParticle can use \l Sprite types to define sprites for each particle. This is again a single
-sprite engine per type. This works similarly to SpriteSequence, but it also has the parametrized variability provided
+sprite engine per type. This works similarly to \c SpriteSequence, but it also has the parameterized variability provided
by the \l ImageParticle type.
\section1 AnimatedSprite Type
-For use-cases which do not need to transition between animations, consider the AnimatedSprite type.
+For use-cases which do not need to transition between animations, consider the \l AnimatedSprite type.
This type displays sprite animations with the same input format, but only one at a time. It also provides more fine-grained
manual control, as there is no sprite engine managing the timing and transitions behind the scenes.
diff --git a/src/quick/doc/src/concepts/layouts/qtquicklayouts-index.qdoc b/src/quick/doc/src/concepts/layouts/qtquicklayouts-index.qdoc
index f65b1152e9..a45ed4b45c 100644
--- a/src/quick/doc/src/concepts/layouts/qtquicklayouts-index.qdoc
+++ b/src/quick/doc/src/concepts/layouts/qtquicklayouts-index.qdoc
@@ -39,6 +39,15 @@
Visit the \l{Qt Quick Layouts Overview} page to get started.
+ \section1 Licenses
+
+ Qt Quick Layouts is available under commercial licenses from \l{The Qt Company}.
+ In addition, it is available under free software licenses. Since Qt 5.4,
+ these free software licenses are
+ \l{GNU Lesser General Public License, version 3}, or
+ the \l{GNU General Public License, version 2}.
+ See \l{Qt Licensing} for further details.
+
\section1 Layouts
\annotatedlist layouts
diff --git a/src/quick/doc/src/concepts/layouts/qtquicklayouts-overview.qdoc b/src/quick/doc/src/concepts/layouts/qtquicklayouts-overview.qdoc
index 06ebe2d3d1..a5f93b972a 100644
--- a/src/quick/doc/src/concepts/layouts/qtquicklayouts-overview.qdoc
+++ b/src/quick/doc/src/concepts/layouts/qtquicklayouts-overview.qdoc
@@ -38,7 +38,7 @@
The QML types can be imported into your application using the following import statement in your \c {.qml} file.
\code
- import QtQuick.Layouts 1.2
+ import QtQuick.Layouts 1.11
\endcode
\section1 Key Features
diff --git a/src/quick/doc/src/concepts/layouts/qtquicklayouts.qdoc b/src/quick/doc/src/concepts/layouts/qtquicklayouts.qdoc
index 8f390c83db..d82e35fb93 100644
--- a/src/quick/doc/src/concepts/layouts/qtquicklayouts.qdoc
+++ b/src/quick/doc/src/concepts/layouts/qtquicklayouts.qdoc
@@ -26,7 +26,7 @@
****************************************************************************/
/*!
- \qmlmodule QtQuick.Layouts 1.3
+ \qmlmodule QtQuick.Layouts 1.11
\title Qt Quick Layouts QML Types
\ingroup qmlmodules
\brief Provides QML types for arranging QML items in a user interface.
@@ -40,7 +40,7 @@
following import statement in your .qml file.
\code
- import QtQuick.Layouts 1.3
+ import QtQuick.Layouts 1.11
\endcode
*/
diff --git a/src/quick/doc/src/guidelines/qtquick-bestpractices.qdoc b/src/quick/doc/src/guidelines/qtquick-bestpractices.qdoc
new file mode 100644
index 0000000000..e70791d1c9
--- /dev/null
+++ b/src/quick/doc/src/guidelines/qtquick-bestpractices.qdoc
@@ -0,0 +1,428 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 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$
+**
+****************************************************************************/
+
+/*!
+\page qtquick-bestpractices.html
+\title Best Practices for QML and Qt Quick
+\brief Lists best practices for working with QML and Qt Quick
+
+Despite all of the benefits that QML and Qt Quick offer, they can be
+challenging in certain situations. The following sections elaborate on some of
+the best practices that will help you get better results when developing
+applications.
+
+\section1 Custom UI Controls
+
+A fluid and modern UI is key for any application's success in today's world, and
+that's where QML makes so much sense for a designer or developer. Qt offers the
+most basic UI controls that are necessary to create a fluid and modern-looking
+UI. It is recommended to browse this list of UI controls before creating your
+own custom UI control.
+
+Besides these basic UI controls offered by Qt Quick itself, a rich set of UI
+controls are also available with Qt Quick Controls 2. They cater to the most
+common use cases without any change, and offer a lot more possibilities with their
+customization options. In particular, Qt Quick Controls 2 provides styling
+options that align with the latest UI design trends. If these UI controls do not
+satisfy your application's needs, only then it is recommended to create a
+custom control.
+
+
+\section2 Related Information
+\list
+\li \l{Qt Quick Controls 2}
+\li \l{Qt Quick}
+\endlist
+
+\section1 Keep it Short and Simple or "KiSS"
+
+QML being a declarative language, a lot of the details are worked out by the underlying
+engine. So it is important for any QML application, especially one with a
+larger codebase, to have its code organized in smaller and simpler \c .qml files.
+
+\omit
+need a few snippet or example applications that showcase this.
+\endomit
+
+\section2 Related Information
+\list
+ \li \l{QML Coding Conventions}
+\endlist
+
+\section1 Bundle Application Resources
+
+Most applications depend on resources such as images and icons to provide a
+rich user experience. It can often be a challenge to make these resources
+available to the application regardless of the target OS. Most popular OS-es
+employ stricter security policies that restrict access to the file system,
+making it harder to load these resources. As an alternative, Qt offers its own
+\l {The Qt Resource System}{resource system} that is built into the
+application binary, enabling access to the application's resources regardless
+of the target OS.
+
+For example, consider the following project directory structure:
+
+\badcode
+project
+├── images
+│ ├── image1.png
+│ └── image2.png
+├── project.pro
+└── qml
+ └── main.qml
+\endcode
+
+The following entry in \c project.pro ensures that the resources are built into
+the application binary, making them available when needed:
+
+\badcode
+ RESOURCES += \
+ qml/main.qml \
+ images/image1.png \
+ images/image2.png
+\endcode
+
+A more convenient approach is to use the
+\l {files(pattern[, recursive=false])}{wildcard syntax} to select several files
+at once:
+
+\badcode
+ RESOURCES += \
+ $$files(qml/*.qml) \
+ $$files(images/*.png)
+\endcode
+
+This approach is convenient for applications that depend on a limited number
+of resources. However, whenever a new file is added to \c RESOURCES using this
+approach, it causes \e all of the other files in \c RESOURCES to be recompiled
+as well. This can be inefficient, especially for large sets of files.
+In this case, a better approach is to separate each type of resource into its
+own \l {Resource Collection Files (.qrc)}{.qrc} file. For example, the snippet
+above could be changed to the following:
+
+\badcode
+ qml.files = $$files(*.qml)
+ qml.prefix = /qml
+ RESOURCES += qml
+
+ images.files = $$files(*.png)
+ images.prefix = /images
+ RESOURCES += images
+\endcode
+
+Now, whenever a QML file is changed, only the QML files have to be recompiled.
+
+Sometimes it can be necessary to have more control over the path for a
+specific file managed by the resource system. For example, if we wanted to give
+\c image2.png an alias, we would need to switch to an explicit \c .qrc file.
+\l {Creating Resource Files} explains how to do this in detail.
+
+\section2 Related Information
+\list
+ \li \l{The Qt Resource System}
+\endlist
+
+\section1 Separate UI from Logic
+
+One of the key goals that most application developers want to achieve is to
+create a maintainable application. One of the ways to achieve this goal is
+to separate the user interface from the business logic. The following are a few
+reasons why an application's UI should be written in QML:
+
+\list
+ \li Declarative languages are strongly suited for defining UIs.
+ \li QML code is simpler to write, as it is less verbose than C++, and is not
+ strongly typed. This also results in it being an excellent language to
+ prototype in, a quality that is vital when collaborating with designers,
+ for example.
+ \li JavaScript can easily be used in QML to respond to events.
+\endlist
+
+Being a strongly typed language, C++ is best suited for an application's logic.
+Typically, such code performs tasks such as complex calculations
+or data processing, which are faster in C++ than QML.
+
+Qt offers various approaches to integrate QML and C++ code in an application.
+A typical use case is displaying a list of data in a user interface.
+If the data set is static, simple, and/or small, a model written in QML can be
+sufficient.
+
+The following snippet demonstrates examples of models written in QML:
+
+\qml
+ model: ListModel {
+ ListElement { name: "Item 1" }
+ ListElement { name: "Item 2" }
+ ListElement { name: "Item 3" }
+ }
+
+ model: [ "Item 1", "Item 2", "Item 3" ]
+
+ model: 10
+\endqml
+
+Use \l {QAbstractItemModel Subclass}{C++} for dynamic data sets that are large
+or frequently modified.
+
+\section2 Interacting with QML from C++
+
+Although Qt enables you to manipulate QML from C++, it is not recommended to do
+so. To explain why, let's take a look at a simplified example.
+
+\section3 Pulling References from QML
+
+Suppose we were writing the UI for a settings page:
+
+\qml
+ import QtQuick 2.11
+ import QtQuick.Controls 2.4
+
+ Page {
+ Button {
+ text: qsTr("Restore default settings")
+ }
+ }
+\endqml
+
+We want the button to do something in C++ when it is clicked. We know objects
+in QML can emit change signals just like they can in C++, so we give the button
+an \l [QML]{QtObject::}{objectName} so that we can find it from C++:
+
+\qml
+ Button {
+ objectName: "restoreDefaultsButton"
+ text: qsTr("Restore default settings")
+ }
+\endqml
+
+Then, in C++, we find that object and connect to its change signal:
+
+\code
+ #include <QGuiApplication>
+ #include <QQmlApplicationEngine>
+ #include <QSettings>
+
+ class Backend : public QObject
+ {
+ Q_OBJECT
+
+ public:
+ Backend() {}
+
+ public slots:
+ void restoreDefaults() {
+ settings.setValue("loadLastProject", QVariant(false));
+ }
+
+ private:
+ QSettings settings;
+ };
+
+ int main(int argc, char *argv[])
+ {
+ QGuiApplication app(argc, argv);
+
+ QQmlApplicationEngine engine;
+ engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
+ if (engine.rootObjects().isEmpty())
+ return -1;
+
+ Backend backend;
+
+ QObject *rootObject = engine.rootObjects().first();
+ QObject *restoreDefaultsButton = rootObject->findChild<QObject*>("restoreDefaultsButton");
+ QObject::connect(restoreDefaultsButton, SIGNAL(clicked()),
+ &backend, SLOT(restoreDefaults()));
+
+ return app.exec();
+ }
+
+ #include "main.moc"
+\endcode
+
+With this approach, references to objects are "pulled" from QML.
+The problem with this is that the C++ logic layer depends on the QML
+presentation layer. If we were to refactor the QML in such a way that the
+\c objectName changes, or some other change breaks the ability for the C++
+to find the QML object, our workflow becomes much more complicated and tedious.
+
+\section3 Pushing References to QML
+
+Refactoring QML is a lot easier than refactoring C++, so in order to make
+maintenance pain-free, we should strive to keep C++ types unaware of QML as
+much as possible. This can be achieved by "pushing" references to C++ types
+into QML:
+
+\code
+ int main(int argc, char *argv[])
+ {
+ QGuiApplication app(argc, argv);
+
+ Backend backend;
+
+ QQmlApplicationEngine engine;
+ engine.rootContext()->setContextProperty("backend", &backend);
+ engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
+ if (engine.rootObjects().isEmpty())
+ return -1;
+
+ return app.exec();
+ }
+\endcode
+
+The QML then calls the C++ slot directly:
+
+\qml
+ import QtQuick 2.11
+ import QtQuick.Controls 2.4
+
+ Page {
+ Button {
+ text: qsTr("Restore default settings")
+ onClicked: backend.restoreDefaults()
+ }
+ }
+\endqml
+
+With this approach, the C++ remains unchanged in the event that the QML needs
+to be refactored in the future.
+
+In the example above, we set a context property on the root context to expose
+the C++ object to QML. This means that the property is available to every
+component loaded by the engine. Context properties are useful for objects that
+must be available as soon as the QML is loaded and cannot be instantiated in
+QML.
+
+\l {Integrating QML and C++} demonstrates an alternative approach where QML is
+made aware of a C++ type so that it can instantiate it itself.
+
+\section2 Related Information
+\list
+\li \l{Integrating QML and C++}
+\li \l{Qt Quick Controls 2 - Chat Tutorial}{Chat application tutorial}
+\endlist
+
+\section1 Using Qt Quick Layouts
+
+Qt offers Qt Quick Layouts to arrange Qt Quick items visually in a layout.
+Unlike its alternative, the item positioners, the Qt Quick Layouts can also
+resize its children on window resize. Although Qt Quick Layouts are often
+the desired choice for most use cases, the following \e dos and \e{don'ts}
+must be considered while using them:
+
+\section2 Dos
+
+\list
+ \li Use anchors or the item's width and height properties to specify the size
+ of the layout against its parent.
+ \li Use the \l Layout attached property to set the size and alignment
+ attributes of the layout's immediate children.
+\endlist
+
+\section2 Don'ts
+
+\list
+ \li Do not rely on anchors to specify the preferred size of an item in a layout.
+ Instead, use \c Layout.preferredWidth and \c Layout.preferredHeight.
+ \li Do not define preferred sizes for items that provide implicitWidth and
+ implicitHeight, unless their implicit sizes are not satisfactory.
+ \li Do not mix anchors and layouts in ways that cause conflicts. For example,
+ do not apply anchor constraints to a layout's immediate children.
+
+ \snippet qml/windowconstraints.qml rowlayout
+\endlist
+
+\note Layouts and anchors are both types of objects that take more memory and
+instantiation time. Avoid using them (especially in list and table delegates,
+and styles for controls) when simple bindings to x, y, width, and height
+properties are enough.
+
+\section2 Related Information
+
+\list
+ \li \l{Item Positioners}
+ \li \l{Qt Quick Layouts Overview}
+\endlist
+
+\section1 Performance
+
+For information on performance in QML and Qt Quick,
+see \l {Performance Considerations And Suggestions}.
+
+\section1 Tools and Utilities
+
+For information on useful tools and utilies that make working with QML and
+Qt Quick easier, see \l {Qt Quick Tools and Utilities}.
+
+\section1 Scene Graph
+
+For information on Qt Quick's scene graph, see \l {Qt Quick Scene Graph}.
+
+\section1 Scalable User Interfaces
+
+As display resolutions improve, a scalable application UI becomes more and
+more important. One of the approaches to achieve this is to maintain several
+copies of the UI for different screen resolutions, and load the appropriate one
+depending on the available resolution. Although this works pretty
+well, it adds to the maintenance overhead.
+
+Qt offers a better solution to this problem and recommends the application
+developers to follow these tips:
+
+\list
+ \li Use anchors or the Qt Quick Layouts module to lay out the visual items.
+ \li Do not specify explicit width and height for a visual item.
+ \li Provide UI resources such as images and icons for each display resolution
+ that your application supports. The Qt Quick Controls 2 gallery example
+ demonstrates this well by providing the \c qt-logo.png for \c @2x, \c @3x,
+ and \c @4x resolutions, enabling the application to cater to high
+ resolution displays. Qt automatically chooses the appropriate
+ image that is suitable for the given display, provided the high DPI scaling
+ feature is explicitly enabled.
+ \li Use SVG images for small icons. While larger SVGs can be slow to render,
+ small ones work well. Vector images avoid the need to provide several
+ versions of an image, as is necessary with bitmap images.
+ \li Use font-based icons, such as Font Awesome. These scale to any display
+ resolution, and also allow colorization. The
+ Qt Quick Controls 2 Text Editor example demonstrates this well.
+\endlist
+
+With this in place, your application's UI should scale depending
+on the display resolution on offer.
+
+\image qtquickcontrols2-gallery-welcome.png
+
+\section2 Related Information
+
+\list
+ \li \l{Qt Quick Controls2 - Gallery Example}{Gallery example}
+ \li \l{Qt Quick Controls 2 - Text Editor}{Text Editor example}
+ \li \l{Font Awesome}
+ \li \l{Scalability}
+ \li \l{High DPI Displays}
+\endlist
+*/
diff --git a/src/quick/doc/src/guidelines/qtquick-toolsnutilities.qdoc b/src/quick/doc/src/guidelines/qtquick-toolsnutilities.qdoc
new file mode 100644
index 0000000000..5f00abc193
--- /dev/null
+++ b/src/quick/doc/src/guidelines/qtquick-toolsnutilities.qdoc
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 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$
+**
+****************************************************************************/
+
+/*!
+\page qtquick-tools-and-utilities.html
+\title Qt Quick Tools and Utilities
+\brief Lists the tools and utilities that enhance developer experience
+
+Qt offers several tools and utilities to enable a rich developer experience,
+especially for Qt Quick developers. The following sections provide a brief
+introduction to those tools and utilities, and provide links to further
+information about them.
+
+\section1 Qt Quick Designer
+
+The Qt Quick Designer enables designing Qt Quick-based UIs using simple
+drag-n-drop gestures that most designers are familiar with. It offers UI
+elements from the Qt Quick and Qt Quick Controls 2 modules, as well as
+integration for custom UI elements.
+
+The following is a list of example applications that use UIs created by
+the Qt Quick Designer:
+
+\list
+ \li \l{Qt Quick Controls 2 - Contact List}
+ \li \l{Qt Quick Controls 2 - Flat Style}
+\endlist
+
+\section2 QML Debugger and Profiler
+
+Being a declarative language, a piece of QML code provides minimal details
+about the entities defined. In such a scenario, the QML debugger is a very
+useful utility that enables:
+\list
+ \li debugging JavaScript functions,
+ \li executing JavaScript expressions,
+ \li and inspecting QML properties.
+\endlist
+
+Besides this, a QML profiler enables you to get necessary diagnostic information,
+allowing you to analyze the application code for performance issues. For
+example, too much JavaScript in each frame, long-running C++ functions, and
+so on.
+
+\section2 Related Information
+\list
+ \li \l{QML Debugger}
+ \li \l{QML Profiler}
+\endlist
+
+\section2 QmlLive, GammaRay, and Squish
+
+QmlLive is a 3rd party tool that offers a QML runtime capable of rendering
+changes to the code in realtime. It avoids the need to rebuild the
+application after every code change and install it on the target device.
+You can also extend it to build a custom runtime that suits your needs.
+
+GammaRay is a useful utility that provides diagnostic information
+about your application. It is similar to the QML Profiler described in the
+earlier section, but offers a lot more. For example, the number of items or
+QObjects created, function calls made, time taken by each function call,
+property value introspection at runtime, and so on. Such information is very
+handy, especially while debugging QML applications.
+
+Squish is a well-known testing tool that automates UI testing by recording
+your actions or running scripts. Once the tests are setup, UI tests are a lot
+easier to run.
+
+\section2 Related Information
+\list
+ \li \l{QmlLive}
+ \li \l{GammaRay}
+ \li \l{Squish}
+\endlist
+
+\section1 Qt Creator
+
+The Qt Creator IDE is the key tool that enhances the overall developer experience of
+working with Qt Quick. Its auto-completion and debugging features make working
+with Qt Quick easier. Besides this, most of the tools and utilities
+mentioned in the earlier sections are integrated into it, with the possibility of
+integrating 3rd party tools such as QmlLive and GammaRay.
+
+\section2 Related Information
+\list
+\li \l{Qt Creator Manual}
+\li \l{Qt Creator: Integrating 3rd Party Tools}
+\endlist
+*/
diff --git a/src/quick/doc/src/qmltypereference.qdoc b/src/quick/doc/src/qmltypereference.qdoc
index f5b189c580..80b9241f36 100644
--- a/src/quick/doc/src/qmltypereference.qdoc
+++ b/src/quick/doc/src/qmltypereference.qdoc
@@ -26,7 +26,7 @@
****************************************************************************/
/*!
-\qmlmodule QtQuick 2.7
+\qmlmodule QtQuick 2.11
\title Qt Quick QML Types
\ingroup qmlmodules
\brief Provides graphical QML types.
@@ -34,11 +34,11 @@
The \l{Qt Quick} module provides graphical primitive types. These types are only
available in a QML document if that document imports the \c QtQuick namespace.
-The current version of the \c QtQuick module is version 2.7, and thus it may be
+The current version of the \c QtQuick module is version 2.11, and thus it may be
imported via the following statement:
\qml
-import QtQuick 2.7
+import QtQuick 2.11
\endqml
Visit the \l {Qt Quick} module documentation for more
@@ -883,14 +883,14 @@ console.log(c + " " + d); // false true
*/
/*!
-\qmlmodule QtTest 1.1
+\qmlmodule QtTest 1.11
\title Qt Quick Test QML Types
\brief This module provides QML types to unit test your QML application
\ingroup qmlmodules
You can import this module using the following statement:
\code
-import QtTest 1.1
+import QtTest 1.11
\endcode
For more information about how to use these types, see
diff --git a/src/quick/doc/src/qtquick.qdoc b/src/quick/doc/src/qtquick.qdoc
index ece66cb589..4d8da5ed5a 100644
--- a/src/quick/doc/src/qtquick.qdoc
+++ b/src/quick/doc/src/qtquick.qdoc
@@ -118,6 +118,7 @@ Additional Qt Quick information:
\li \l{Qt Quick Test QML Types}{Tests} - contains types for writing unit test for a QML application
\endlist
\li \l{Qt Quick Examples and Tutorials}
+\li \l{Qt Quick Guidelines}
\endlist
Further information for writing QML applications:
diff --git a/src/quick/handlers/qquickpointerhandler.cpp b/src/quick/handlers/qquickpointerhandler.cpp
index 959030b8fe..e5b1dc8985 100644
--- a/src/quick/handlers/qquickpointerhandler.cpp
+++ b/src/quick/handlers/qquickpointerhandler.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQuick module of the Qt Toolkit.
@@ -245,6 +245,14 @@ void QQuickPointerHandler::setGrabPermissions(GrabPermissions grabPermission)
emit grabPermissionChanged();
}
+void QQuickPointerHandler::classBegin()
+{
+}
+
+void QQuickPointerHandler::componentComplete()
+{
+}
+
/*!
\internal
Acquire or give up the exclusive grab of the given \a point, according to
diff --git a/src/quick/handlers/qquickpointerhandler_p.h b/src/quick/handlers/qquickpointerhandler_p.h
index 9ea6a8b5e2..e2bcce8fc9 100644
--- a/src/quick/handlers/qquickpointerhandler_p.h
+++ b/src/quick/handlers/qquickpointerhandler_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQuick module of the Qt Toolkit.
@@ -106,9 +106,6 @@ public:
GrabPermissions grabPermissions() const { return static_cast<GrabPermissions>(m_grabPermissions); }
void setGrabPermissions(GrabPermissions grabPermissions);
- void classBegin() override { }
- void componentComplete() override { }
-
Q_SIGNALS:
void enabledChanged();
void activeChanged();
@@ -118,6 +115,9 @@ Q_SIGNALS:
void canceled(QQuickEventPoint *point);
protected:
+ void classBegin() override;
+ void componentComplete() override;
+
QQuickPointerEvent *currentEvent() { return m_currentEvent; }
virtual bool wantsPointerEvent(QQuickPointerEvent *event);
virtual void handlePointerEventImpl(QQuickPointerEvent *event);
diff --git a/src/quick/items/qquickanimatedsprite.cpp b/src/quick/items/qquickanimatedsprite.cpp
index 741e4607e5..190c48ac88 100644
--- a/src/quick/items/qquickanimatedsprite.cpp
+++ b/src/quick/items/qquickanimatedsprite.cpp
@@ -152,10 +152,10 @@ QT_BEGIN_NAMESPACE
/*!
\qmlproperty qreal QtQuick::AnimatedSprite::frameRate
- Frames per second to show in the animation. Values equal to or below 0 are invalid.
+ Frames per second to show in the animation. Values less than or equal to \c 0 are invalid.
- If frameRate is valid then it will be used to calculate the duration of the frames.
- If not, and frameDuration is valid , then frameDuration will be used.
+ If \c frameRate is valid, it will be used to calculate the duration of the frames.
+ If not, and \l frameDuration is valid, \c frameDuration will be used.
Changing this parameter will restart the animation.
*/
@@ -163,10 +163,10 @@ QT_BEGIN_NAMESPACE
/*!
\qmlproperty int QtQuick::AnimatedSprite::frameDuration
- Duration of each frame of the animation in milliseconds. Values equal to or below 0 are invalid.
+ Duration of each frame of the animation in milliseconds. Values less than or equal to \c 0 are invalid.
- If frameRate is valid then it will be used to calculate the duration of the frames.
- If not, and frameDuration is valid, then frameDuration will be used.
+ If frameRate is valid, it will be used to calculate the duration of the frames.
+ If not, and \l frameDuration is valid, \c frameDuration will be used.
Changing this parameter will restart the animation.
*/
@@ -218,21 +218,21 @@ QT_BEGIN_NAMESPACE
/*!
\qmlproperty bool QtQuick::AnimatedSprite::reverse
- If true, then the animation will be played in reverse.
+ If \c true, the animation will be played in reverse.
- Default is false.
+ Default is \c false.
*/
/*!
\qmlproperty bool QtQuick::AnimatedSprite::frameSync
- If true, then the animation will have no duration. Instead, the animation will advance
+ If \c true, the animation will have no duration. Instead, the animation will advance
one frame each time a frame is rendered to the screen. This synchronizes it with the painting
rate as opposed to elapsed time.
If frameSync is set to true, it overrides both frameRate and frameDuration.
- Default is false.
+ Default is \c false.
Changing this parameter will restart the animation.
*/
@@ -242,9 +242,9 @@ QT_BEGIN_NAMESPACE
After playing the animation this many times, the animation will automatically stop. Negative values are invalid.
- If this is set to AnimatedSprite.Infinite the animation will not stop playing on its own.
+ If this is set to \c AnimatedSprite.Infinite the animation will not stop playing on its own.
- Default is AnimatedSprite.Infinite
+ Default is \c AnimatedSprite.Infinite
*/
/*!
@@ -252,13 +252,13 @@ QT_BEGIN_NAMESPACE
When paused, the current frame can be advanced manually.
- Default is false.
+ Default is \c false.
*/
/*!
\qmlproperty int QtQuick::AnimatedSprite::currentFrame
- When paused, the current frame can be advanced manually by setting this property or calling advance().
+ When paused, the current frame can be advanced manually by setting this property or calling \l advance().
*/
@@ -452,7 +452,7 @@ void QQuickAnimatedSprite::maybeUpdate()
\qmlmethod int QtQuick::AnimatedSprite::pause()
Pauses the sprite animation. This does nothing if
- \l paused is true.
+ \l paused is \c true.
\sa resume()
*/
@@ -471,7 +471,7 @@ void QQuickAnimatedSprite::pause()
/*!
\qmlmethod int QtQuick::AnimatedSprite::resume()
- Resumes the sprite animation if \l paused is true;
+ Resumes the sprite animation if \l paused is \c true;
otherwise, this does nothing.
\sa pause()
diff --git a/src/quick/items/qquickevents_p_p.h b/src/quick/items/qquickevents_p_p.h
index c4f0b60d92..2a1e9dc184 100644
--- a/src/quick/items/qquickevents_p_p.h
+++ b/src/quick/items/qquickevents_p_p.h
@@ -597,6 +597,7 @@ public:
Area = QTouchDevice::Area,
Pressure = QTouchDevice::Pressure,
Velocity = QTouchDevice::Velocity,
+ MouseEmulation = QTouchDevice::MouseEmulation,
// some bits reserved in case we need more of QTouchDevice::Capabilities
Scroll = 0x0100, // mouse has a wheel, or there is OS-level scroll gesture recognition (dubious?)
Hover = 0x0200,
diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp
index d4f10a9fd9..cefe2de883 100644
--- a/src/quick/items/qquickflickable.cpp
+++ b/src/quick/items/qquickflickable.cpp
@@ -1652,10 +1652,12 @@ void QQuickFlickable::timerEvent(QTimerEvent *event)
}
} else if (event->timerId() == d->movementEndingTimer.timerId()) {
d->movementEndingTimer.stop();
- d->pressed = false;
- d->stealMouse = false;
- if (!d->velocityTimeline.isActive() && !d->timeline.isActive())
- movementEnding(true, true);
+ if (!d->scrollingPhase) {
+ d->pressed = false;
+ d->stealMouse = false;
+ if (!d->velocityTimeline.isActive() && !d->timeline.isActive())
+ movementEnding(true, true);
+ }
}
}
diff --git a/src/quick/items/qquickimage.cpp b/src/quick/items/qquickimage.cpp
index dc2cd17b4e..db5cfd2526 100644
--- a/src/quick/items/qquickimage.cpp
+++ b/src/quick/items/qquickimage.cpp
@@ -135,6 +135,48 @@ QQuickImagePrivate::QQuickImagePrivate()
\clearfloat
+ \section1 OpenGL Texture Files
+
+ When the default OpenGL \l{Qt Quick Scene Graph}{scene graph} backend is in
+ use, images can also be supplied in compressed texture files. The content
+ must be a simple RGB(A) format 2D texture. Supported compression schemes
+ are only limited by the underlying OpenGL driver and GPU. The following
+ container file formats are supported:
+
+ \list
+ \li \c PKM (since Qt 5.10)
+ \li \c KTX (since Qt 5.11)
+ \endlist
+
+ \note Semi-transparent original images require alpha pre-multiplication
+ prior to texture compression in order to be correctly displayed in Qt
+ Quick. This can be done with the following ImageMagick command
+ line:
+ \badcode
+ convert MYORIGIMAGE \( +clone -alpha Extract \) -channel RGB -compose Multiply -composite MYPMIMAGE
+ \endcode
+
+ \section1 Automatic Detection of File Extension
+
+ If the \l source URL indicates a non-existing local file or resource, the
+ Image element attempts to auto-detect the file extension. If an existing
+ file can be found by appending any of the supported image file extensions
+ to the \l source URL, then that file will be loaded.
+
+ If the OpenGL \l{Qt Quick Scene Graph}{scene graph} backend is in use, the
+ file search the attempts the OpenGL texture file extensions first. If the
+ search is unsuccessful, it attempts to search with the file extensions for
+ the \l{QImageReader::supportedImageFormats()}{conventional image file
+ types}. For example:
+
+ \snippet qml/image-ext.qml ext
+
+ This functionality facilitates deploying different image asset file types
+ on different target platforms. This can be useful in order to tune
+ application performance and adapt to different graphics hardware.
+
+ This functionality was introduced in Qt 5.11.
+
\section1 Performance
By default, locally available images are loaded immediately, and the user interface
@@ -154,7 +196,7 @@ QQuickImagePrivate::QQuickImagePrivate()
size bounded via the \l sourceSize property. This is especially important for content
that is loaded from external sources or provided by the user.
- \sa {Qt Quick Examples - Image Elements}, QQuickImageProvider
+ \sa {Qt Quick Examples - Image Elements}, QQuickImageProvider, QImageReader::setAutoDetectImageFormat()
*/
QQuickImage::QQuickImage(QQuickItem *parent)
@@ -461,7 +503,7 @@ qreal QQuickImage::paintedHeight() const
The URL may be absolute, or relative to the URL of the component.
- \sa QQuickImageProvider
+ \sa QQuickImageProvider {OpenGL Texture Files} {Automatic Detection of File Extension}
*/
/*!
diff --git a/src/quick/items/qquickitemgrabresult.cpp b/src/quick/items/qquickitemgrabresult.cpp
index 003fde8c9e..b45cb09c4b 100644
--- a/src/quick/items/qquickitemgrabresult.cpp
+++ b/src/quick/items/qquickitemgrabresult.cpp
@@ -139,7 +139,7 @@ public:
* This property holds the pixel results from a grab.
*
* If the grab is not yet complete or if it failed,
- * an empty image is returned.
+ * a null image is returned (\c {image.isNull()} will return \c true).
*/
/*!
diff --git a/src/quick/items/qquickloader.cpp b/src/quick/items/qquickloader.cpp
index 34f30e81a3..cd48896e58 100644
--- a/src/quick/items/qquickloader.cpp
+++ b/src/quick/items/qquickloader.cpp
@@ -102,7 +102,7 @@ void QQuickLoaderPrivate::clear()
// this we may get transient errors from use of 'parent', for example.
QQmlContext *context = qmlContext(object);
if (context)
- QQmlContextData::get(context)->invalidate();
+ QQmlContextData::get(context)->clearContextRecursively();
if (loadingFromSource && component) {
// disconnect since we deleteLater
@@ -311,10 +311,7 @@ QQuickLoader::QQuickLoader(QQuickItem *parent)
QQuickLoader::~QQuickLoader()
{
Q_D(QQuickLoader);
- if (d->item) {
- QQuickItemPrivate *p = QQuickItemPrivate::get(d->item);
- p->removeItemChangeListener(d, watchedChanges);
- }
+ d->clear();
}
/*!
@@ -363,7 +360,7 @@ void QQuickLoader::setActive(bool newVal)
// this we may get transient errors from use of 'parent', for example.
QQmlContext *context = qmlContext(d->object);
if (context)
- QQmlContextData::get(context)->invalidate();
+ QQmlContextData::get(context)->clearContextRecursively();
if (d->item) {
QQuickItemPrivate *p = QQuickItemPrivate::get(d->item);
diff --git a/src/quick/items/qquicksprite.cpp b/src/quick/items/qquicksprite.cpp
index 99b1b1f430..6b8567439b 100644
--- a/src/quick/items/qquicksprite.cpp
+++ b/src/quick/items/qquicksprite.cpp
@@ -51,8 +51,8 @@ QT_BEGIN_NAMESPACE
\ingroup qtquick-visual-utility
\brief Specifies sprite animations
- QQuickSprite renders sprites of one or more frames and animates them. The sprites
- can be in the middle of an image file, or split along multiple rows, as long as they form
+ Sprite defines a series of one or more frames to be animated and rendered by SpriteSequence.
+ The sprites can be in the middle of an image file, or split along multiple rows, as long as they form
a contiguous line wrapping to the next row of the file from the left edge of the file.
For full details, see the \l{Sprite Animations} overview.
diff --git a/src/quick/items/qquickspritesequence.cpp b/src/quick/items/qquickspritesequence.cpp
index 0a39c09ebc..72761ab82b 100644
--- a/src/quick/items/qquickspritesequence.cpp
+++ b/src/quick/items/qquickspritesequence.cpp
@@ -73,38 +73,38 @@ QT_BEGIN_NAMESPACE
Whether the sprite is animating or not.
- Default is true
+ Default is \c true.
*/
/*!
\qmlproperty bool QtQuick::SpriteSequence::interpolate
- If true, interpolation will occur between sprite frames to make the
+ If \c true, interpolation will occur between sprite frames to make the
animation appear smoother.
- Default is true.
+ Default is \c true.
*/
/*!
\qmlproperty string QtQuick::SpriteSequence::currentSprite
- The name of the Sprite which is currently animating.
+ The name of the \l Sprite that is currently animating.
*/
/*!
\qmlproperty string QtQuick::SpriteSequence::goalSprite
- The name of the Sprite which the animation should move to.
+ The name of the \l Sprite that the animation should move to.
- Sprite states have defined durations and transitions between them, setting goalState
- will cause it to disregard any path weightings (including 0) and head down the path
- which will reach the goalState quickest (fewest animations). It will pass through
+ Sprite states have defined durations and transitions between them; setting \c goalSprite
+ will cause it to disregard any path weightings (including \c 0) and head down the path
+ that will reach the \c goalSprite quickest (fewest animations). It will pass through
intermediate states on that path, and animate them for their duration.
- If it is possible to return to the goalState from the starting point of the goalState
- it will continue to do so until goalState is set to "" or an unreachable state.
+ If it is possible to return to the \c goalSprite from the starting point of the \c goalSprite,
+ it will continue to do so until \c goalSprite is set to \c "" or an unreachable state.
*/
/*! \qmlmethod QtQuick::SpriteSequence::jumpTo(string sprite)
- This function causes the SpriteSequence to jump to the specified sprite immediately, intermediate
- sprites are not played. The \a sprite argument is the name of the sprite you wish to jump to.
+ This function causes the SpriteSequence to jump to the specified \a sprite immediately;
+ intermediate sprites are not played.
*/
/*!
\qmlproperty list<Sprite> QtQuick::SpriteSequence::sprites
diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp
index 383aa2b821..9eaf9f8d6d 100644
--- a/src/quick/items/qquicktext.cpp
+++ b/src/quick/items/qquicktext.cpp
@@ -2318,8 +2318,10 @@ void QQuickText::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeo
if (!(widthChanged || widthMaximum) && !d->isLineLaidOutConnected()) { // only height has changed
if (newGeometry.height() > oldGeometry.height()) {
- if (!d->heightExceeded) // Height is adequate and growing.
+ if (!d->heightExceeded && !qFuzzyIsNull(oldGeometry.height())) {
+ // Height is adequate and growing, and it wasn't 0 previously.
goto geomChangeDone;
+ }
if (d->lineCount == d->maximumLineCount()) // Reached maximum line and height is growing.
goto geomChangeDone;
} else if (newGeometry.height() < oldGeometry.height()) {
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index 26b97d452a..02fe4809ab 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -656,6 +656,12 @@ bool QQuickWindowPrivate::deliverTouchAsMouse(QQuickItem *item, QQuickPointerEve
Q_Q(QQuickWindow);
auto device = pointerEvent->device();
+ // A touch event from a trackpad is likely to be followed by a mouse or gesture event, so mouse event synth is redundant
+ if (device->type() == QQuickPointerDevice::TouchPad && device->capabilities().testFlag(QQuickPointerDevice::MouseEmulation)) {
+ qCDebug(DBG_TOUCH_TARGET) << "skipping delivery of synth-mouse event from" << device;
+ return false;
+ }
+
// FIXME: make this work for mouse events too and get rid of the asTouchEvent in here.
Q_ASSERT(pointerEvent->asPointerTouchEvent());
QScopedPointer<QTouchEvent> event(pointerEvent->asPointerTouchEvent()->touchEventForItem(item));
@@ -2833,7 +2839,11 @@ bool QQuickWindowPrivate::sendFilteredPointerEventImpl(QQuickPointerEvent *event
// In versions prior to Qt 6, we can't trust item->acceptTouchEvents() here, because it defaults to true.
bool acceptsTouchEvents = false;
#endif
- if (acceptsTouchEvents || receiver->acceptedMouseButtons()) {
+ auto device = pte->device();
+ if (device->type() == QQuickPointerDevice::TouchPad &&
+ device->capabilities().testFlag(QQuickPointerDevice::MouseEmulation)) {
+ qCDebug(DBG_TOUCH_TARGET) << "skipping filtering of synth-mouse event from" << device;
+ } else if (acceptsTouchEvents || receiver->acceptedMouseButtons()) {
// get a touch event customized for delivery to filteringParent
QScopedPointer<QTouchEvent> filteringParentTouchEvent(pte->touchEventForItem(receiver, true));
if (filteringParentTouchEvent) {
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode.cpp
index 3b0f3c48ff..aa83709b72 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode.cpp
@@ -320,6 +320,7 @@ QSGSoftwareInternalImageNode::QSGSoftwareInternalImageNode()
, m_subSourceRect(0, 0, 1, 1)
, m_texture(nullptr)
, m_mirror(false)
+ , m_textureIsLayer(false)
, m_smooth(true)
, m_tileHorizontal(false)
, m_tileVertical(false)
@@ -366,6 +367,7 @@ void QSGSoftwareInternalImageNode::setTexture(QSGTexture *texture)
{
m_texture = texture;
m_cachedMirroredPixmapIsDirty = true;
+ m_textureIsLayer = static_cast<bool>(qobject_cast<QSGSoftwareLayer*>(texture));
markDirty(DirtyMaterial);
}
@@ -415,8 +417,13 @@ void QSGSoftwareInternalImageNode::setVerticalWrapMode(QSGTexture::WrapMode wrap
void QSGSoftwareInternalImageNode::update()
{
if (m_cachedMirroredPixmapIsDirty) {
- if (m_mirror) {
- m_cachedMirroredPixmap = pixmap().transformed(QTransform(-1, 0, 0, 1, 0, 0));
+ if (m_mirror || m_textureIsLayer) {
+ QTransform transform(
+ (m_mirror ? -1 : 1), 0,
+ 0 , (m_textureIsLayer ? -1 :1),
+ 0 , 0
+ );
+ m_cachedMirroredPixmap = pixmap().transformed(transform);
} else {
//Cleanup cached pixmap if necessary
if (!m_cachedMirroredPixmap.isNull())
@@ -436,6 +443,7 @@ void QSGSoftwareInternalImageNode::preprocess()
}
if (doDirty)
markDirty(DirtyMaterial);
+ m_cachedMirroredPixmapIsDirty = doDirty;
}
static Qt::TileRule getTileRule(qreal factor)
@@ -454,7 +462,7 @@ void QSGSoftwareInternalImageNode::paint(QPainter *painter)
{
painter->setRenderHint(QPainter::SmoothPixmapTransform, m_smooth);
- const QPixmap &pm = m_mirror ? m_cachedMirroredPixmap : pixmap();
+ const QPixmap &pm = m_mirror || m_textureIsLayer ? m_cachedMirroredPixmap : pixmap();
if (m_innerTargetRect != m_targetRect) {
// border image
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode_p.h
index 5c95eb064a..b80bacbaa0 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode_p.h
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode_p.h
@@ -136,6 +136,7 @@ private:
QPixmap m_cachedMirroredPixmap;
bool m_mirror;
+ bool m_textureIsLayer;
bool m_smooth;
bool m_tileHorizontal;
bool m_tileVertical;
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer.cpp
index b4301451d8..70378d2950 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer.cpp
@@ -240,9 +240,9 @@ void QSGSoftwareLayer::grab()
m_renderer->setDeviceRect(m_size);
m_renderer->setViewportRect(m_size);
QRect mirrored(m_mirrorHorizontal ? m_rect.right() * m_device_pixel_ratio : m_rect.left() * m_device_pixel_ratio,
- m_mirrorVertical ? m_rect.top() * m_device_pixel_ratio : m_rect.bottom() * m_device_pixel_ratio,
+ m_mirrorVertical ? m_rect.bottom() * m_device_pixel_ratio : m_rect.top() * m_device_pixel_ratio,
m_mirrorHorizontal ? -m_rect.width() * m_device_pixel_ratio : m_rect.width() * m_device_pixel_ratio,
- m_mirrorVertical ? m_rect.height() * m_device_pixel_ratio : -m_rect.height() * m_device_pixel_ratio);
+ m_mirrorVertical ? -m_rect.height() * m_device_pixel_ratio : m_rect.height() * m_device_pixel_ratio);
m_renderer->setProjectionRect(mirrored);
m_renderer->setClearColor(Qt::transparent);
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer.cpp
index 303f98c801..bb4afc8301 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer.cpp
@@ -79,7 +79,7 @@ void QSGSoftwarePixmapRenderer::render(QPaintDevice *target)
QElapsedTimer renderTimer;
// Setup background item
- setBackgroundRect(m_projectionRect);
+ setBackgroundRect(m_projectionRect.normalized());
setBackgroundColor(clearColor());
renderTimer.start();
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp
index 423f5f7321..b400473128 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp
@@ -195,7 +195,7 @@ void QSGSoftwareRenderLoop::renderWindow(QQuickWindow *window, bool isNewExpose)
int(polishTime / 1000000),
int((syncTime - polishTime) / 1000000),
int((renderTime - syncTime) / 1000000),
- int((swapTime - renderTime) / 10000000),
+ int((swapTime - renderTime) / 1000000),
int(lastFrameTime.msecsTo(QTime::currentTime())));
lastFrameTime = QTime::currentTime();
}
diff --git a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp
index dc473a6640..ce706d76f7 100644
--- a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp
+++ b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp
@@ -71,9 +71,9 @@ static inline QVector4D qsg_premultiply(const QVector4D &c, float globalOpacity)
return QVector4D(c.x() * o, c.y() * o, c.z() * o, o);
}
-static inline int qsg_device_pixel_ratio(QOpenGLContext *ctx)
+static inline qreal qsg_device_pixel_ratio(QOpenGLContext *ctx)
{
- int devicePixelRatio = 1;
+ qreal devicePixelRatio = 1;
if (ctx->surface()->surfaceClass() == QSurface::Window) {
QWindow *w = static_cast<QWindow *>(ctx->surface());
if (QQuickWindow *qw = qobject_cast<QQuickWindow *>(w))
diff --git a/src/quick/scenegraph/qsgrenderloop.cpp b/src/quick/scenegraph/qsgrenderloop.cpp
index 88b9c93448..3cdf851a8f 100644
--- a/src/quick/scenegraph/qsgrenderloop.cpp
+++ b/src/quick/scenegraph/qsgrenderloop.cpp
@@ -310,6 +310,8 @@ void QSGGuiThreadRenderLoop::hide(QQuickWindow *window)
{
QQuickWindowPrivate *cd = QQuickWindowPrivate::get(window);
cd->fireAboutToStop();
+ if (m_windows.contains(window))
+ m_windows[window].updatePending = false;
}
void QSGGuiThreadRenderLoop::windowDestroyed(QQuickWindow *window)
@@ -501,7 +503,8 @@ QImage QSGGuiThreadRenderLoop::grab(QQuickWindow *window)
void QSGGuiThreadRenderLoop::maybeUpdate(QQuickWindow *window)
{
- if (!m_windows.contains(window))
+ QQuickWindowPrivate *cd = QQuickWindowPrivate::get(window);
+ if (!cd->isRenderable() || !m_windows.contains(window))
return;
m_windows[window].updatePending = true;
diff --git a/src/quick/util/qquickimageprovider.cpp b/src/quick/util/qquickimageprovider.cpp
index 1a13f6395a..2bb2af4fc0 100644
--- a/src/quick/util/qquickimageprovider.cpp
+++ b/src/quick/util/qquickimageprovider.cpp
@@ -680,15 +680,18 @@ QSize QQuickImageProviderWithOptions::loadSize(const QSize &originalSize, const
return res;
const bool preserveAspectCropOrFit = options.preserveAspectRatioCrop() || options.preserveAspectRatioFit();
+ const bool formatIsSvg = (format == "svg" || format == "svgz");
- if (!preserveAspectCropOrFit && (format == "svg" || format == "svgz") && !requestedSize.isEmpty())
+ if (!preserveAspectCropOrFit && formatIsSvg && !requestedSize.isEmpty())
return requestedSize;
qreal ratio = 0.0;
- if (requestedSize.width() && (preserveAspectCropOrFit || requestedSize.width() < originalSize.width())) {
+ if (requestedSize.width() && (preserveAspectCropOrFit || formatIsSvg ||
+ requestedSize.width() < originalSize.width())) {
ratio = qreal(requestedSize.width()) / originalSize.width();
}
- if (requestedSize.height() && (preserveAspectCropOrFit || requestedSize.height() < originalSize.height())) {
+ if (requestedSize.height() && (preserveAspectCropOrFit || formatIsSvg ||
+ requestedSize.height() < originalSize.height())) {
qreal hr = qreal(requestedSize.height()) / originalSize.height();
if (ratio == 0.0)
ratio = hr;