aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick
diff options
context:
space:
mode:
Diffstat (limited to 'src/quick')
-rw-r--r--src/quick/designer/designersupport.cpp5
-rw-r--r--src/quick/doc/images/visualize-batches.pngbin0 -> 666 bytes
-rw-r--r--src/quick/doc/images/visualize-clip.pngbin0 -> 9201 bytes
-rw-r--r--src/quick/doc/images/visualize-original.pngbin0 -> 4151 bytes
-rw-r--r--src/quick/doc/images/visualize-overdraw-1.pngbin0 -> 6872 bytes
-rw-r--r--src/quick/doc/images/visualize-overdraw-2.pngbin0 -> 5386 bytes
-rw-r--r--src/quick/doc/qtquick.qdocconf1
-rw-r--r--src/quick/doc/snippets/qml/xmlrole.qml9
-rw-r--r--src/quick/doc/snippets/qml/xmlrole.xml20
-rw-r--r--src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc117
-rw-r--r--src/quick/doc/src/dynamicview-tutorial.qdoc4
-rw-r--r--src/quick/doc/src/examples.qdoc18
-rw-r--r--src/quick/doc/src/tutorial.qdoc4
-rw-r--r--src/quick/doc/src/whatsnew.qdoc9
-rw-r--r--src/quick/items/context2d/qquickcanvasitem.cpp46
-rw-r--r--src/quick/items/context2d/qquickcontext2d.cpp15
-rw-r--r--src/quick/items/context2d/qquickcontext2d_p.h5
-rw-r--r--src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp2
-rw-r--r--src/quick/items/qquickanimatedsprite.cpp58
-rw-r--r--src/quick/items/qquickdrag.cpp16
-rw-r--r--src/quick/items/qquickdroparea.cpp24
-rw-r--r--src/quick/items/qquickflickable.cpp46
-rw-r--r--src/quick/items/qquickframebufferobject.cpp4
-rw-r--r--src/quick/items/qquickgridview.cpp29
-rw-r--r--src/quick/items/qquickimage.cpp14
-rw-r--r--src/quick/items/qquickimagebase.cpp73
-rw-r--r--src/quick/items/qquickimagebase_p.h4
-rw-r--r--src/quick/items/qquickimagebase_p_p.h2
-rw-r--r--src/quick/items/qquickitem.cpp276
-rw-r--r--src/quick/items/qquickitemsmodule.cpp8
-rw-r--r--src/quick/items/qquickitemview.cpp12
-rw-r--r--src/quick/items/qquicklistview.cpp50
-rw-r--r--src/quick/items/qquickloader.cpp9
-rw-r--r--src/quick/items/qquickmousearea.cpp122
-rw-r--r--src/quick/items/qquickmultipointtoucharea.cpp48
-rw-r--r--src/quick/items/qquickpathview.cpp44
-rw-r--r--src/quick/items/qquickpincharea.cpp155
-rw-r--r--src/quick/items/qquickrendercontrol.cpp32
-rw-r--r--src/quick/items/qquickrendercontrol_p.h2
-rw-r--r--src/quick/items/qquickrepeater.cpp14
-rw-r--r--src/quick/items/qquickscreen.cpp8
-rw-r--r--src/quick/items/qquicktext.cpp20
-rw-r--r--src/quick/items/qquicktextcontrol.cpp46
-rw-r--r--src/quick/items/qquicktextcontrol_p.h1
-rw-r--r--src/quick/items/qquicktextedit.cpp20
-rw-r--r--src/quick/items/qquicktextedit_p.h3
-rw-r--r--src/quick/items/qquicktextinput.cpp22
-rw-r--r--src/quick/items/qquicktextinput_p.h4
-rw-r--r--src/quick/items/qquickview.cpp10
-rw-r--r--src/quick/items/qquickview_p.h4
-rw-r--r--src/quick/items/qquickwindow.cpp63
-rw-r--r--src/quick/items/qquickwindowmodule.cpp31
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp17
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h2
-rw-r--r--src/quick/scenegraph/coreapi/qsggeometry.cpp3
-rw-r--r--src/quick/scenegraph/coreapi/qsgmaterial.cpp11
-rw-r--r--src/quick/scenegraph/coreapi/qsgnode.cpp19
-rw-r--r--src/quick/scenegraph/coreapi/qsgrenderer_p.h2
-rw-r--r--src/quick/scenegraph/qsgcontext.cpp41
-rw-r--r--src/quick/scenegraph/qsgcontext_p.h3
-rw-r--r--src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp6
-rw-r--r--src/quick/scenegraph/qsgdefaultimagenode.cpp19
-rw-r--r--src/quick/scenegraph/qsgdefaultrectanglenode.cpp20
-rw-r--r--src/quick/scenegraph/qsgrenderloop.cpp48
-rw-r--r--src/quick/scenegraph/qsgrenderloop_p.h12
-rw-r--r--src/quick/scenegraph/qsgthreadedrenderloop.cpp20
-rw-r--r--src/quick/scenegraph/qsgthreadedrenderloop_p.h1
-rw-r--r--src/quick/scenegraph/qsgwindowsrenderloop.cpp8
-rw-r--r--src/quick/scenegraph/util/qsgatlastexture.cpp21
-rw-r--r--src/quick/scenegraph/util/qsgdepthstencilbuffer.cpp13
-rw-r--r--src/quick/scenegraph/util/qsgsimplematerial.cpp6
-rw-r--r--src/quick/scenegraph/util/qsgsimpletexturenode.cpp2
-rw-r--r--src/quick/scenegraph/util/qsgtexture.cpp18
-rw-r--r--src/quick/scenegraph/util/qsgtexturematerial.cpp29
-rw-r--r--src/quick/util/qquickanimation.cpp74
-rw-r--r--src/quick/util/qquickanimation_p_p.h14
-rw-r--r--src/quick/util/qquickglobal.cpp52
-rw-r--r--src/quick/util/qquickpath.cpp4
-rw-r--r--src/quick/util/qquickprofiler.cpp13
-rw-r--r--src/quick/util/qquickprofiler_p.h21
-rw-r--r--src/quick/util/qquickpropertychanges.cpp64
-rw-r--r--src/quick/util/qquickpropertychanges_p.h4
-rw-r--r--src/quick/util/qquicksmoothedanimation.cpp7
-rw-r--r--src/quick/util/qquicksmoothedanimation_p_p.h1
-rw-r--r--src/quick/util/qquickspringanimation.cpp10
-rw-r--r--src/quick/util/qquickstyledtext.cpp2
-rw-r--r--src/quick/util/qquicktimeline.cpp5
-rw-r--r--src/quick/util/qquicktimeline_p_p.h1
88 files changed, 1471 insertions, 651 deletions
diff --git a/src/quick/designer/designersupport.cpp b/src/quick/designer/designersupport.cpp
index e0b4bd41e5..82f796361b 100644
--- a/src/quick/designer/designersupport.cpp
+++ b/src/quick/designer/designersupport.cpp
@@ -94,7 +94,10 @@ void DesignerSupport::refFromEffectItem(QQuickItem *referencedItem, bool hide)
texture->setSize(referencedItem->boundingRect().size().toSize());
texture->setRecursive(true);
#ifndef QT_OPENGL_ES
- texture->setFormat(GL_RGBA8);
+ if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL)
+ texture->setFormat(GL_RGBA8);
+ else
+ texture->setFormat(GL_RGBA);
#else
texture->setFormat(GL_RGBA);
#endif
diff --git a/src/quick/doc/images/visualize-batches.png b/src/quick/doc/images/visualize-batches.png
new file mode 100644
index 0000000000..eb6ebe3606
--- /dev/null
+++ b/src/quick/doc/images/visualize-batches.png
Binary files differ
diff --git a/src/quick/doc/images/visualize-clip.png b/src/quick/doc/images/visualize-clip.png
new file mode 100644
index 0000000000..0a67b308cc
--- /dev/null
+++ b/src/quick/doc/images/visualize-clip.png
Binary files differ
diff --git a/src/quick/doc/images/visualize-original.png b/src/quick/doc/images/visualize-original.png
new file mode 100644
index 0000000000..00a2de2e4b
--- /dev/null
+++ b/src/quick/doc/images/visualize-original.png
Binary files differ
diff --git a/src/quick/doc/images/visualize-overdraw-1.png b/src/quick/doc/images/visualize-overdraw-1.png
new file mode 100644
index 0000000000..af2cf098d7
--- /dev/null
+++ b/src/quick/doc/images/visualize-overdraw-1.png
Binary files differ
diff --git a/src/quick/doc/images/visualize-overdraw-2.png b/src/quick/doc/images/visualize-overdraw-2.png
new file mode 100644
index 0000000000..6872074808
--- /dev/null
+++ b/src/quick/doc/images/visualize-overdraw-2.png
Binary files differ
diff --git a/src/quick/doc/qtquick.qdocconf b/src/quick/doc/qtquick.qdocconf
index 515263f079..edad14cfd4 100644
--- a/src/quick/doc/qtquick.qdocconf
+++ b/src/quick/doc/qtquick.qdocconf
@@ -44,7 +44,6 @@ sourcedirs += .. \
../../quickwidgets
exampledirs += ../../../examples/quick \
- ../../../examples/quickwidgets \
snippets
diff --git a/src/quick/doc/snippets/qml/xmlrole.qml b/src/quick/doc/snippets/qml/xmlrole.qml
index 0f75135da2..257594179a 100644
--- a/src/quick/doc/snippets/qml/xmlrole.qml
+++ b/src/quick/doc/snippets/qml/xmlrole.qml
@@ -52,7 +52,7 @@ XmlListModel {
//![1]
// XmlRole queries will be made on <book> elements
- query: "/catalogue/book"
+ query: "/catalog/book"
// query the book title
XmlRole { name: "title"; query: "title/string()" }
@@ -65,17 +65,22 @@ XmlListModel {
// query the book's first listed author (note in XPath the first index is 1, not 0)
XmlRole { name: "first_author"; query: "author[1]/string()" }
+
+ // query the wanted attribute as a boolean
+ XmlRole { name: "wanted"; query: "boolean(@wanted)" }
}
//![1]
+//![2]
ListView {
width: 300; height: 200
model: model
delegate: Column {
- Text { text: title + " (" + type + ")"; font.bold: true }
+ Text { text: title + " (" + type + ")"; font.bold: wanted }
Text { text: first_author }
Text { text: year }
}
+//![2]
}
}
diff --git a/src/quick/doc/snippets/qml/xmlrole.xml b/src/quick/doc/snippets/qml/xmlrole.xml
new file mode 100644
index 0000000000..70280e067d
--- /dev/null
+++ b/src/quick/doc/snippets/qml/xmlrole.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="iso-8859-1" ?>
+<catalog>
+ <book type="Online" wanted="true">
+ <title>Qt 5 Cadaques</title>
+ <year>2014</year>
+ <author>Juergen Bocklage-Ryannel</author>
+ <author>Johan Thelin</author>
+ </book>
+ <book type="Hardcover">
+ <title>C++ GUI Programming with Qt 4</title>
+ <year>2006</year>
+ <author>Jasmin Blanchette</author>
+ <author>Mark Summerfield</author>
+ </book>
+ <book type="Paperback">
+ <title>Programming with Qt</title>
+ <year>2002</year>
+ <author>Matthias Kalle Dalheimer</author>
+ </book>
+ </catalog>
diff --git a/src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc b/src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc
index 278733de8d..7a54b7a021 100644
--- a/src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc
+++ b/src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc
@@ -739,4 +739,121 @@ with multiple windows.
{QSG_RENDER_TIMING=1} will output a number of useful timing
parameters which can be useful in pinpointing where a problem lies.
+ \section1 Visualizing
+
+ To visualize the various aspects of the scene graph's default renderer, the
+ \c QSG_VISUALIZE environment variable can be set to one of the values
+ detailed in each section below. We provide examples of the output of
+ some of the variables using the following QML code:
+
+ \code
+ import QtQuick 2.2
+
+ Rectangle {
+ width: 200
+ height: 140
+
+ ListView {
+ id: clippedList
+ x: 20
+ y: 20
+ width: 70
+ height: 100
+ clip: true
+ model: ["Item A", "Item B", "Item C", "Item D"]
+
+ delegate: Rectangle {
+ color: "lightblue"
+ width: parent.width
+ height: 25
+
+ Text {
+ text: modelData
+ anchors.fill: parent
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ }
+ }
+ }
+
+ ListView {
+ id: clippedDelegateList
+ x: clippedList.x + clippedList.width + 20
+ y: 20
+ width: 70
+ height: 100
+ clip: true
+ model: ["Item A", "Item B", "Item C", "Item D"]
+
+ delegate: Rectangle {
+ color: "lightblue"
+ width: parent.width
+ height: 25
+ clip: true
+
+ Text {
+ text: modelData
+ anchors.fill: parent
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ }
+ }
+ }
+ }
+ \endcode
+
+ For the ListView on the left, we set its \l {Item::clip}{clip} property to
+ \c true. For the ListView on right, we also set each delegate's
+ \l {Item::clip}{clip} property to \c true to illustrate the effects of
+ clipping on batching.
+
+ \image visualize-original.png "Original"
+ Original
+
+ \note The visualized elements do not respect clipping, and rendering order is
+ arbitrary.
+
+ \section2 Visualizing Batches
+
+ Setting \c QSG_VISUALIZE to \c batches visualizes batches in the renderer.
+ Merged batches are drawn with a solid color and unmerged batches are drawn
+ with a diagonal line pattern. Few unique colors means good batching.
+ Unmerged batches are bad if they contain many individual nodes.
+
+ \image visualize-batches.png "batches"
+ \c QSG_VISUALIZE=batches
+
+ \section2 Visualizing Clipping
+
+ Setting \c QSG_VISUALIZE to \c clip draws red areas on top of the scene
+ to indicate clipping. As Qt Quick Items do not clip by default, no clipping
+ is usually visualized.
+
+ \image visualize-clip.png
+ \c QSG_VISUALIZE=clip
+
+ \section2 Visualizing Changes
+
+ Setting \c QSG_VISUALIZE to \c changes visualizes changes in the renderer.
+ Changes in the scenegraph are visualized with a flashing overlay of a random
+ color. Changes on a primitive are visualized with a solid color, while
+ changes in an ancestor, such as matrix or opacity changes, are visualized
+ with a pattern.
+
+ \section2 Visualizing Overdraw
+
+ Setting \c QSG_VISUALIZE to \c overdraw visualizes overdraw in the renderer.
+ Visualize all items in 3D to highlight overdraws. This mode can also be used
+ to detect geometry outside the viewport to some extent. Opaque items are
+ rendered with a green tint, while translucent items are rendered with a red
+ tint. The bounding box for the viewport is rendered in blue. Opaque content
+ is easier for the scenegraph to process and is usually faster to render.
+
+ Note that the root rectangle in the code above is superfluous as the window
+ is also white, so drawing the rectangle is a waste of resources in this case.
+ Changing it to an Item can give a slight performance boost.
+
+ \image visualize-overdraw-1.png "overdraw-1"
+ \image visualize-overdraw-2.png "overdraw-2"
+ \c QSG_VISUALIZE=overdraw
*/
diff --git a/src/quick/doc/src/dynamicview-tutorial.qdoc b/src/quick/doc/src/dynamicview-tutorial.qdoc
index 2f07b7b234..cf1115cf4a 100644
--- a/src/quick/doc/src/dynamicview-tutorial.qdoc
+++ b/src/quick/doc/src/dynamicview-tutorial.qdoc
@@ -109,8 +109,8 @@ the view and cannot be moved by other means.
Dragging the content item is enabled by binding it to the MouseArea's
\l {QtQuick::MouseArea::drag.target}{drag.target} property. Because we still want the view to be
-flickable we wait until the MouseArea's \l {QtQuick::MouseArea::onPressAndHold}{onPressAndHold}
-handler is triggered before binding the drag target. This way when mouse moves before the hold
+flickable we wait until the MouseArea's \l {QtQuick::MouseArea::}{pressAndHold}
+signal is emitted before binding the drag target. This way when mouse moves before the hold
timeout has expired it is interpreted as moving the list and if it moves after it is interpreted as
dragging an item. To make it more obvious to the user when an item can be dragged we'll change the
background color of the content item when the timeout has expired.
diff --git a/src/quick/doc/src/examples.qdoc b/src/quick/doc/src/examples.qdoc
index def50ecd60..22c9786fda 100644
--- a/src/quick/doc/src/examples.qdoc
+++ b/src/quick/doc/src/examples.qdoc
@@ -74,7 +74,7 @@ steps such as use cases and introductory material. For more information about Qt
\div {class="landingicons"}
\div {class="icons1of3"}
- \bold{Development Environment}
+ \b{Development Environment}
\list
\li \l{Qt Creator: Creating Qt Quick Projects}{Creating Qt Quick Projects}
\li \l{Qt Creator: Using Qt Quick Designer}{Using Qt Quick Designer}
@@ -85,7 +85,7 @@ steps such as use cases and introductory material. For more information about Qt
\endlist
\enddiv
\div {class="icons1of3"}
- \bold{Beginning with QML and Qt Quick}
+ \b{Beginning with QML and Qt Quick}
\list
\li \l{First Steps with QML}
\li \l{Getting Started Programming with Qt Quick}{Qt Quick Text Editor}
@@ -93,7 +93,7 @@ steps such as use cases and introductory material. For more information about Qt
\endlist
\enddiv
\div {class="icons1of3"}
- \bold{Use Cases}
+ \b{Use Cases}
\list
\li \l{qtquick-usecase-visual.html}{Visual types in QML}
\li \l{qtquick-usecase-userinput.html}{Responding to User Input in QML}
@@ -124,7 +124,7 @@ the examples from within Qt Creator.
\div {class="landingicons"}
\div {class="icons1of3"}
- \bold{QML Types and Controls}
+ \b{QML Types and Controls}
\list
\li \l{Qt Quick Controls - Gallery}{Controls Gallery}
\li \l{Qt Quick System Dialog Examples}{Dialog Examples}
@@ -135,7 +135,7 @@ the examples from within Qt Creator.
\endlist
\enddiv
\div {class="icons1of3"}
- \bold{Layouts and Views}
+ \b{Layouts and Views}
\list
\li \l{Qt Quick Controls - Basic Layouts Example}{Basic Layouts}
\li \l{Qt Quick Examples - Positioners}{Positioners}
@@ -145,7 +145,7 @@ the examples from within Qt Creator.
\endlist
\enddiv
\div {class="icons1of3"}
- \bold{Image and Graphics}
+ \b{Image and Graphics}
\list
\li \l{Qt Quick Examples - Image Elements}{Image Elements}
\li \l{Qt Quick Examples - Animation}{Animation}
@@ -157,7 +157,7 @@ the examples from within Qt Creator.
\div {class="landingicons"}
\div {class="icons1of3"}
- \bold{Keyboard, Focus, and Touch}
+ \b{Keyboard, Focus, and Touch}
\list
\li \l{Qt Quick Examples - Key Interaction}{Key Interaction}
\li \l{Qt Quick Examples - MouseArea}{MouseArea}
@@ -165,7 +165,7 @@ the examples from within Qt Creator.
\endlist
\enddiv
\div {class="icons1of3"}
- \bold{System and Events}
+ \b{System and Events}
\list
\li \l{Qt Quick Examples - Threading}{Threading}
\li \l{Qt Quick Examples - Accessibility}{Accessibility}
@@ -174,7 +174,7 @@ the examples from within Qt Creator.
\endlist
\enddiv
\div {class="icons1of3"}
- \bold{Scene Graph}
+ \b{Scene Graph}
\list
\li \l{Scene Graph - OpenGL Under QML}{OpenGL Under QML}
\li \l{Scene Graph - Painted Item}{Painted Item}
diff --git a/src/quick/doc/src/tutorial.qdoc b/src/quick/doc/src/tutorial.qdoc
index e0c05b16a8..75ca1b8d55 100644
--- a/src/quick/doc/src/tutorial.qdoc
+++ b/src/quick/doc/src/tutorial.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the documentation of the Qt Toolkit.
@@ -31,7 +31,7 @@
\brief An introduction to the basic concepts and features of QML.
\nextpage QML Tutorial 1 - Basic Types
-This tutorial gives an introduction to QML, the declarative language for Qt Quick. It doesn't cover everything;
+This tutorial gives an introduction to QML, the language for Qt Quick UIs. It doesn't cover everything;
the emphasis is on teaching the key principles, and features are introduced as needed.
Through the different steps of this tutorial we will learn about QML basic types, we will create our own QML component
diff --git a/src/quick/doc/src/whatsnew.qdoc b/src/quick/doc/src/whatsnew.qdoc
index f50e80edf6..ca2a2156d8 100644
--- a/src/quick/doc/src/whatsnew.qdoc
+++ b/src/quick/doc/src/whatsnew.qdoc
@@ -53,7 +53,6 @@ features introduced by the new import and new classes in Qt 5.1:
\endlist
These types are kept due to compatibility reasons and are replaced by the
\l{Qt QML Models QML Types}{Qt QML Models} types.
- \endlist
\endlist
\section2 New Submodules
@@ -216,7 +215,7 @@ relative to its start.
\list
\li \c Text.RightElide is now supported where text spans multiple lines.
\li New \l{Text::}{linkColor} property controls the color of linked text.
- \li New \l{Text::}{onLineLaidOut} handler is called for every line during the layout process to
+ \li New \l{Text::}{lineLaidOut} signal is emitted for every line during the layout process to
give the option of positioning and/or resizing lines as they are laid out.
\li New \l{Text::}{doLayout()} method will trigger the text layout from Javascript.
\li New \l{Text::}{fontSizeMode} property allows text to be fitted to the item size.
@@ -250,9 +249,9 @@ the window loses focus.
\list
\li Wheel events are now supported; events are provided through the new WheelEvent type.
\li New \l{MouseArea::}{propagateComposedEvents} property sets whether composed events are
- propagated to other mouse areas. If this property is true and the l{MouseArea::onClicked}{clicked},
- \l{MouseArea::onDoubleClicked}{doubleClicked} or \l{MouseArea::onPressAndHold}{pressAndHold}
- handlers reject a mouse event, the event will be propagated to overlapping MouseArea items
+ propagated to other mouse areas. If this property is true and the handlers of the
+ \l{MouseArea::}{clicked}, \l{MouseArea::}{doubleClicked} or \l{MouseArea::}{pressAndHold}
+ signals reject a mouse event, the event will be propagated to overlapping MouseArea items
in the same area that are lower in the stacking order.
\li New \l{MouseArea::}{cursorShape} property controls the cursor shape.
\endlist
diff --git a/src/quick/items/context2d/qquickcanvasitem.cpp b/src/quick/items/context2d/qquickcanvasitem.cpp
index 17adf1b66b..7d3be0865b 100644
--- a/src/quick/items/context2d/qquickcanvasitem.cpp
+++ b/src/quick/items/context2d/qquickcanvasitem.cpp
@@ -271,10 +271,10 @@ QQuickCanvasItemPrivate::~QQuickCanvasItemPrivate()
\li Replace all HTML event handlers with the MouseArea item.
\li Change setInterval/setTimeout function calls with the \l Timer item or
the use of requestAnimationFrame().
- \li Place painting code into the onPaint handler and trigger
+ \li Place painting code into the \c onPaint handler and trigger
painting by calling the markDirty() or requestPaint() methods.
\li To draw images, load them by calling the Canvas's loadImage() method and then request to paint
- them in the onImageLoaded handler.
+ them in the \c onImageLoaded handler.
\endlist
\sa Context2D
@@ -590,8 +590,10 @@ void QQuickCanvasItem::geometryChanged(const QRectF &newGeometry, const QRectF &
emit canvasWindowChanged();
}
- if (d->available && newSize != oldGeometry.size())
- requestPaint();
+ if (d->available && newSize != oldGeometry.size()) {
+ if (isVisible() || (d->extra.isAllocated() && d->extra->effectRefCount > 0))
+ requestPaint();
+ }
}
void QQuickCanvasItem::releaseResources()
@@ -640,9 +642,6 @@ void QQuickCanvasItem::updatePolish()
QQuickItem::updatePolish();
Q_D(QQuickCanvasItem);
- if (!isVisible() && !(d->extra.isAllocated() && d->extra->effectRefCount>0))
- return;
-
if (d->context && d->renderStrategy != QQuickCanvasItem::Cooperative)
d->context->prepare(d->canvasSize.toSize(), d->tileSize, d->canvasWindow.toRect(), d->dirtyRect.toRect(), d->smooth, antialiasing());
@@ -844,10 +843,9 @@ void QQuickCanvasItem::requestPaint()
\qmlmethod QtQuick::Canvas::markDirty(rect area)
Mark the given \a area as dirty, so that when this area is visible the
- canvas renderer will redraw it. This will trigger the onPaint signal
- handler function.
+ canvas renderer will redraw it. This will trigger the \c paint signal.
- \sa onPaint, requestPaint()
+ \sa paint, requestPaint()
*/
void QQuickCanvasItem::markDirty(const QRectF& rect)
@@ -897,9 +895,11 @@ QQmlRefPointer<QQuickCanvasPixmap> QQuickCanvasItem::loadedPixmap(const QUrl& ur
}
/*!
- \qmlsignal QtQuick::Canvas::onImageLoaded()
+ \qmlsignal QtQuick::Canvas::imageLoaded()
- This handler is called when an image has been loaded.
+ This signal is emitted when an image has been loaded.
+
+ The corresponding handler is \c onImageLoaded.
\sa loadImage()
*/
@@ -908,11 +908,11 @@ QQmlRefPointer<QQuickCanvasPixmap> QQuickCanvasItem::loadedPixmap(const QUrl& ur
\qmlmethod QtQuick::Canvas::loadImage(url image)
Loads the given \c image asynchronously.
- When the image is ready, onImageLoaded will be emitted.
+ When the image is ready, \l imageLoaded will be emitted.
The loaded image can be unloaded by the unloadImage() method.
Note: Only loaded images can be painted on the Canvas item.
- \sa unloadImage, onImageLoaded, isImageLoaded(),
+ \sa unloadImage, imageLoaded, isImageLoaded(),
Context2D::createImageData(), Context2D::drawImage()
*/
void QQuickCanvasItem::loadImage(const QUrl& url)
@@ -939,7 +939,7 @@ void QQuickCanvasItem::loadImage(const QUrl& url)
Once an image is unloaded it cannot be painted by the canvas context
unless it is loaded again.
- \sa loadImage(), onImageLoaded, isImageLoaded(),
+ \sa loadImage(), imageLoaded, isImageLoaded(),
Context2D::createImageData(), Context2D::drawImage
*/
void QQuickCanvasItem::unloadImage(const QUrl& url)
@@ -1099,20 +1099,24 @@ QRect QQuickCanvasItem::tiledRect(const QRectF &window, const QSize &tileSize)
}
/*!
- \qmlsignal QtQuick::Canvas::onPaint(rect region)
+ \qmlsignal QtQuick::Canvas::paint(rect region)
- This handler is called to render the \a region. If a context is active it
- can be referenced from the context property.
+ This signal is emitted when the \a region needs to be rendered. If a context
+ is active it can be referenced from the context property.
- This signal can be triggered markdirty(), requestPaint() or by changing
+ This signal can be triggered by markdirty(), requestPaint() or by changing
the current canvas window.
+
+ The corresponding handler is \c onPaint.
*/
/*!
- \qmlsignal QtQuick::Canvas::onPainted()
+ \qmlsignal QtQuick::Canvas::painted()
- This handler is called after all context painting commands are executed and
+ This signal is emitted after all context painting commands are executed and
the Canvas has been rendered.
+
+ The corresponding handler is \c onPainted.
*/
QT_END_NAMESPACE
diff --git a/src/quick/items/context2d/qquickcontext2d.cpp b/src/quick/items/context2d/qquickcontext2d.cpp
index 9851983201..2a6eae71f7 100644
--- a/src/quick/items/context2d/qquickcontext2d.cpp
+++ b/src/quick/items/context2d/qquickcontext2d.cpp
@@ -2916,7 +2916,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_measureText(QV4::CallConte
\sa Image
\sa Canvas::loadImage
\sa Canvas::isImageLoaded
- \sa Canvas::onImageLoaded
+ \sa Canvas::imageLoaded
\sa {http://www.w3.org/TR/2dcontext/#dom-context-2d-drawimage}{W3C 2d context standard for drawImage}
*/
@@ -2936,7 +2936,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_measureText(QV4::CallConte
\sa Image
\sa Canvas::loadImage()
\sa Canvas::isImageLoaded
- \sa Canvas::onImageLoaded
+ \sa Canvas::imageLoaded
\sa {http://www.w3.org/TR/2dcontext/#dom-context-2d-drawimage}{W3C 2d context standard for drawImage}
*/
@@ -2957,7 +2957,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_measureText(QV4::CallConte
\sa Image
\sa Canvas::loadImage()
\sa Canvas::isImageLoaded
- \sa Canvas::onImageLoaded
+ \sa Canvas::imageLoaded
\sa {http://www.w3.org/TR/2dcontext/#dom-context-2d-drawimage}{W3C 2d context standard for drawImage}
*/
@@ -3175,8 +3175,11 @@ QV4::ReturnedValue QQuickJSContext2DPixelData::getIndexed(QV4::Managed *m, uint
QV4::ExecutionEngine *v4 = m->engine();
QV4::Scope scope(v4);
QV4::Scoped<QQuickJSContext2DPixelData> r(scope, m->as<QQuickJSContext2DPixelData>());
- if (!m)
+ if (!m) {
+ if (hasProperty)
+ *hasProperty = false;
return m->engine()->currentContext()->throwTypeError();
+ }
if (r && index < static_cast<quint32>(r->image.width() * r->image.height() * 4)) {
if (hasProperty)
@@ -4136,7 +4139,9 @@ void QQuickContext2D::init(QQuickCanvasItem *canvasItem, const QVariantMap &args
if (m_renderTarget == QQuickCanvasItem::FramebufferObject && renderThread != sceneGraphThread) {
QOpenGLContext *cc = QQuickWindowPrivate::get(window)->context->openglContext();
- m_surface = window;
+ m_surface.reset(new QOffscreenSurface);
+ m_surface->setFormat(window->format());
+ m_surface->create();
m_glContext = new QOpenGLContext;
m_glContext->setFormat(cc->format());
m_glContext->setShareContext(cc);
diff --git a/src/quick/items/context2d/qquickcontext2d_p.h b/src/quick/items/context2d/qquickcontext2d_p.h
index 4390ae62cc..ab851d302f 100644
--- a/src/quick/items/context2d/qquickcontext2d_p.h
+++ b/src/quick/items/context2d/qquickcontext2d_p.h
@@ -49,6 +49,7 @@
#include <private/qquickcanvasitem_p.h>
#include <QtGui/qpainter.h>
#include <QtGui/qpainterpath.h>
+#include <QtGui/qoffscreensurface.h>
#include <QtCore/qstring.h>
#include <QtCore/qstack.h>
#include <QtCore/qqueue.h>
@@ -229,7 +230,7 @@ public:
QQmlRefPointer<QQuickCanvasPixmap> createPixmap(const QUrl& url);
QOpenGLContext *glContext() { return m_glContext; }
- QSurface *surface() { return m_surface; }
+ QSurface *surface() { return m_surface.data(); }
void setGrabbedImage(const QImage& grab);
State state;
@@ -241,7 +242,7 @@ public:
QV4::PersistentValue m_strokeStyle;
QV4::PersistentValue m_v4path;
QV8Engine *m_v8engine;
- QSurface *m_surface;
+ QScopedPointer<QOffscreenSurface> m_surface;
QOpenGLContext *m_glContext;
QV4::PersistentValue m_v4value;
QQuickContext2DTexture *m_texture;
diff --git a/src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp b/src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp
index 06a0713365..5697c25ff0 100644
--- a/src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp
+++ b/src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp
@@ -214,6 +214,8 @@ void QQuickContext2DCommandBuffer::setPainterState(QPainter* p, const QQuickCont
if (state.globalCompositeOperation != p->compositionMode())
p->setCompositionMode(state.globalCompositeOperation);
+
+ p->setClipPath(state.clipPath);
}
static void qt_drawImage(QPainter *p, QQuickContext2D::State& state, QImage image, const QRectF& sr, const QRectF& dr, bool shadow = false)
diff --git a/src/quick/items/qquickanimatedsprite.cpp b/src/quick/items/qquickanimatedsprite.cpp
index 64b8f257dc..bfe957e943 100644
--- a/src/quick/items/qquickanimatedsprite.cpp
+++ b/src/quick/items/qquickanimatedsprite.cpp
@@ -596,7 +596,10 @@ void QQuickAnimatedSprite::prepareNextFrame()
qreal frameDuration = m_spriteEngine->spriteDuration()/frameCount;
if (frameDuration > 0) {
qreal frame = (time - animT)/(frameDuration / 1000.0);
- frame = qBound(qreal(0.0), frame, frameCount - qreal(1.0));//Stop at count-1 frames until we have between anim interpolation
+ bool lastLoop = m_loops > 0 && m_curLoop == m_loops-1;
+ //don't visually interpolate for the last frame of the last loop
+ qreal max = lastLoop ? frameCount - qreal(1.0) : frameCount;
+ frame = qBound(qreal(0.0), frame, max);
progress = modf(frame,&frameAt);
if (m_curFrame > frameAt) //went around
m_curLoop++;
@@ -623,21 +626,54 @@ void QQuickAnimatedSprite::prepareNextFrame()
}
if (m_curFrame != lastFrame && isCurrentFrameChangedConnected())
emit currentFrameChanged(m_curFrame);
- if (m_spriteEngine->sprite()->reverse())
- frameAt = (m_spriteEngine->spriteFrames() - 1) - frameAt;
- qreal y = m_spriteEngine->spriteY() / m_sheetSize.height();
+
+ qreal frameCount = m_spriteEngine->spriteFrames();
+ bool reverse = m_spriteEngine->sprite()->reverse();
+ if (reverse)
+ frameAt = (frameCount - 1) - frameAt;
+
qreal w = m_spriteEngine->spriteWidth() / m_sheetSize.width();
qreal h = m_spriteEngine->spriteHeight() / m_sheetSize.height();
- qreal x1 = m_spriteEngine->spriteX() / m_sheetSize.width();
- x1 += frameAt * w;
- qreal x2 = x1;
- if (frameAt < (m_spriteEngine->spriteFrames()-1))
- x2 += w;
+ qreal x1 = m_spriteEngine->spriteX() / m_sheetSize.width() + frameAt * w;
+ qreal y1 = m_spriteEngine->spriteY() / m_sheetSize.height();
+
+ //### hard-coded 0/1 work because we are the only
+ // images in the sprite sheet (without this we cannot assume
+ // where in the sheet we begin/end).
+ qreal x2;
+ qreal y2;
+ if (reverse) {
+ if (frameAt > 0) {
+ x2 = x1 - w;
+ y2 = y1;
+ } else {
+ x2 = 1.0 - w;
+ y2 = y1 - h;
+ if (y2 < 0.0) {
+ //the last row may not fill the entire width
+ int maxRowFrames = m_sheetSize.width() / m_spriteEngine->spriteWidth();
+ if (m_spriteEngine->maxFrames() % maxRowFrames)
+ x2 = ((m_spriteEngine->maxFrames() % maxRowFrames) - 1) * w;
+
+ y2 = 1.0 - h;
+ }
+ }
+ } else {
+ if (frameAt < (frameCount-1)) {
+ x2 = x1 + w;
+ y2 = y1;
+ } else {
+ x2 = 0.0;
+ y2 = y1 + h;
+ if (y2 >= 1.0)
+ y2 = 0.0;
+ }
+ }
m_material->animX1 = x1;
- m_material->animY1 = y;
+ m_material->animY1 = y1;
m_material->animX2 = x2;
- m_material->animY2 = y;
+ m_material->animY2 = y2;
m_material->animW = w;
m_material->animH = h;
m_material->animT = m_interpolate ? progress : 0.0;
diff --git a/src/quick/items/qquickdrag.cpp b/src/quick/items/qquickdrag.cpp
index 605c485f6b..6c36032d3c 100644
--- a/src/quick/items/qquickdrag.cpp
+++ b/src/quick/items/qquickdrag.cpp
@@ -523,7 +523,7 @@ void QQuickDragAttached::setProposedAction(Qt::DropAction action)
\endlist
When using \c Drag.Automatic you should also define \l mimeData and bind the
- \active property to the active property of \l MouseArea.drag.
+ \l active property to the active property of \l MouseArea.drag.
*/
QQuickDrag::DragType QQuickDragAttached::dragType() const
@@ -694,17 +694,21 @@ void QQuickDragAttached::cancel()
}
/*!
- \qmlattachedsignal QtQuick::Drag::onDragStarted()
+ \qmlattachedsignal QtQuick::Drag::dragStarted()
- This handler is called when a drag is started with the \l startDrag method
+ This signal is emitted when a drag is started with the \l startDrag() method
or when it is started automatically using the \l dragType property.
+
+ The corresponding handler is \c onDragStarted.
*/
/*!
- \qmlattachedsignal QtQuick::Drag::onDragFinished(DropAction action)
+ \qmlattachedsignal QtQuick::Drag::dragFinished(DropAction action)
+
+ This signal is emitted when a drag finishes and the drag was started with the
+ \l startDrag() method or started automatically using the \l dragType property.
- This handler is called when a drag finishes and the drag was started with the
- \l startDrag method or started automatically using the \l dragType property.
+ The corresponding handler is \c onDragFinished.
*/
Qt::DropAction QQuickDragAttachedPrivate::startDrag(Qt::DropActions supportedActions)
diff --git a/src/quick/items/qquickdroparea.cpp b/src/quick/items/qquickdroparea.cpp
index 57e500a150..23ee016941 100644
--- a/src/quick/items/qquickdroparea.cpp
+++ b/src/quick/items/qquickdroparea.cpp
@@ -208,9 +208,11 @@ qreal QQuickDropAreaDrag::y() const
}
/*!
- \qmlsignal QtQuick::DropArea::onPositionChanged(DragEvent drag)
+ \qmlsignal QtQuick::DropArea::positionChanged(DragEvent drag)
- This handler is called when the position of a drag has changed.
+ This signal is emitted when the position of a drag has changed.
+
+ The corresponding handler is \c onPositionChanged.
*/
void QQuickDropArea::dragMoveEvent(QDragMoveEvent *event)
@@ -249,9 +251,11 @@ QStringList QQuickDropAreaPrivate::getKeys(const QMimeData *mimeData) const
}
/*!
- \qmlsignal QtQuick::DropArea::onEntered(DragEvent drag)
+ \qmlsignal QtQuick::DropArea::entered(DragEvent drag)
+
+ This signal is emitted when a \a drag enters the bounds of a DropArea.
- This handler is called when a \a drag enters the bounds of a DropArea.
+ The corresponding handler is \c onEntered.
*/
void QQuickDropArea::dragEnterEvent(QDragEnterEvent *event)
@@ -282,9 +286,11 @@ void QQuickDropArea::dragEnterEvent(QDragEnterEvent *event)
}
/*!
- \qmlsignal QtQuick::DropArea::onExited()
+ \qmlsignal QtQuick::DropArea::exited()
- This handler is called when a drag exits the bounds of a DropArea.
+ This signal is emitted when a drag exits the bounds of a DropArea.
+
+ The corresponding handler is \c onExited.
*/
void QQuickDropArea::dragLeaveEvent(QDragLeaveEvent *)
@@ -303,10 +309,12 @@ void QQuickDropArea::dragLeaveEvent(QDragLeaveEvent *)
}
/*!
- \qmlsignal QtQuick::DropArea::onDropped(DragEvent drop)
+ \qmlsignal QtQuick::DropArea::dropped(DragEvent drop)
- This handler is called when a drop event occurs within the bounds of
+ This signal is emitted when a drop event occurs within the bounds of
a DropArea.
+
+ The corresponding handler is \c onDropped.
*/
void QQuickDropArea::dropEvent(QDropEvent *event)
diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp
index 77687cf72a..d1bad78d41 100644
--- a/src/quick/items/qquickflickable.cpp
+++ b/src/quick/items/qquickflickable.cpp
@@ -548,19 +548,23 @@ is finished.
*/
/*!
- \qmlsignal QtQuick::Flickable::onDragStarted()
+ \qmlsignal QtQuick::Flickable::dragStarted()
- This handler is called when the view starts to be dragged due to user
+ This signal is emitted when the view starts to be dragged due to user
interaction.
+
+ The corresponding handler is \c onDragStarted.
*/
/*!
- \qmlsignal QtQuick::Flickable::onDragEnded()
+ \qmlsignal QtQuick::Flickable::dragEnded()
- This handler is called when the user stops dragging the view.
+ This signal is emitted when the user stops dragging the view.
If the velocity of the drag is sufficient at the time the
touch/mouse button is released then a flick will start.
+
+ The corresponding handler is \c onDragEnded.
*/
/*!
@@ -615,34 +619,42 @@ is finished.
*/
/*!
- \qmlsignal QtQuick::Flickable::onMovementStarted()
+ \qmlsignal QtQuick::Flickable::movementStarted()
- This handler is called when the view begins moving due to user
+ This signal is emitted when the view begins moving due to user
interaction.
+
+ The corresponding handler is \c onMovementStarted.
*/
/*!
- \qmlsignal QtQuick::Flickable::onMovementEnded()
+ \qmlsignal QtQuick::Flickable::movementEnded()
- This handler is called when the view stops moving due to user
- interaction. If a flick was generated, this handler will
- be triggered once the flick stops. If a flick was not
- generated, the handler will be triggered when the
+ This signal is emitted when the view stops moving due to user
+ interaction. If a flick was generated, this signal will
+ be emitted once the flick stops. If a flick was not
+ generated, this signal will be emitted when the
user stops dragging - i.e. a mouse or touch release.
+
+ The corresponding handler is \c onMovementEnded.
*/
/*!
- \qmlsignal QtQuick::Flickable::onFlickStarted()
+ \qmlsignal QtQuick::Flickable::flickStarted()
- This handler is called when the view is flicked. A flick
+ This signal is emitted when the view is flicked. A flick
starts from the point that the mouse or touch is released,
while still in motion.
+
+ The corresponding handler is \c onFlickStarted.
*/
/*!
- \qmlsignal QtQuick::Flickable::onFlickEnded()
+ \qmlsignal QtQuick::Flickable::flickEnded()
- This handler is called when the view stops moving due to a flick.
+ This signal is emitted when the view stops moving due to a flick.
+
+ The corresponding handler is \c onFlickEnded.
*/
/*!
@@ -1725,9 +1737,9 @@ void QQuickFlickable::setRebound(QQuickTransition *transition)
and \l {Item::childrenRect.height}{childrenRect.height} properties
of the \l contentItem. For example, the previous snippet could be rewritten with:
- \qml
+ \code
contentWidth: contentItem.childrenRect.width; contentHeight: contentItem.childrenRect.height
- \endqml
+ \endcode
Though this assumes that the origin of the childrenRect is 0,0.
*/
diff --git a/src/quick/items/qquickframebufferobject.cpp b/src/quick/items/qquickframebufferobject.cpp
index 268c2d5342..10d281b7a1 100644
--- a/src/quick/items/qquickframebufferobject.cpp
+++ b/src/quick/items/qquickframebufferobject.cpp
@@ -70,7 +70,7 @@ public:
* for integrating OpenGL rendering using a framebuffer object (FBO)
* with Qt Quick.
*
- * On most platforms, the rendering will occur on a dedicated thread.
+ * On most platforms, the rendering will occur on a \l {Scene Graph and Rendering}{dedicated thread}.
* For this reason, the QQuickFramebufferObject class enforces a strict
* separation between the item implementation and the FBO rendering. All
* item logic, such as properties and UI-related helper functions needed by
@@ -99,7 +99,7 @@ public:
* to \c false and return a texture of your choosing from
* QQuickFramebufferObject::Renderer::createFramebufferObject().
*
- * \sa {Scene Graph - Rendering FBOs}
+ * \sa {Scene Graph - Rendering FBOs}, {Scene Graph and Rendering}
*/
/*!
diff --git a/src/quick/items/qquickgridview.cpp b/src/quick/items/qquickgridview.cpp
index e7b1437cf3..82658c73fc 100644
--- a/src/quick/items/qquickgridview.cpp
+++ b/src/quick/items/qquickgridview.cpp
@@ -1305,16 +1305,20 @@ void QQuickGridView::setHighlightFollowsCurrentItem(bool autoHighlight)
*/
/*!
- \qmlattachedsignal QtQuick::GridView::onAdd()
- This attached handler is called immediately after an item is added to the view.
+ \qmlattachedsignal QtQuick::GridView::add()
+ This attached signal is emitted immediately after an item is added to the view.
+
+ The corresponding handler is \c onAdd.
*/
/*!
- \qmlattachedsignal QtQuick::GridView::onRemove()
- This attached handler is called immediately before an item is removed from the view.
+ \qmlattachedsignal QtQuick::GridView::remove()
+ This attached signal is emitted immediately before an item is removed from the view.
If a \l remove transition has been specified, it is applied after
- this signal handler is called, providing that delayRemove is false.
+ this signal is handled, providing that \l delayRemove is false.
+
+ The corresponding handler is \c onRemove.
*/
@@ -1345,6 +1349,8 @@ void QQuickGridView::setHighlightFollowsCurrentItem(bool autoHighlight)
The item size of the GridView is determined by cellHeight and cellWidth. It will not resize the items
based on the size of the root item in the delegate.
+ The default \l {QQuickItem::z}{stacking order} of delegate instances is \c 1.
+
\note Delegates are instantiated as needed and may be destroyed at any time.
State should \e never be stored in a delegate.
*/
@@ -1373,6 +1379,8 @@ void QQuickGridView::setHighlightFollowsCurrentItem(bool autoHighlight)
The highlightItem is managed by the view unless
\l highlightFollowsCurrentItem is set to false.
+ The default \l {QQuickItem::z}{stacking order}
+ of the highlight item is \c 0.
\sa highlight, highlightFollowsCurrentItem
*/
@@ -1391,6 +1399,7 @@ void QQuickGridView::setHighlightFollowsCurrentItem(bool autoHighlight)
An instance of the highlight component is created for each view.
The geometry of the resulting component instance will be managed by the view
so as to stay with the current item, unless the highlightFollowsCurrentItem property is false.
+ The default \l {QQuickItem::z}{stacking order} of the highlight item is \c 0.
\sa highlightItem, highlightFollowsCurrentItem
*/
@@ -1691,7 +1700,8 @@ void QQuickGridView::setSnapMode(SnapMode mode)
This property holds the component to use as the footer.
An instance of the footer component is created for each view. The
- footer is positioned at the end of the view, after any items.
+ footer is positioned at the end of the view, after any items. The
+ default \l {QQuickItem::z}{stacking order} of the footer is \c 1.
\sa header, footerItem
*/
@@ -1701,6 +1711,7 @@ void QQuickGridView::setSnapMode(SnapMode mode)
An instance of the header component is created for each view. The
header is positioned at the beginning of the view, before any items.
+ The default \l {QQuickItem::z}{stacking order} of the header is \c 1.
\sa footer, headerItem
*/
@@ -1711,6 +1722,7 @@ void QQuickGridView::setSnapMode(SnapMode mode)
An instance of the header component is created for each view. The
header is positioned at the beginning of the view, before any items.
+ The default \l {QQuickItem::z}{stacking order} of the header is \c 1.
\sa header, footerItem
*/
@@ -1720,7 +1732,8 @@ void QQuickGridView::setSnapMode(SnapMode mode)
This holds the footer item created from the \l footer component.
An instance of the footer component is created for each view. The
- footer is positioned at the end of the view, after any items.
+ footer is positioned at the end of the view, after any items. The
+ default \l {QQuickItem::z}{stacking order} of the footer is \c 1.
\sa footer, headerItem
*/
@@ -1788,7 +1801,7 @@ void QQuickGridView::setSnapMode(SnapMode mode)
populated, or when the view's \l model changes. (In those cases, the \l populate transition is
applied instead.) Additionally, this transition should \e not animate the height of the new item;
doing so will cause any items beneath the new item to be laid out at the wrong position. Instead,
- the height can be animated within a \l {ListView::onAdd}{ListView.onAdd} in the delegate.
+ the height can be animated within the \l {add}{onAdd} handler in the delegate.
\sa addDisplaced, populate, ViewTransition
*/
diff --git a/src/quick/items/qquickimage.cpp b/src/quick/items/qquickimage.cpp
index 69a39d2396..08dbfa3c23 100644
--- a/src/quick/items/qquickimage.cpp
+++ b/src/quick/items/qquickimage.cpp
@@ -589,8 +589,8 @@ QSGNode *QQuickImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
QSGTexture::WrapMode hWrap = QSGTexture::ClampToEdge;
QSGTexture::WrapMode vWrap = QSGTexture::ClampToEdge;
- qreal pixWidth = (d->fillMode == PreserveAspectFit) ? d->paintedWidth : d->pix.width();
- qreal pixHeight = (d->fillMode == PreserveAspectFit) ? d->paintedHeight : d->pix.height();
+ qreal pixWidth = (d->fillMode == PreserveAspectFit) ? d->paintedWidth : d->pix.width() / d->devicePixelRatio;
+ qreal pixHeight = (d->fillMode == PreserveAspectFit) ? d->paintedHeight : d->pix.height() / d->devicePixelRatio;
int xOffset = 0;
if (d->hAlign == QQuickImage::AlignHCenter)
@@ -671,10 +671,12 @@ QSGNode *QQuickImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
break;
};
- QRectF nsrect(sourceRect.x() / d->pix.width(),
- sourceRect.y() / d->pix.height(),
- sourceRect.width() / d->pix.width(),
- sourceRect.height() / d->pix.height());
+ qreal nsWidth = (hWrap == QSGTexture::Repeat) ? d->pix.width() / d->devicePixelRatio : d->pix.width();
+ qreal nsHeight = (vWrap == QSGTexture::Repeat) ? d->pix.height() / d->devicePixelRatio : d->pix.height();
+ QRectF nsrect(sourceRect.x() / nsWidth,
+ sourceRect.y() / nsHeight,
+ sourceRect.width() / nsWidth,
+ sourceRect.height() / nsHeight);
if (targetRect.isEmpty()
|| !qIsFinite(targetRect.width()) || !qIsFinite(targetRect.height())
diff --git a/src/quick/items/qquickimagebase.cpp b/src/quick/items/qquickimagebase.cpp
index c842922dc6..66a56cc8bf 100644
--- a/src/quick/items/qquickimagebase.cpp
+++ b/src/quick/items/qquickimagebase.cpp
@@ -42,7 +42,10 @@
#include "qquickimagebase_p.h"
#include "qquickimagebase_p_p.h"
+#include <QtGui/qguiapplication.h>
+
#include <QtQml/qqmlinfo.h>
+#include <QtQml/qqmlfile.h>
QT_BEGIN_NAMESPACE
@@ -50,12 +53,14 @@ QQuickImageBase::QQuickImageBase(QQuickItem *parent)
: QQuickImplicitSizeItem(*(new QQuickImageBasePrivate), parent)
{
setFlag(ItemHasContents);
+ connect(this, SIGNAL(windowChanged(QQuickWindow*)), SLOT(handleWindowChanged(QQuickWindow*)));
}
QQuickImageBase::QQuickImageBase(QQuickImageBasePrivate &dd, QQuickItem *parent)
: QQuickImplicitSizeItem(dd, parent)
{
setFlag(ItemHasContents);
+ connect(this, SIGNAL(windowChanged(QQuickWindow*)), SLOT(handleWindowChanged(QQuickWindow*)));
}
QQuickImageBase::~QQuickImageBase()
@@ -208,7 +213,13 @@ void QQuickImageBase::load()
if (d->cache)
options |= QQuickPixmap::Cache;
d->pix.clear(this);
- d->pix.load(qmlEngine(this), d->url, d->sourcesize, options);
+
+ const qreal targetDevicePixelRatio = (window() ? window()->devicePixelRatio() : qApp->devicePixelRatio());
+ d->devicePixelRatio = 1.0;
+
+ QUrl loadUrl = d->url;
+ resolve2xLocalFile(d->url, targetDevicePixelRatio, &loadUrl, &d->devicePixelRatio);
+ d->pix.load(qmlEngine(this), loadUrl, d->sourcesize * d->devicePixelRatio, options);
if (d->pix.isLoading()) {
if (d->progress != 0.0) {
@@ -275,6 +286,19 @@ void QQuickImageBase::requestProgress(qint64 received, qint64 total)
}
}
+void QQuickImageBase::handleWindowChanged(QQuickWindow* window)
+{
+ if (window)
+ connect(window, SIGNAL(screenChanged(QScreen*)), this, SLOT(handleScreenChanged(QScreen*)));
+}
+
+void QQuickImageBase::handleScreenChanged(QScreen*)
+{
+ // Screen DPI might have changed, reload images on screen change.
+ if (isComponentComplete())
+ load();
+}
+
void QQuickImageBase::componentComplete()
{
Q_D(QQuickImageBase);
@@ -286,7 +310,52 @@ void QQuickImageBase::componentComplete()
void QQuickImageBase::pixmapChange()
{
Q_D(QQuickImageBase);
- setImplicitSize(d->pix.width(), d->pix.height());
+ setImplicitSize(d->pix.width() / d->devicePixelRatio, d->pix.height() / d->devicePixelRatio);
+}
+
+// /path/to/foo.png -> path/too/foo@2x.png
+static QString image2xPath(const QString &path)
+{
+ const int dotIndex = path.lastIndexOf(QLatin1Char('.'));
+ if (dotIndex == -1)
+ return path;
+ if (path.contains(QLatin1String("@2x.")))
+ return path;
+
+ QString retinaPath = path;
+ retinaPath.insert(dotIndex, QStringLiteral("@2x"));
+ return retinaPath;
+}
+
+void QQuickImageBase::resolve2xLocalFile(const QUrl &url, qreal targetDevicePixelRatio, QUrl *sourceUrl, qreal *sourceDevicePixelRatio)
+{
+ Q_ASSERT(sourceUrl);
+ Q_ASSERT(sourceDevicePixelRatio);
+
+ QString localFile = QQmlFile::urlToLocalFileOrQrc(url);
+
+ // Non-local file path: @2x loading is not supported.
+ if (localFile.isEmpty())
+ return;
+
+ // Special case: the url in the QML source refers directly to an "@2x" file.
+ if (localFile.contains(QLatin1String("@2x"))) {
+ *sourceDevicePixelRatio = qreal(2.0);
+ return;
+ }
+
+ // Don't load @2x files non normal-dpi displays.
+ if (!(targetDevicePixelRatio > qreal(1.0)))
+ return;
+
+ // Look for an @2x version
+ QString localFile2x = image2xPath(localFile);
+ if (!QFile(localFile2x).exists())
+ return;
+
+ // @2x file found found: Change url and devicePixelRatio
+ *sourceUrl = QUrl::fromLocalFile(localFile2x);
+ *sourceDevicePixelRatio = qreal(2.0);
}
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickimagebase_p.h b/src/quick/items/qquickimagebase_p.h
index 72258b4971..67f1e81cae 100644
--- a/src/quick/items/qquickimagebase_p.h
+++ b/src/quick/items/qquickimagebase_p.h
@@ -86,6 +86,8 @@ public:
virtual void setMirror(bool mirror);
bool mirror() const;
+ void resolve2xLocalFile(const QUrl &url, qreal targetDevicePixelRatio, QUrl *sourceUrl, qreal *sourceDevicePixelRatio);
+
Q_SIGNALS:
void sourceChanged(const QUrl &);
void sourceSizeChanged();
@@ -104,6 +106,8 @@ protected:
private Q_SLOTS:
virtual void requestFinished();
void requestProgress(qint64,qint64);
+ void handleWindowChanged(QQuickWindow *window);
+ void handleScreenChanged(QScreen *);
private:
Q_DISABLE_COPY(QQuickImageBase)
diff --git a/src/quick/items/qquickimagebase_p_p.h b/src/quick/items/qquickimagebase_p_p.h
index 395abf01fa..bb8778d789 100644
--- a/src/quick/items/qquickimagebase_p_p.h
+++ b/src/quick/items/qquickimagebase_p_p.h
@@ -69,6 +69,7 @@ public:
QQuickImageBasePrivate()
: status(QQuickImageBase::Null),
progress(0.0),
+ devicePixelRatio(1.0),
async(false),
cache(true),
mirror(false)
@@ -81,6 +82,7 @@ public:
qreal progress;
QSize sourcesize;
QSize oldSourceSize;
+ qreal devicePixelRatio;
bool async : 1;
bool cache : 1;
bool mirror: 1;
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index 2c89c32b45..03a78895cf 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -924,276 +924,354 @@ bool QQuickKeysAttached::isConnected(const char *signalName)
*/
/*!
- \qmlsignal QtQuick::Keys::onPressed(KeyEvent event)
+ \qmlsignal QtQuick::Keys::pressed(KeyEvent event)
- This handler is called when a key has been pressed. The \a event
+ This signal is emitted when a key has been pressed. The \a event
parameter provides information about the event.
+
+ The corresponding handler is \c onPressed.
*/
/*!
- \qmlsignal QtQuick::Keys::onReleased(KeyEvent event)
+ \qmlsignal QtQuick::Keys::released(KeyEvent event)
- This handler is called when a key has been released. The \a event
+ This signal is emitted when a key has been released. The \a event
parameter provides information about the event.
+
+ The corresponding handler is \c onReleased.
*/
/*!
- \qmlsignal QtQuick::Keys::onDigit0Pressed(KeyEvent event)
+ \qmlsignal QtQuick::Keys::digit0Pressed(KeyEvent event)
- This handler is called when the digit '0' has been pressed. The \a event
+ This signal is emitted when the digit '0' has been pressed. The \a event
parameter provides information about the event.
+
+ The corresponding handler is \c onDigit0Pressed.
*/
/*!
- \qmlsignal QtQuick::Keys::onDigit1Pressed(KeyEvent event)
+ \qmlsignal QtQuick::Keys::digit1Pressed(KeyEvent event)
- This handler is called when the digit '1' has been pressed. The \a event
+ This signal is emitted when the digit '1' has been pressed. The \a event
parameter provides information about the event.
+
+ The corresponding handler is \c onDigit1Pressed.
*/
/*!
- \qmlsignal QtQuick::Keys::onDigit2Pressed(KeyEvent event)
+ \qmlsignal QtQuick::Keys::digit2Pressed(KeyEvent event)
- This handler is called when the digit '2' has been pressed. The \a event
+ This signal is emitted when the digit '2' has been pressed. The \a event
parameter provides information about the event.
+
+ The corresponding handler is \c onDigit2Pressed.
*/
/*!
- \qmlsignal QtQuick::Keys::onDigit3Pressed(KeyEvent event)
+ \qmlsignal QtQuick::Keys::digit3Pressed(KeyEvent event)
- This handler is called when the digit '3' has been pressed. The \a event
+ This signal is emitted when the digit '3' has been pressed. The \a event
parameter provides information about the event.
+
+ The corresponding handler is \c onDigit3Pressed.
*/
/*!
- \qmlsignal QtQuick::Keys::onDigit4Pressed(KeyEvent event)
+ \qmlsignal QtQuick::Keys::digit4Pressed(KeyEvent event)
- This handler is called when the digit '4' has been pressed. The \a event
+ This signal is emitted when the digit '4' has been pressed. The \a event
parameter provides information about the event.
+
+ The corresponding handler is \c onDigit4Pressed.
*/
/*!
- \qmlsignal QtQuick::Keys::onDigit5Pressed(KeyEvent event)
+ \qmlsignal QtQuick::Keys::digit5Pressed(KeyEvent event)
- This handler is called when the digit '5' has been pressed. The \a event
+ This signal is emitted when the digit '5' has been pressed. The \a event
parameter provides information about the event.
+
+ The corresponding handler is \c onDigit5Pressed.
*/
/*!
- \qmlsignal QtQuick::Keys::onDigit6Pressed(KeyEvent event)
+ \qmlsignal QtQuick::Keys::digit6Pressed(KeyEvent event)
- This handler is called when the digit '6' has been pressed. The \a event
+ This signal is emitted when the digit '6' has been pressed. The \a event
parameter provides information about the event.
+
+ The corresponding handler is \c onDigit6Pressed.
*/
/*!
- \qmlsignal QtQuick::Keys::onDigit7Pressed(KeyEvent event)
+ \qmlsignal QtQuick::Keys::digit7Pressed(KeyEvent event)
- This handler is called when the digit '7' has been pressed. The \a event
+ This signal is emitted when the digit '7' has been pressed. The \a event
parameter provides information about the event.
+
+ The corresponding handler is \c onDigit7Pressed.
*/
/*!
- \qmlsignal QtQuick::Keys::onDigit8Pressed(KeyEvent event)
+ \qmlsignal QtQuick::Keys::digit8Pressed(KeyEvent event)
- This handler is called when the digit '8' has been pressed. The \a event
+ This signal is emitted when the digit '8' has been pressed. The \a event
parameter provides information about the event.
+
+ The corresponding handler is \c onDigit8Pressed.
*/
/*!
- \qmlsignal QtQuick::Keys::onDigit9Pressed(KeyEvent event)
+ \qmlsignal QtQuick::Keys::digit9Pressed(KeyEvent event)
- This handler is called when the digit '9' has been pressed. The \a event
+ This signal is emitted when the digit '9' has been pressed. The \a event
parameter provides information about the event.
+
+ The corresponding handler is \c onDigit9Pressed.
*/
/*!
- \qmlsignal QtQuick::Keys::onLeftPressed(KeyEvent event)
+ \qmlsignal QtQuick::Keys::leftPressed(KeyEvent event)
- This handler is called when the Left arrow has been pressed. The \a event
+ This signal is emitted when the Left arrow has been pressed. The \a event
parameter provides information about the event.
+
+ The corresponding handler is \c onLeftPressed.
*/
/*!
- \qmlsignal QtQuick::Keys::onRightPressed(KeyEvent event)
+ \qmlsignal QtQuick::Keys::rightPressed(KeyEvent event)
- This handler is called when the Right arrow has been pressed. The \a event
+ This signal is emitted when the Right arrow has been pressed. The \a event
parameter provides information about the event.
+
+ The corresponding handler is \c onRightPressed.
*/
/*!
- \qmlsignal QtQuick::Keys::onUpPressed(KeyEvent event)
+ \qmlsignal QtQuick::Keys::upPressed(KeyEvent event)
- This handler is called when the Up arrow has been pressed. The \a event
+ This signal is emitted when the Up arrow has been pressed. The \a event
parameter provides information about the event.
+
+ The corresponding handler is \c onUpPressed.
*/
/*!
- \qmlsignal QtQuick::Keys::onDownPressed(KeyEvent event)
+ \qmlsignal QtQuick::Keys::downPressed(KeyEvent event)
- This handler is called when the Down arrow has been pressed. The \a event
+ This signal is emitted when the Down arrow has been pressed. The \a event
parameter provides information about the event.
+
+ The corresponding handler is \c onDownPressed.
*/
/*!
- \qmlsignal QtQuick::Keys::onTabPressed(KeyEvent event)
+ \qmlsignal QtQuick::Keys::tabPressed(KeyEvent event)
- This handler is called when the Tab key has been pressed. The \a event
+ This signal is emitted when the Tab key has been pressed. The \a event
parameter provides information about the event.
+
+ The corresponding handler is \c onTabPressed.
*/
/*!
- \qmlsignal QtQuick::Keys::onBacktabPressed(KeyEvent event)
+ \qmlsignal QtQuick::Keys::backtabPressed(KeyEvent event)
- This handler is called when the Shift+Tab key combination (Backtab) has
+ This signal is emitted when the Shift+Tab key combination (Backtab) has
been pressed. The \a event parameter provides information about the event.
+
+ The corresponding handler is \c onBacktabPressed.
*/
/*!
- \qmlsignal QtQuick::Keys::onAsteriskPressed(KeyEvent event)
+ \qmlsignal QtQuick::Keys::asteriskPressed(KeyEvent event)
- This handler is called when the Asterisk '*' has been pressed. The \a event
+ This signal is emitted when the Asterisk '*' has been pressed. The \a event
parameter provides information about the event.
+
+ The corresponding handler is \c onAsteriskPressed.
*/
/*!
- \qmlsignal QtQuick::Keys::onEscapePressed(KeyEvent event)
+ \qmlsignal QtQuick::Keys::escapePressed(KeyEvent event)
- This handler is called when the Escape key has been pressed. The \a event
+ This signal is emitted when the Escape key has been pressed. The \a event
parameter provides information about the event.
+
+ The corresponding handler is \c onEscapePressed.
*/
/*!
- \qmlsignal QtQuick::Keys::onReturnPressed(KeyEvent event)
+ \qmlsignal QtQuick::Keys::returnPressed(KeyEvent event)
- This handler is called when the Return key has been pressed. The \a event
+ This signal is emitted when the Return key has been pressed. The \a event
parameter provides information about the event.
+
+ The corresponding handler is \c onReturnPressed.
*/
/*!
- \qmlsignal QtQuick::Keys::onEnterPressed(KeyEvent event)
+ \qmlsignal QtQuick::Keys::enterPressed(KeyEvent event)
- This handler is called when the Enter key has been pressed. The \a event
+ This signal is emitted when the Enter key has been pressed. The \a event
parameter provides information about the event.
+
+ The corresponding handler is \c onEnterPressed.
*/
/*!
- \qmlsignal QtQuick::Keys::onDeletePressed(KeyEvent event)
+ \qmlsignal QtQuick::Keys::deletePressed(KeyEvent event)
- This handler is called when the Delete key has been pressed. The \a event
+ This signal is emitted when the Delete key has been pressed. The \a event
parameter provides information about the event.
+
+ The corresponding handler is \c onDeletePressed.
*/
/*!
- \qmlsignal QtQuick::Keys::onSpacePressed(KeyEvent event)
+ \qmlsignal QtQuick::Keys::spacePressed(KeyEvent event)
- This handler is called when the Space key has been pressed. The \a event
+ This signal is emitted when the Space key has been pressed. The \a event
parameter provides information about the event.
+
+ The corresponding handler is \c onSpacePressed.
*/
/*!
- \qmlsignal QtQuick::Keys::onBackPressed(KeyEvent event)
+ \qmlsignal QtQuick::Keys::backPressed(KeyEvent event)
- This handler is called when the Back key has been pressed. The \a event
+ This signal is emitted when the Back key has been pressed. The \a event
parameter provides information about the event.
+
+ The corresponding handler is \c onBackPressed.
*/
/*!
- \qmlsignal QtQuick::Keys::onCancelPressed(KeyEvent event)
+ \qmlsignal QtQuick::Keys::cancelPressed(KeyEvent event)
- This handler is called when the Cancel key has been pressed. The \a event
+ This signal is emitted when the Cancel key has been pressed. The \a event
parameter provides information about the event.
+
+ The corresponding handler is \c onCancelPressed.
*/
/*!
- \qmlsignal QtQuick::Keys::onSelectPressed(KeyEvent event)
+ \qmlsignal QtQuick::Keys::selectPressed(KeyEvent event)
- This handler is called when the Select key has been pressed. The \a event
+ This signal is emitted when the Select key has been pressed. The \a event
parameter provides information about the event.
+
+ The corresponding handler is \c onSelectPressed.
*/
/*!
- \qmlsignal QtQuick::Keys::onYesPressed(KeyEvent event)
+ \qmlsignal QtQuick::Keys::yesPressed(KeyEvent event)
- This handler is called when the Yes key has been pressed. The \a event
+ This signal is emitted when the Yes key has been pressed. The \a event
parameter provides information about the event.
+
+ The corresponding handler is \c onYesPressed.
*/
/*!
- \qmlsignal QtQuick::Keys::onNoPressed(KeyEvent event)
+ \qmlsignal QtQuick::Keys::noPressed(KeyEvent event)
- This handler is called when the No key has been pressed. The \a event
+ This signal is emitted when the No key has been pressed. The \a event
parameter provides information about the event.
+
+ The corresponding handler is \c onNoPressed.
*/
/*!
- \qmlsignal QtQuick::Keys::onContext1Pressed(KeyEvent event)
+ \qmlsignal QtQuick::Keys::context1Pressed(KeyEvent event)
- This handler is called when the Context1 key has been pressed. The \a event
+ This signal is emitted when the Context1 key has been pressed. The \a event
parameter provides information about the event.
+
+ The corresponding handler is \c onContext1Pressed.
*/
/*!
- \qmlsignal QtQuick::Keys::onContext2Pressed(KeyEvent event)
+ \qmlsignal QtQuick::Keys::context2Pressed(KeyEvent event)
- This handler is called when the Context2 key has been pressed. The \a event
+ This signal is emitted when the Context2 key has been pressed. The \a event
parameter provides information about the event.
+
+ The corresponding handler is \c onContext2Pressed.
*/
/*!
- \qmlsignal QtQuick::Keys::onContext3Pressed(KeyEvent event)
+ \qmlsignal QtQuick::Keys::context3Pressed(KeyEvent event)
- This handler is called when the Context3 key has been pressed. The \a event
+ This signal is emitted when the Context3 key has been pressed. The \a event
parameter provides information about the event.
+
+ The corresponding handler is \c onContext3Pressed.
*/
/*!
- \qmlsignal QtQuick::Keys::onContext4Pressed(KeyEvent event)
+ \qmlsignal QtQuick::Keys::context4Pressed(KeyEvent event)
- This handler is called when the Context4 key has been pressed. The \a event
+ This signal is emitted when the Context4 key has been pressed. The \a event
parameter provides information about the event.
+
+ The corresponding handler is \c onContext4Pressed.
*/
/*!
- \qmlsignal QtQuick::Keys::onCallPressed(KeyEvent event)
+ \qmlsignal QtQuick::Keys::callPressed(KeyEvent event)
- This handler is called when the Call key has been pressed. The \a event
+ This signal is emitted when the Call key has been pressed. The \a event
parameter provides information about the event.
+
+ The corresponding handler is \c onCallPressed.
*/
/*!
- \qmlsignal QtQuick::Keys::onHangupPressed(KeyEvent event)
+ \qmlsignal QtQuick::Keys::hangupPressed(KeyEvent event)
- This handler is called when the Hangup key has been pressed. The \a event
+ This signal is emitted when the Hangup key has been pressed. The \a event
parameter provides information about the event.
+
+ The corresponding handler is \c onHangupPressed.
*/
/*!
- \qmlsignal QtQuick::Keys::onFlipPressed(KeyEvent event)
+ \qmlsignal QtQuick::Keys::flipPressed(KeyEvent event)
- This handler is called when the Flip key has been pressed. The \a event
+ This signal is emitted when the Flip key has been pressed. The \a event
parameter provides information about the event.
+
+ The corresponding handler is \c onFlipPressed.
*/
/*!
- \qmlsignal QtQuick::Keys::onMenuPressed(KeyEvent event)
+ \qmlsignal QtQuick::Keys::menuPressed(KeyEvent event)
- This handler is called when the Menu key has been pressed. The \a event
+ This signal is emitted when the Menu key has been pressed. The \a event
parameter provides information about the event.
+
+ The corresponding handler is \c onMenuPressed.
*/
/*!
- \qmlsignal QtQuick::Keys::onVolumeUpPressed(KeyEvent event)
+ \qmlsignal QtQuick::Keys::volumeUpPressed(KeyEvent event)
- This handler is called when the VolumeUp key has been pressed. The \a event
+ This signal is emitted when the VolumeUp key has been pressed. The \a event
parameter provides information about the event.
+
+ The corresponding handler is \c onVolumeUpPressed.
*/
/*!
- \qmlsignal QtQuick::Keys::onVolumeDownPressed(KeyEvent event)
+ \qmlsignal QtQuick::Keys::volumeDownPressed(KeyEvent event)
- This handler is called when the VolumeDown key has been pressed. The \a event
+ This signal is emitted when the VolumeDown key has been pressed. The \a event
parameter provides information about the event.
+
+ The corresponding handler is \c onVolumeDownPressed.
*/
QQuickKeysAttached::QQuickKeysAttached(QObject *parent)
@@ -1256,7 +1334,7 @@ void QQuickKeysAttached::keyPressed(QKeyEvent *event, bool post)
for (int ii = 0; ii < d->targets.count(); ++ii) {
QQuickItem *i = d->targets.at(ii);
if (i && i->isVisible()) {
- d->item->window()->sendEvent(i, event);
+ QCoreApplication::sendEvent(i, event);
if (event->isAccepted()) {
d->inPress = false;
return;
@@ -1298,7 +1376,7 @@ void QQuickKeysAttached::keyReleased(QKeyEvent *event, bool post)
for (int ii = 0; ii < d->targets.count(); ++ii) {
QQuickItem *i = d->targets.at(ii);
if (i && i->isVisible()) {
- d->item->window()->sendEvent(i, event);
+ QCoreApplication::sendEvent(i, event);
if (event->isAccepted()) {
d->inRelease = false;
return;
@@ -1604,8 +1682,8 @@ void QQuickItemPrivate::updateSubFocusItem(QQuickItem *scope, bool focus)
thumb is to only use classes with the "QSG" prefix inside the
QQuickItem::updatePaintNode() function.
- To read more about how the scene graph rendering works, see
- \l{Scene Graph and Rendering}
+ \note All classes with QSG prefix should be used solely on the scene graph's
+ rendering thread. See \l {Scene Graph and Rendering} for more information.
\section1 Custom QPainter Items
@@ -1667,12 +1745,12 @@ void QQuickItemPrivate::updateSubFocusItem(QQuickItem *scope, bool focus)
\section2 Key Handling
Key handling is available to all Item-based visual types via the \l Keys
- attached property. The \e Keys attached property provides basic handlers
- such as \l {Keys::}{onPressed} and \l {Keys}{::onReleased}, as well as
- handlers for specific keys, such as \l {Keys::}{onSpacePressed}. The
+ attached property. The \e Keys attached property provides basic signals
+ such as \l {Keys::}{pressed} and \l {Keys::}{released}, as well as
+ signals for specific keys, such as \l {Keys::}{spacePressed}. The
example below assigns \l {Keyboard Focus in Qt Quick}{keyboard focus} to
- the item and handles the left key via the general \e onPressed handler
- and the return key via the onReturnPressed handler:
+ the item and handles the left key via the general \c onPressed handler
+ and the return key via the \c onReturnPressed handler:
\qml
import QtQuick 2.0
@@ -2055,8 +2133,6 @@ bool QQuickItemPrivate::qt_tab_all_widgets()
*/
bool QQuickItemPrivate::canAcceptTabFocus(QQuickItem *item)
{
- bool result = true;
-
if (!item->window())
return false;
@@ -2064,14 +2140,13 @@ bool QQuickItemPrivate::canAcceptTabFocus(QQuickItem *item)
return true;
#ifndef QT_NO_ACCESSIBILITY
- result = false;
if (QObject *acc = qmlAttachedPropertiesObject<QQuickAccessibleAttached>(item, false)) {
int role = acc->property("role").toInt();
if (role == QAccessible::EditableText
|| role == QAccessible::Table
|| role == QAccessible::List
|| role == QAccessible::SpinBox) {
- result = true;
+ return true;
} else if (role == QAccessible::ComboBox) {
QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(item);
return iface->state().editable;
@@ -2079,7 +2154,11 @@ bool QQuickItemPrivate::canAcceptTabFocus(QQuickItem *item)
}
#endif
- return result;
+ QVariant readonly = item->property("readOnly");
+ if (readonly.isValid() && !readonly.toBool() && item->property("text").isValid())
+ return true;
+
+ return false;
}
/*!
@@ -3348,6 +3427,9 @@ void QQuickItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeo
in this function. Similarly for signals, these will be emitted on the render
thread and will thus often be delivered via queued connections.
+ \note All classes with QSG prefix should be used solely on the scene graph's
+ rendering thread. See \l {Scene Graph and Rendering} for more information.
+
\sa QSGMaterial, QSGSimpleMaterial, QSGGeometryNode, QSGGeometry,
QSGFlatColorMaterial, QSGTextureMaterial, QSGNode::markDirty()
*/
@@ -6319,10 +6401,12 @@ void QQuickItem::setFocus(bool focus, Qt::FocusReason reason)
while (scope && !scope->isFocusScope() && scope->parentItem())
scope = scope->parentItem();
if (d->window) {
- if (focus)
- QQuickWindowPrivate::get(d->window)->setFocusInScope(scope, this, reason);
- else
- QQuickWindowPrivate::get(d->window)->clearFocusInScope(scope, this, reason);
+ if (reason != Qt::PopupFocusReason) {
+ if (focus)
+ QQuickWindowPrivate::get(d->window)->setFocusInScope(scope, this, reason);
+ else
+ QQuickWindowPrivate::get(d->window)->clearFocusInScope(scope, this, reason);
+ }
} else {
// do the focus changes from setFocusInScope/clearFocusInScope that are
// unrelated to a window
diff --git a/src/quick/items/qquickitemsmodule.cpp b/src/quick/items/qquickitemsmodule.cpp
index dc8230f6be..1436ab332f 100644
--- a/src/quick/items/qquickitemsmodule.cpp
+++ b/src/quick/items/qquickitemsmodule.cpp
@@ -127,13 +127,6 @@ static QQmlPrivate::AutoParentResult qquickitem_autoParent(QObject *obj, QObject
return QQmlPrivate::IncompatibleParent;
}
-static bool compareQQuickAnchorLines(const void *p1, const void *p2)
-{
- const QQuickAnchorLine &l1 = *static_cast<const QQuickAnchorLine*>(p1);
- const QQuickAnchorLine &l2 = *static_cast<const QQuickAnchorLine*>(p2);
- return l1 == l2;
-}
-
static void qt_quickitems_defineModule(const char *uri, int major, int minor)
{
QQmlPrivate::RegisterAutoParent autoparent = { 0, &qquickitem_autoParent };
@@ -211,7 +204,6 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
qmlRegisterType<QQuickPen>();
qmlRegisterType<QQuickFlickableVisibleArea>();
qRegisterMetaType<QQuickAnchorLine>("QQuickAnchorLine");
- QQmlMetaType::setQQuickAnchorLineCompareFunction(compareQQuickAnchorLines);
qmlRegisterType<QQuickTextDocument>();
diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp
index e51a562490..b4f6c34c6a 100644
--- a/src/quick/items/qquickitemview.cpp
+++ b/src/quick/items/qquickitemview.cpp
@@ -364,6 +364,8 @@ void QQuickItemView::setDelegate(QQmlComponent *delegate)
if (!d->ownModel) {
d->model = new QQmlDelegateModel(qmlContext(this));
d->ownModel = true;
+ if (isComponentComplete())
+ static_cast<QQmlDelegateModel *>(d->model.data())->componentComplete();
}
if (QQmlDelegateModel *dataModel = qobject_cast<QQmlDelegateModel*>(d->model)) {
int oldCount = dataModel->count();
@@ -906,12 +908,12 @@ void QQuickItemViewPrivate::positionViewAtIndex(int index, int mode)
else
maxExtent = isContentFlowReversed() ? q->minXExtent()-size(): -q->maxXExtent();
if (!item) {
- int itemPos = positionAt(idx);
+ qreal itemPos = positionAt(idx);
changedVisibleIndex(idx);
// save the currently visible items in case any of them end up visible again
QList<FxViewItem *> oldVisible = visibleItems;
visibleItems.clear();
- setPosition(qMin(qreal(itemPos), maxExtent));
+ setPosition(qMin(itemPos, maxExtent));
// now release the reference to all the old visible items.
for (int i = 0; i < oldVisible.count(); ++i)
releaseItem(oldVisible.at(i));
@@ -2318,7 +2320,8 @@ void QQuickItemView::initItem(int, QObject *object)
{
QQuickItem* item = qmlobject_cast<QQuickItem*>(object);
if (item) {
- item->setZ(1);
+ if (qFuzzyIsNull(item->z()))
+ item->setZ(1);
item->setParentItem(contentItem());
QQuickItemPrivate::get(item)->setCulled(true);
}
@@ -2382,7 +2385,8 @@ QQuickItem *QQuickItemViewPrivate::createComponentItem(QQmlComponent *component,
item = new QQuickItem;
}
if (item) {
- item->setZ(zValue);
+ if (qFuzzyIsNull(item->z()))
+ item->setZ(zValue);
QQml_setParent_noEvent(item, q->contentItem());
item->setParentItem(q->contentItem());
}
diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp
index 3ac28f438b..8f9dbb567f 100644
--- a/src/quick/items/qquicklistview.cpp
+++ b/src/quick/items/qquicklistview.cpp
@@ -966,7 +966,8 @@ QQuickItem * QQuickListViewPrivate::getSectionItem(const QString &section)
if (!sectionItem) {
delete nobj;
} else {
- sectionItem->setZ(2);
+ if (qFuzzyIsNull(sectionItem->z()))
+ sectionItem->setZ(2);
QQml_setParent_noEvent(sectionItem, contentItem);
sectionItem->setParentItem(contentItem);
}
@@ -1836,19 +1837,23 @@ QQuickListView::~QQuickListView()
*/
/*!
- \qmlattachedsignal QtQuick::ListView::onAdd()
- This attached signal handler is called immediately after an item is added to the view.
+ \qmlattachedsignal QtQuick::ListView::add()
+ This attached signal is emitted immediately after an item is added to the view.
If an \l add transition is specified, it is applied immediately after
- this signal handler is called.
+ this signal is handled.
+
+ The corresponding handler is \c onAdd.
*/
/*!
- \qmlattachedsignal QtQuick::ListView::onRemove()
- This attached handler is called immediately before an item is removed from the view.
+ \qmlattachedsignal QtQuick::ListView::remove()
+ This attached signal is emitted immediately before an item is removed from the view.
If a \l remove transition has been specified, it is applied after
- this signal handler is called, providing that delayRemove is false.
+ this signal is handled, providing that \l delayRemove is false.
+
+ The corresponding handler is \c onRemove.
*/
/*!
@@ -1881,6 +1886,8 @@ QQuickListView::~QQuickListView()
It is recommended that the delegate's size be a whole number to avoid sub-pixel
alignment of items.
+ The default \l {QQuickItem::z}{stacking order} of delegate instances is \c 1.
+
\note Delegates are instantiated as needed and may be destroyed at any time.
They are parented to ListView's \l {Flickable::contentItem}{contentItem}, not to the view itself.
State should \e never be stored in a delegate.
@@ -1908,6 +1915,8 @@ QQuickListView::~QQuickListView()
The \c highlightItem is managed by the view unless
\l highlightFollowsCurrentItem is set to false.
+ The default \l {QQuickItem::z}{stacking order}
+ of the highlight item is \c 0.
\sa highlight, highlightFollowsCurrentItem
*/
@@ -1924,7 +1933,8 @@ QQuickListView::~QQuickListView()
An instance of the highlight component is created for each list.
The geometry of the resulting component instance is managed by the list
so as to stay with the current item, unless the highlightFollowsCurrentItem
- property is false.
+ property is false. The default \l {QQuickItem::z}{stacking order} of the
+ highlight item is \c 0.
\sa highlightItem, highlightFollowsCurrentItem,
{Qt Quick Examples - Views#Highlight demonstrates adding a custom highlight to a ListView.}{ListView highlight example}
@@ -2202,7 +2212,9 @@ void QQuickListView::setOrientation(QQuickListView::Orientation orientation)
A case insensitive comparison is used when determining section
boundaries.
- \c section.delegate holds the delegate component for each section.
+ \c section.delegate holds the delegate component for each section. The
+ default \l {QQuickItem::z}{stacking order} of section delegate instances
+ is \c 2.
\c section.labelPositioning determines whether the current and/or
next section labels stick to the start/end of the view, and whether
@@ -2388,7 +2400,8 @@ void QQuickListView::setSnapMode(SnapMode mode)
This property holds the component to use as the footer.
An instance of the footer component is created for each view. The
- footer is positioned at the end of the view, after any items.
+ footer is positioned at the end of the view, after any items. The
+ default \l {QQuickItem::z}{stacking order} of the footer is \c 1.
\sa header, footerItem
*/
@@ -2400,6 +2413,7 @@ void QQuickListView::setSnapMode(SnapMode mode)
An instance of the header component is created for each view. The
header is positioned at the beginning of the view, before any items.
+ The default \l {QQuickItem::z}{stacking order} of the header is \c 1.
\sa footer, headerItem
*/
@@ -2410,6 +2424,7 @@ void QQuickListView::setSnapMode(SnapMode mode)
An instance of the header component is created for each view. The
header is positioned at the beginning of the view, before any items.
+ The default \l {QQuickItem::z}{stacking order} of the header is \c 1.
\sa header, footerItem
*/
@@ -2419,7 +2434,8 @@ void QQuickListView::setSnapMode(SnapMode mode)
This holds the footer item created from the \l footer component.
An instance of the footer component is created for each view. The
- footer is positioned at the end of the view, after any items.
+ footer is positioned at the end of the view, after any items. The
+ default \l {QQuickItem::z}{stacking order} of the footer is \c 1.
\sa footer, headerItem
*/
@@ -2487,7 +2503,7 @@ void QQuickListView::setSnapMode(SnapMode mode)
populated, or when the view's \l model changes. (In those cases, the \l populate transition is
applied instead.) Additionally, this transition should \e not animate the height of the new item;
doing so will cause any items beneath the new item to be laid out at the wrong position. Instead,
- the height can be animated within \l onAdd in the delegate.
+ the height can be animated within the \l {add}{onAdd} handler in the delegate.
\sa addDisplaced, populate, ViewTransition
*/
@@ -2844,11 +2860,11 @@ void QQuickListView::geometryChanged(const QRectF &newGeometry, const QRectF &ol
Q_D(QQuickListView);
if (d->isRightToLeft()) {
// maintain position relative to the right edge
- int dx = newGeometry.width() - oldGeometry.width();
+ qreal dx = newGeometry.width() - oldGeometry.width();
setContentX(contentX() - dx);
} else if (d->isBottomToTop()) {
// maintain position relative to the bottom edge
- int dy = newGeometry.height() - oldGeometry.height();
+ qreal dy = newGeometry.height() - oldGeometry.height();
setContentY(contentY() - dy);
}
QQuickItemView::geometryChanged(newGeometry, oldGeometry);
@@ -2958,7 +2974,7 @@ bool QQuickListViewPrivate::applyInsertionChange(const QQmlChangeSet::Insert &ch
}
// index can be the next item past the end of the visible items list (i.e. appended)
- int pos = 0;
+ qreal pos = 0;
if (visibleItems.count()) {
pos = index < visibleItems.count() ? visibleItems.at(index)->position()
: visibleItems.last()->endPosition()+spacing;
@@ -2969,7 +2985,7 @@ bool QQuickListViewPrivate::applyInsertionChange(const QQmlChangeSet::Insert &ch
// Insert items before the visible item.
int insertionIdx = index;
int i = 0;
- int from = tempPos - displayMarginBeginning - buffer;
+ qreal from = tempPos - displayMarginBeginning - buffer;
for (i = count-1; i >= 0; --i) {
if (pos > from && insertionIdx < visibleIndex) {
@@ -3000,7 +3016,7 @@ bool QQuickListViewPrivate::applyInsertionChange(const QQmlChangeSet::Insert &ch
}
} else {
int i = 0;
- int to = buffer+displayMarginEnd+tempPos+size();
+ qreal to = buffer + displayMarginEnd + tempPos + size();
for (i = 0; i < count && pos <= to; ++i) {
FxViewItem *item = 0;
if (change.isMove() && (item = currentChanges.removedItems.take(change.moveKey(modelIndex + i))))
diff --git a/src/quick/items/qquickloader.cpp b/src/quick/items/qquickloader.cpp
index debe4b7497..f8a4f26ec3 100644
--- a/src/quick/items/qquickloader.cpp
+++ b/src/quick/items/qquickloader.cpp
@@ -449,8 +449,7 @@ void QQuickLoader::loadFromSource()
}
\endqml
- To unload the currently loaded object, set this property to an empty string
- or \c undefined.
+ To unload the currently loaded object, set this property to \c undefined.
Since \c {QtQuick 2.0}, Loader is able to load any type of object; it
is not restricted to Item types.
@@ -816,10 +815,12 @@ void QQuickLoader::componentComplete()
}
/*!
- \qmlsignal QtQuick::Loader::onLoaded()
+ \qmlsignal QtQuick::Loader::loaded()
- This handler is called when the \l status becomes \c Loader.Ready, or on successful
+ This signal is emitted when the \l status becomes \c Loader.Ready, or on successful
initial load.
+
+ The corresponding handler is \c onLoaded.
*/
diff --git a/src/quick/items/qquickmousearea.cpp b/src/quick/items/qquickmousearea.cpp
index 5aa72836b3..2d84660b6d 100644
--- a/src/quick/items/qquickmousearea.cpp
+++ b/src/quick/items/qquickmousearea.cpp
@@ -258,30 +258,32 @@ bool QQuickMouseAreaPrivate::propagateHelper(QQuickMouseEvent *ev, QQuickItem *i
*/
/*!
- \qmlsignal QtQuick::MouseArea::onEntered()
+ \qmlsignal QtQuick::MouseArea::entered()
- This handler is called when the mouse enters the mouse area.
+ This signal is emitted when the mouse enters the mouse area.
- By default the onEntered handler is only called while a button is
- pressed. Setting hoverEnabled to true enables handling of
- onEntered when no mouse button is pressed.
+ By default this signal is only emitted if a button is currently
+ pressed. Set \l hoverEnabled to true to emit this signal
+ even when no mouse button is pressed.
\sa hoverEnabled
+
+ The corresponding handler is \c onEntered.
*/
/*!
- \qmlsignal QtQuick::MouseArea::onExited()
+ \qmlsignal QtQuick::MouseArea::exited()
- This handler is called when the mouse exits the mouse area.
+ This signal is emitted when the mouse exits the mouse area.
- By default the onExited handler is only called while a button is
- pressed. Setting hoverEnabled to true enables handling of
- onExited when no mouse button is pressed.
+ By default this signal is only emitted if a button is currently
+ pressed. Set \l hoverEnabled to true to emit this signal
+ even when no mouse button is pressed.
The example below shows a fairly typical relationship between
two MouseAreas, with \c mouseArea2 on top of \c mouseArea1. Moving the
- mouse into \c mouseArea2 from \c mouseArea1 will cause \c onExited
- to be called for \c mouseArea1.
+ mouse into \c mouseArea2 from \c mouseArea1 will cause \c mouseArea1
+ to emit the \c exited signal.
\qml
Rectangle {
width: 400; height: 400
@@ -299,112 +301,134 @@ bool QQuickMouseAreaPrivate::propagateHelper(QQuickMouseEvent *ev, QQuickItem *i
}
\endqml
- If instead you give the two mouseAreas a parent-child relationship,
+ If instead you give the two MouseAreas a parent-child relationship,
moving the mouse into \c mouseArea2 from \c mouseArea1 will \b not
- cause \c onExited to be called for \c mouseArea1. Instead, they will
+ cause \c mouseArea1 to emit \c exited. Instead, they will
both be considered to be simultaneously hovered.
\sa hoverEnabled
+
+ The corresponding handler is \c onExited.
*/
/*!
- \qmlsignal QtQuick::MouseArea::onPositionChanged(MouseEvent mouse)
+ \qmlsignal QtQuick::MouseArea::positionChanged(MouseEvent mouse)
- This handler is called when the mouse position changes.
+ This signal is emitted when the mouse position changes.
The \l {MouseEvent}{mouse} parameter provides information about the mouse, including the x and y
position, and any buttons currently pressed.
- The \e accepted property of the MouseEvent parameter is ignored in this handler.
+ By default this signal is only emitted if a button is currently
+ pressed. Set \l hoverEnabled to true to emit this signal
+ even when no mouse button is pressed.
+
+ When handling this signal, changing the \l {MouseEvent::}{accepted} property of the \a mouse
+ parameter has no effect.
- By default the onPositionChanged handler is only called while a button is
- pressed. Setting hoverEnabled to true enables handling of
- onPositionChanged when no mouse button is pressed.
+ The corresponding handler is \c onPositionChanged.
*/
/*!
- \qmlsignal QtQuick::MouseArea::onClicked(MouseEvent mouse)
+ \qmlsignal QtQuick::MouseArea::clicked(MouseEvent mouse)
- This handler is called when there is a click. A click is defined as a press followed by a release,
+ This signal is emitted when there is a click. A click is defined as a press followed by a release,
both inside the MouseArea (pressing, moving outside the MouseArea, and then moving back inside and
releasing is also considered a click).
The \l {MouseEvent}{mouse} parameter provides information about the click, including the x and y
position of the release of the click, and whether the click was held.
- The \e accepted property of the MouseEvent parameter is ignored in this handler.
+ When handling this signal, changing the \l {MouseEvent::}{accepted} property of the \a mouse
+ parameter has no effect.
+
+ The corresponding handler is \c onClicked.
*/
/*!
- \qmlsignal QtQuick::MouseArea::onPressed(MouseEvent mouse)
+ \qmlsignal QtQuick::MouseArea::pressed(MouseEvent mouse)
- This handler is called when there is a press.
+ This signal is emitted when there is a press.
The \l {MouseEvent}{mouse} parameter provides information about the press, including the x and y
position and which button was pressed.
- The \e accepted property of the MouseEvent parameter determines whether this MouseArea
- will handle the press and all future mouse events until release. The default is to accept
- the event and not allow other MouseArea beneath this one to handle the event. If \e accepted
- is set to false, no further events will be sent to this MouseArea until the button is next
- pressed.
+ When handling this signal, use the \l {MouseEvent::}{accepted} property of the \a mouse
+ parameter to control whether this MouseArea handles the press and all future mouse events until
+ release. The default is to accept the event and not allow other MouseAreas beneath this one to
+ handle the event. If \e accepted is set to false, no further events will be sent to this MouseArea
+ until the button is next pressed.
+
+ The corresponding handler is \c onPressed.
*/
/*!
- \qmlsignal QtQuick::MouseArea::onReleased(MouseEvent mouse)
+ \qmlsignal QtQuick::MouseArea::released(MouseEvent mouse)
- This handler is called when there is a release.
+ This signal is emitted when there is a release.
The \l {MouseEvent}{mouse} parameter provides information about the click, including the x and y
position of the release of the click, and whether the click was held.
- The \e accepted property of the MouseEvent parameter is ignored in this handler.
+ When handling this signal, changing the \l {MouseEvent::}{accepted} property of the \a mouse
+ parameter has no effect.
- \sa onCanceled
+ The corresponding handler is \c onReleased.
+
+ \sa canceled
*/
/*!
- \qmlsignal QtQuick::MouseArea::onPressAndHold(MouseEvent mouse)
+ \qmlsignal QtQuick::MouseArea::pressAndHold(MouseEvent mouse)
- This handler is called when there is a long press (currently 800ms).
+ This signal is emitted when there is a long press (currently 800ms).
The \l {MouseEvent}{mouse} parameter provides information about the press, including the x and y
position of the press, and which button is pressed.
- The \e accepted property of the MouseEvent parameter is ignored in this handler.
+ When handling this signal, changing the \l {MouseEvent::}{accepted} property of the \a mouse
+ parameter has no effect.
+
+ The corresponding handler is \c onPressAndHold.
*/
/*!
- \qmlsignal QtQuick::MouseArea::onDoubleClicked(MouseEvent mouse)
+ \qmlsignal QtQuick::MouseArea::doubleClicked(MouseEvent mouse)
- This handler is called when there is a double-click (a press followed by a release followed by a press).
+ This signal is emitted when there is a double-click (a press followed by a release followed by a press).
The \l {MouseEvent}{mouse} parameter provides information about the click, including the x and y
position of the release of the click, and whether the click was held.
- If the \e accepted property of the \l {MouseEvent}{mouse} parameter is set to false
- in the handler, the onPressed/onReleased/onClicked handlers will be called for the second
- click; otherwise they are suppressed. The accepted property defaults to true.
+ When handling this signal, if the \l {MouseEvent::}{accepted} property of the \a mouse
+ parameter is set to false, the pressed/released/clicked signals will be emitted for the second
+ click; otherwise they are suppressed. The \c accepted property defaults to true.
+
+ The corresponding handler is \c onDoubleClicked.
*/
/*!
- \qmlsignal QtQuick::MouseArea::onCanceled()
+ \qmlsignal QtQuick::MouseArea::canceled()
- This handler is called when mouse events have been canceled, either because an event was not accepted, or
+ This signal is emitted when mouse events have been canceled, either because an event was not accepted, or
because another item stole the mouse event handling.
This signal is for advanced use: it is useful when there is more than one MouseArea
that is handling input, or when there is a MouseArea inside a \l Flickable. In the latter
- case, if you execute some logic on the pressed signal and then start dragging, the
+ case, if you execute some logic in the \c onPressed signal handler and then start dragging, the
\l Flickable will steal the mouse handling from the MouseArea. In these cases, to reset
the logic when the MouseArea has lost the mouse handling to the \l Flickable,
- \c onCanceled should be used in addition to onReleased.
+ \c canceled should be handled in addition to \l released.
+
+ The corresponding handler is \c onCanceled.
*/
/*!
- \qmlsignal QtQuick::MouseArea::onWheel(WheelEvent wheel)
+ \qmlsignal QtQuick::MouseArea::wheel(WheelEvent wheel)
- This handler is called in response to both mouse wheel and trackpad scroll gestures.
+ This signal is emitted in response to both mouse wheel and trackpad scroll gestures.
The \l {WheelEvent}{wheel} parameter provides information about the event, including the x and y
position, any buttons currently pressed, and information about the wheel movement, including
angleDelta and pixelDelta.
+
+ The corresponding handler is \c onWheel.
*/
QQuickMouseArea::QQuickMouseArea(QQuickItem *parent)
@@ -1217,7 +1241,7 @@ void QQuickMouseArea::setCursorShape(Qt::CursorShape shape)
\c drag.axis. For example, if \c anchors.left or \c anchors.right was set
for \c rect in the above example, it cannot be dragged along the X-axis.
This can be avoided by settng the anchor value to \c undefined in
- an \l onPressed handler.
+ an \l {pressed}{onPressed} handler.
If \c drag.filterChildren is set to true, a drag can override descendant MouseAreas. This
enables a parent MouseArea to handle drags, for example, while descendants handle clicks:
diff --git a/src/quick/items/qquickmultipointtoucharea.cpp b/src/quick/items/qquickmultipointtoucharea.cpp
index 6a5ba931c7..c20559454e 100644
--- a/src/quick/items/qquickmultipointtoucharea.cpp
+++ b/src/quick/items/qquickmultipointtoucharea.cpp
@@ -259,60 +259,72 @@ void QQuickTouchPoint::setSceneY(qreal sceneY)
*/
/*!
- \qmlsignal QtQuick::MultiPointTouchArea::onPressed(list<TouchPoint> touchPoints)
+ \qmlsignal QtQuick::MultiPointTouchArea::pressed(list<TouchPoint> touchPoints)
- This handler is called when new touch points are added. \a touchPoints is a list of these new points.
+ This signal is emitted when new touch points are added. \a touchPoints is a list of these new points.
- If minimumTouchPoints is set to a value greater than one, this handler will not be called until the minimum number
- of required touch points has been reached. At that point, onPressed will be called with all the current touch points.
+ If minimumTouchPoints is set to a value greater than one, this signal will not be emitted until the minimum number
+ of required touch points has been reached.
+
+ The corresponding handler is \c onPressed.
*/
/*!
- \qmlsignal QtQuick::MultiPointTouchArea::onUpdated(list<TouchPoint> touchPoints)
+ \qmlsignal QtQuick::MultiPointTouchArea::updated(list<TouchPoint> touchPoints)
+
+ This signal is emitted when existing touch points are updated. \a touchPoints is a list of these updated points.
- This handler is called when existing touch points are updated. \a touchPoints is a list of these updated points.
+ The corresponding handler is \c onUpdated.
*/
/*!
- \qmlsignal QtQuick::MultiPointTouchArea::onReleased(list<TouchPoint> touchPoints)
+ \qmlsignal QtQuick::MultiPointTouchArea::released(list<TouchPoint> touchPoints)
+
+ This signal is emitted when existing touch points are removed. \a touchPoints is a list of these removed points.
- This handler is called when existing touch points are removed. \a touchPoints is a list of these removed points.
+ The corresponding handler is \c onReleased.
*/
/*!
- \qmlsignal QtQuick::MultiPointTouchArea::onCanceled(list<TouchPoint> touchPoints)
+ \qmlsignal QtQuick::MultiPointTouchArea::canceled(list<TouchPoint> touchPoints)
- This handler is called when new touch events have been canceled because another item stole the touch event handling.
+ This signal is emitted when new touch events have been canceled because another item stole the touch event handling.
This signal is for advanced use: it is useful when there is more than one MultiPointTouchArea
that is handling input, or when there is a MultiPointTouchArea inside a \l Flickable. In the latter
- case, if you execute some logic on the onPressed signal and then start dragging, the
+ case, if you execute some logic in the \c onPressed signal handler and then start dragging, the
\l Flickable may steal the touch handling from the MultiPointTouchArea. In these cases, to reset
the logic when the MultiPointTouchArea has lost the touch handling to the \l Flickable,
- \c onCanceled should be used in addition to onReleased.
+ \c canceled should be handled in addition to \l released.
\a touchPoints is the list of canceled points.
+
+ The corresponding handler is \c onCanceled.
*/
/*!
- \qmlsignal QtQuick::MultiPointTouchArea::onGestureStarted(GestureEvent gesture)
+ \qmlsignal QtQuick::MultiPointTouchArea::gestureStarted(GestureEvent gesture)
- This handler is called when the global drag threshold has been reached.
+ This signal is emitted when the global drag threshold has been reached.
- This function is typically used when a MultiPointTouchAreas has been nested in a Flickable or another MultiPointTouchArea.
- When the threshold has been reached, and the handler called, you can determine whether or not the touch
+ This signal is typically used when a MultiPointTouchArea has been nested in a Flickable or another MultiPointTouchArea.
+ When the threshold has been reached and the signal is handled, you can determine whether or not the touch
area should grab the current touch points. By default they will not be grabbed; to grab them call \c gesture.grab(). If the
gesture is not grabbed, the nesting Flickable, for example, would also have an opportunity to grab.
The gesture object also includes information on the current set of \c touchPoints and the \c dragThreshold.
+
+ The corresponding handler is \c onGestureStarted.
*/
/*!
- \qmlsignal QtQuick::MultiPointTouchArea::onTouchUpdated(list<TouchPoint> touchPoints)
+ \qmlsignal QtQuick::MultiPointTouchArea::touchUpdated(list<TouchPoint> touchPoints)
- This handler is called when the touch points handled by the MultiPointTouchArea change. This includes adding new touch points,
+ This signal is emitted when the touch points handled by the MultiPointTouchArea change. This includes adding new touch points,
removing or canceling previous touch points, as well as updating current touch point data. \a touchPoints is the list of all current touch
points.
+
+ The corresponding handler is \c onTouchUpdated.
*/
/*!
diff --git a/src/quick/items/qquickpathview.cpp b/src/quick/items/qquickpathview.cpp
index 0080f54d20..45cd8e184c 100644
--- a/src/quick/items/qquickpathview.cpp
+++ b/src/quick/items/qquickpathview.cpp
@@ -1147,50 +1147,62 @@ bool QQuickPathView::isDragging() const
}
/*!
- \qmlsignal QtQuick::PathView::onMovementStarted()
+ \qmlsignal QtQuick::PathView::movementStarted()
- This handler is called when the view begins moving due to user
+ This signal is emitted when the view begins moving due to user
interaction.
+
+ The corresponding handler is \c onMovementStarted.
*/
/*!
- \qmlsignal QtQuick::PathView::onMovementEnded()
+ \qmlsignal QtQuick::PathView::movementEnded()
- This handler is called when the view stops moving due to user
- interaction. If a flick was generated, this handler will
- be triggered once the flick stops. If a flick was not
- generated, the handler will be triggered when the
+ This signal is emitted when the view stops moving due to user
+ interaction. If a flick was generated, this signal will
+ be emitted once the flick stops. If a flick was not
+ generated, this signal will be emitted when the
user stops dragging - i.e. a mouse or touch release.
+
+ The corresponding handler is \c onMovementEnded.
*/
/*!
- \qmlsignal QtQuick::PathView::onFlickStarted()
+ \qmlsignal QtQuick::PathView::flickStarted()
- This handler is called when the view is flicked. A flick
+ This signal is emitted when the view is flicked. A flick
starts from the point that the mouse or touch is released,
while still in motion.
+
+ The corresponding handler is \c onFlickStarted.
*/
/*!
- \qmlsignal QtQuick::PathView::onFlickEnded()
+ \qmlsignal QtQuick::PathView::flickEnded()
- This handler is called when the view stops moving due to a flick.
+ This signal is emitted when the view stops moving due to a flick.
+
+ The corresponding handler is \c onFlickEnded.
*/
/*!
- \qmlsignal QtQuick::PathView::onDragStarted()
+ \qmlsignal QtQuick::PathView::dragStarted()
- This handler is called when the view starts to be dragged due to user
+ This signal is emitted when the view starts to be dragged due to user
interaction.
+
+ The corresponding handler is \c onDragStarted.
*/
/*!
- \qmlsignal QtQuick::PathView::onDragEnded()
+ \qmlsignal QtQuick::PathView::dragEnded()
- This handler is called when the user stops dragging the view.
+ This signal is emitted when the user stops dragging the view.
If the velocity of the drag is suffient at the time the
touch/mouse button is released then a flick will start.
+
+ The corresponding handler is \c onDragEnded.
*/
/*!
@@ -1230,6 +1242,8 @@ void QQuickPathView::setDelegate(QQmlComponent *delegate)
if (!d->ownModel) {
d->model = new QQmlDelegateModel(qmlContext(this));
d->ownModel = true;
+ if (isComponentComplete())
+ static_cast<QQmlDelegateModel *>(d->model.data())->componentComplete();
}
if (QQmlDelegateModel *dataModel = qobject_cast<QQmlDelegateModel*>(d->model)) {
int oldCount = dataModel->count();
diff --git a/src/quick/items/qquickpincharea.cpp b/src/quick/items/qquickpincharea.cpp
index c2ca66f840..234f78c380 100644
--- a/src/quick/items/qquickpincharea.cpp
+++ b/src/quick/items/qquickpincharea.cpp
@@ -100,7 +100,7 @@ QT_BEGIN_NAMESPACE
\li \c previousScale is the scale factor of the previous event.
\endlist
- When a pinch gesture is started, the scale is 1.0.
+ When a pinch gesture is started, the scale is \c 1.0.
*/
/*!
@@ -116,7 +116,7 @@ QT_BEGIN_NAMESPACE
\li \c rotation is the total rotation since the pinch gesture started.
\endlist
- When a pinch gesture is started, the rotation is 0.0.
+ When a pinch gesture is started, the rotation is \c 0.0.
*/
/*!
@@ -190,33 +190,50 @@ QQuickPinchAreaPrivate::~QQuickPinchAreaPrivate()
*/
/*!
- \qmlsignal QtQuick::PinchArea::onPinchStarted()
+ \qmlsignal QtQuick::PinchArea::pinchStarted()
- This handler is called when the pinch area detects that a pinch gesture has started.
+ This signal is emitted when the pinch area detects that a pinch gesture has
+ started: two touch points (fingers) have been detected, and they have moved
+ beyond the \l {QStyleHints}{startDragDistance} threshold for the gesture to begin.
- The \l {PinchEvent}{pinch} parameter provides information about the pinch gesture,
- including the scale, center and angle of the pinch.
+ The \l {PinchEvent}{pinch} parameter (not the same as the \l {PinchArea}{pinch}
+ property) provides information about the pinch gesture, including the scale,
+ center and angle of the pinch. At the time of the \c pinchStarted signal,
+ these values are reset to the default values, regardless of the results
+ from previous gestures: pinch.scale will be \c 1.0 and pinch.rotation will be \c 0.0.
+ As the gesture progresses, \l pinchUpdated will report the deviation from those
+ defaults.
To ignore this gesture set the \c pinch.accepted property to false. The gesture
will be canceled and no further events will be sent.
+
+ The corresponding handler is \c onPinchStarted.
*/
/*!
- \qmlsignal QtQuick::PinchArea::onPinchUpdated()
+ \qmlsignal QtQuick::PinchArea::pinchUpdated()
+
+ This signal is emitted when the pinch area detects that a pinch gesture has changed.
- This handler is called when the pinch area detects that a pinch gesture has changed.
+ The \l {PinchEvent}{pinch} parameter provides information about the pinch
+ gesture, including the scale, center and angle of the pinch. These values
+ reflect changes only since the beginning of the current gesture, and
+ therefore are not limited by the minimum and maximum limits in the
+ \l {PinchArea}{pinch} property.
- The \l {PinchEvent}{pinch} parameter provides information about the pinch gesture,
- including the scale, center and angle of the pinch.
+ The corresponding handler is \c onPinchUpdated.
*/
/*!
- \qmlsignal QtQuick::PinchArea::onPinchFinished()
+ \qmlsignal QtQuick::PinchArea::pinchFinished()
- This handler is called when the pinch area detects that a pinch gesture has finished.
+ This signal is emitted when the pinch area detects that a pinch gesture has finished.
- The \l {PinchEvent}{pinch} parameter provides information about the pinch gesture,
- including the scale, center and angle of the pinch.
+ The \l {PinchEvent}{pinch} parameter (not the same as the \l {PinchArea}{pinch}
+ property) provides information about the pinch gesture, including the
+ scale, center and angle of the pinch.
+
+ The corresponding handler is \c onPinchFinished.
*/
@@ -239,8 +256,8 @@ QQuickPinchAreaPrivate::~QQuickPinchAreaPrivate()
\list
\li \c pinch.target specifies the id of the item to drag.
\li \c pinch.active specifies if the target item is currently being dragged.
- \li \c pinch.minimumScale and \c pinch.maximumScale limit the range of the Item::scale property.
- \li \c pinch.minimumRotation and \c pinch.maximumRotation limit the range of the Item::rotation property.
+ \li \c pinch.minimumScale and \c pinch.maximumScale limit the range of the Item.scale property, but not the \c PinchEvent \l {PinchEvent}{scale} property.
+ \li \c pinch.minimumRotation and \c pinch.maximumRotation limit the range of the Item.rotation property, but not the \c PinchEvent \l {PinchEvent}{rotation} property.
\li \c pinch.dragAxis specifies whether dragging in not allowed (\c Pinch.NoDrag), can be done horizontally (\c Pinch.XAxis), vertically (\c Pinch.YAxis), or both (\c Pinch.XAndYAxis)
\li \c pinch.minimum and \c pinch.maximum limit how far the target can be dragged along the corresponding axes.
\endlist
@@ -360,6 +377,39 @@ void QQuickPinchArea::updatePinch()
Q_D(QQuickPinchArea);
QQuickWindow *win = window();
+
+ if (d->touchPoints.count() < 2) {
+ setKeepMouseGrab(false);
+ QQuickWindow *c = window();
+ if (c && c->mouseGrabberItem() == this)
+ ungrabMouse();
+ }
+
+ if (d->touchPoints.count() == 0) {
+ if (d->inPinch) {
+ d->inPinch = false;
+ QPointF pinchCenter = mapFromScene(d->sceneLastCenter);
+ QQuickPinchEvent pe(pinchCenter, d->pinchLastScale, d->pinchLastAngle, d->pinchRotation);
+ pe.setStartCenter(d->pinchStartCenter);
+ pe.setPreviousCenter(pinchCenter);
+ pe.setPreviousAngle(d->pinchLastAngle);
+ pe.setPreviousScale(d->pinchLastScale);
+ pe.setStartPoint1(mapFromScene(d->sceneStartPoint1));
+ pe.setStartPoint2(mapFromScene(d->sceneStartPoint2));
+ pe.setPoint1(mapFromScene(d->lastPoint1));
+ pe.setPoint2(mapFromScene(d->lastPoint2));
+ emit pinchFinished(&pe);
+ d->pinchStartDist = 0;
+ d->pinchActivated = false;
+ if (d->pinch && d->pinch->target())
+ d->pinch->setActive(false);
+ }
+ d->initPinch = false;
+ d->pinchRejected = false;
+ d->stealMouse = false;
+ return;
+ }
+
QTouchEvent::TouchPoint touchPoint1 = d->touchPoints.at(0);
QTouchEvent::TouchPoint touchPoint2 = d->touchPoints.at(d->touchPoints. count() >= 2 ? 1 : 0);
@@ -404,48 +454,57 @@ void QQuickPinchArea::updatePinch()
if (angle > 180)
angle -= 360;
if (!d->inPinch || d->initPinch) {
- if (d->touchPoints.count() >= 2
- && (qAbs(p1.x()-d->sceneStartPoint1.x()) >= dragThreshold
- || qAbs(p1.y()-d->sceneStartPoint1.y()) >= dragThreshold
- || qAbs(p2.x()-d->sceneStartPoint2.x()) >= dragThreshold
- || qAbs(p2.y()-d->sceneStartPoint2.y()) >= dragThreshold)) {
- d->initPinch = false;
+ if (d->touchPoints.count() >= 2) {
+ if (d->initPinch) {
+ if (!d->inPinch)
+ d->pinchStartDist = dist;
+ d->initPinch = false;
+ }
d->sceneStartCenter = sceneCenter;
d->sceneLastCenter = sceneCenter;
d->pinchStartCenter = mapFromScene(sceneCenter);
- d->pinchStartDist = dist;
d->pinchStartAngle = angle;
d->pinchLastScale = 1.0;
d->pinchLastAngle = angle;
d->pinchRotation = 0.0;
d->lastPoint1 = p1;
d->lastPoint2 = p2;
- QQuickPinchEvent pe(d->pinchStartCenter, 1.0, angle, 0.0);
- pe.setStartCenter(d->pinchStartCenter);
- pe.setPreviousCenter(d->pinchStartCenter);
- pe.setPreviousAngle(d->pinchLastAngle);
- pe.setPreviousScale(d->pinchLastScale);
- pe.setStartPoint1(mapFromScene(d->sceneStartPoint1));
- pe.setStartPoint2(mapFromScene(d->sceneStartPoint2));
- pe.setPoint1(mapFromScene(d->lastPoint1));
- pe.setPoint2(mapFromScene(d->lastPoint2));
- pe.setPointCount(d->touchPoints.count());
- emit pinchStarted(&pe);
- if (pe.accepted()) {
- if (win && win->mouseGrabberItem() != this)
- grabMouse();
- setKeepMouseGrab(true);
- grabTouchPoints(QVector<int>() << touchPoint1.id() << touchPoint2.id());
- d->inPinch = true;
- d->stealMouse = true;
- if (d->pinch && d->pinch->target()) {
- d->pinchStartPos = pinch()->target()->position();
- d->pinchStartScale = d->pinch->target()->scale();
- d->pinchStartRotation = d->pinch->target()->rotation();
- d->pinch->setActive(true);
+ if (qAbs(dist - d->pinchStartDist) >= dragThreshold ||
+ (pinch()->axis() != QQuickPinch::NoDrag &&
+ (qAbs(p1.x()-d->sceneStartPoint1.x()) >= dragThreshold
+ || qAbs(p1.y()-d->sceneStartPoint1.y()) >= dragThreshold
+ || qAbs(p2.x()-d->sceneStartPoint2.x()) >= dragThreshold
+ || qAbs(p2.y()-d->sceneStartPoint2.y()) >= dragThreshold))) {
+ QQuickPinchEvent pe(d->pinchStartCenter, 1.0, angle, 0.0);
+ d->pinchStartDist = dist;
+ pe.setStartCenter(d->pinchStartCenter);
+ pe.setPreviousCenter(d->pinchStartCenter);
+ pe.setPreviousAngle(d->pinchLastAngle);
+ pe.setPreviousScale(d->pinchLastScale);
+ pe.setStartPoint1(mapFromScene(d->sceneStartPoint1));
+ pe.setStartPoint2(mapFromScene(d->sceneStartPoint2));
+ pe.setPoint1(mapFromScene(d->lastPoint1));
+ pe.setPoint2(mapFromScene(d->lastPoint2));
+ pe.setPointCount(d->touchPoints.count());
+ emit pinchStarted(&pe);
+ if (pe.accepted()) {
+ d->inPinch = true;
+ d->stealMouse = true;
+ if (win && win->mouseGrabberItem() != this)
+ grabMouse();
+ setKeepMouseGrab(true);
+ grabTouchPoints(QVector<int>() << touchPoint1.id() << touchPoint2.id());
+ d->inPinch = true;
+ d->stealMouse = true;
+ if (d->pinch && d->pinch->target()) {
+ d->pinchStartPos = pinch()->target()->position();
+ d->pinchStartScale = d->pinch->target()->scale();
+ d->pinchStartRotation = d->pinch->target()->rotation();
+ d->pinch->setActive(true);
+ }
+ } else {
+ d->pinchRejected = true;
}
- } else {
- d->pinchRejected = true;
}
}
} else if (d->pinchStartDist > 0) {
diff --git a/src/quick/items/qquickrendercontrol.cpp b/src/quick/items/qquickrendercontrol.cpp
index 4a199d9352..55736c33c3 100644
--- a/src/quick/items/qquickrendercontrol.cpp
+++ b/src/quick/items/qquickrendercontrol.cpp
@@ -220,7 +220,7 @@ QImage QQuickRenderControl::grab()
return QImage();
render();
- QImage grabContent = qt_gl_read_framebuffer(d->window->size(), false, false);
+ QImage grabContent = qt_gl_read_framebuffer(d->window->size() * d->window->devicePixelRatio(), false, false);
return grabContent;
}
@@ -248,4 +248,34 @@ QQuickWindow *QQuickRenderControl::window() const
return d->window;
}
+/*!
+ \fn QWindow *QQuickRenderControl::renderWindow(QPoint *offset)
+
+ Reimplemented in subclasses to return the real window this render control
+ is rendering into.
+
+ If \a offset in non-null, it is set to the offset of the control
+ inside the window.
+*/
+
+/*!
+ Returns the real window that \a win is being rendered to, if any.
+
+ If \a offset in non-null, it is set to the offset of the rendering
+ inside its window.
+
+ */
+
+QWindow *QQuickRenderControl::renderWindowFor(QQuickWindow *win, QPoint *offset)
+{
+ if (!win)
+ return 0;
+ QQuickRenderControl *rc = QQuickWindowPrivate::get(win)->renderControl;
+ if (rc)
+ return rc->renderWindow(offset);
+ return 0;
+}
+
+
+
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickrendercontrol_p.h b/src/quick/items/qquickrendercontrol_p.h
index 98dc946303..e7b7759afa 100644
--- a/src/quick/items/qquickrendercontrol_p.h
+++ b/src/quick/items/qquickrendercontrol_p.h
@@ -63,6 +63,8 @@ public:
~QQuickRenderControl();
QQuickWindow *window() const;
+ virtual QWindow *renderWindow(QPoint *offset) { Q_UNUSED(offset); return 0; }
+ static QWindow *renderWindowFor(QQuickWindow *win, QPoint *offset = 0);
void windowDestroyed();
diff --git a/src/quick/items/qquickrepeater.cpp b/src/quick/items/qquickrepeater.cpp
index 072bfab73c..e226d7ba49 100644
--- a/src/quick/items/qquickrepeater.cpp
+++ b/src/quick/items/qquickrepeater.cpp
@@ -131,22 +131,26 @@ QQuickRepeaterPrivate::~QQuickRepeaterPrivate()
*/
/*!
- \qmlsignal QtQuick::Repeater::onItemAdded(int index, Item item)
+ \qmlsignal QtQuick::Repeater::itemAdded(int index, Item item)
- This handler is called when an item is added to the repeater. The \a index
+ This signal is emitted when an item is added to the repeater. The \a index
parameter holds the index at which the item has been inserted within the
repeater, and the \a item parameter holds the \l Item that has been added.
+
+ The corresponding handler is \c onItemAdded.
*/
/*!
- \qmlsignal QtQuick::Repeater::onItemRemoved(int index, Item item)
+ \qmlsignal QtQuick::Repeater::itemRemoved(int index, Item item)
- This handler is called when an item is removed from the repeater. The \a index
+ This signal is emitted when an item is removed from the repeater. The \a index
parameter holds the index at which the item was removed from the repeater,
and the \a item parameter holds the \l Item that was removed.
Do not keep a reference to \a item if it was created by this repeater, as
- in these cases it will be deleted shortly after the handler is called.
+ in these cases it will be deleted shortly after the signal is handled.
+
+ The corresponding handler is \c onItemRemoved.
*/
QQuickRepeater::QQuickRepeater(QQuickItem *parent)
: QQuickItem(*(new QQuickRepeaterPrivate), parent)
diff --git a/src/quick/items/qquickscreen.cpp b/src/quick/items/qquickscreen.cpp
index 54c7527eec..82f4f0af3e 100644
--- a/src/quick/items/qquickscreen.cpp
+++ b/src/quick/items/qquickscreen.cpp
@@ -108,9 +108,9 @@ QT_BEGIN_NAMESPACE
such as task bars and system menus. If you want to position a Window at
the right of the desktop, you can bind to it like this:
- \qml
+ \code
x: Screen.desktopAvailableWidth - width
- \endqml
+ \endcode
*/
/*!
\qmlattachedproperty int Screen::desktopAvailableHeight
@@ -122,9 +122,9 @@ QT_BEGIN_NAMESPACE
such as task bars and system menus. If you want to position a Window at
the bottom of the desktop, you can bind to it like this:
- \qml
+ \code
y: Screen.desktopAvailableHeight - height
- \endqml
+ \endcode
*/
/*!
\qmlattachedproperty real Screen::logicalPixelDensity
diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp
index 287173957f..312cd483e2 100644
--- a/src/quick/items/qquicktext.cpp
+++ b/src/quick/items/qquicktext.cpp
@@ -1250,9 +1250,9 @@ QQuickText::~QQuickText()
*/
/*!
- \qmlsignal QtQuick::Text::onLineLaidOut(object line)
+ \qmlsignal QtQuick::Text::lineLaidOut(object line)
- This handler is called for each line of text that is laid out during the layout
+ This signal is emitted for each line of text that is laid out during the layout
process. The specified \a line object provides more details about the line that
is currently being laid out.
@@ -1277,12 +1277,14 @@ QQuickText::~QQuickText()
}
}
\endcode
+
+ The corresponding handler is \c onLineLaidOut.
*/
/*!
- \qmlsignal QtQuick::Text::onLinkActivated(string link)
+ \qmlsignal QtQuick::Text::linkActivated(string link)
- This handler is called when the user clicks on a link embedded in the text.
+ This signal is emitted when the user clicks on a link embedded in the text.
The link must be in rich text or HTML format and the
\a link string provides access to the particular link.
@@ -1293,6 +1295,8 @@ QQuickText::~QQuickText()
Clicking on the highlighted link will output
\tt{http://qt-project.org link activated} to the console.
+
+ The corresponding handler is \c onLinkActivated.
*/
/*!
@@ -2566,13 +2570,15 @@ bool QQuickTextPrivate::isLinkHoveredConnected()
}
/*!
- \qmlsignal QtQuick::Text::onLinkHovered(string link)
+ \qmlsignal QtQuick::Text::linkHovered(string link)
\since 5.2
- This handler is called when the user hovers a link embedded in the
+ This signal is emitted when the user hovers a link embedded in the
text. The link must be in rich text or HTML format and the \a link
string provides access to the particular link.
+ The corresponding handler is \c onLinkHovered.
+
\sa hoveredLink, linkAt()
*/
@@ -2584,7 +2590,7 @@ bool QQuickTextPrivate::isLinkHoveredConnected()
embedded in the text. The link must be in rich text or HTML format
and the \a hoveredLink string provides access to the particular link.
- \sa onLinkHovered, linkAt()
+ \sa linkHovered, linkAt()
*/
QString QQuickText::hoveredLink() const
diff --git a/src/quick/items/qquicktextcontrol.cpp b/src/quick/items/qquicktextcontrol.cpp
index 0a9677bd4e..53d736fb36 100644
--- a/src/quick/items/qquicktextcontrol.cpp
+++ b/src/quick/items/qquicktextcontrol.cpp
@@ -1365,6 +1365,11 @@ void QQuickTextControlPrivate::inputMethodEvent(QInputMethodEvent *e)
QVariant QQuickTextControl::inputMethodQuery(Qt::InputMethodQuery property) const
{
+ return inputMethodQuery(property, QVariant());
+}
+
+QVariant QQuickTextControl::inputMethodQuery(Qt::InputMethodQuery property, QVariant argument) const
+{
Q_D(const QQuickTextControl);
QTextBlock block = d->cursor.block();
switch (property) {
@@ -1382,6 +1387,47 @@ QVariant QQuickTextControl::inputMethodQuery(Qt::InputMethodQuery property) cons
return QVariant(); // No limit.
case Qt::ImAnchorPosition:
return QVariant(d->cursor.anchor() - block.position());
+ case Qt::ImAbsolutePosition:
+ return QVariant(d->cursor.anchor());
+ case Qt::ImTextAfterCursor:
+ {
+ int maxLength = argument.isValid() ? argument.toInt() : 1024;
+ QTextCursor tmpCursor = d->cursor;
+ int localPos = d->cursor.position() - block.position();
+ QString result = block.text().mid(localPos);
+ while (result.length() < maxLength) {
+ int currentBlock = tmpCursor.blockNumber();
+ tmpCursor.movePosition(QTextCursor::NextBlock);
+ if (tmpCursor.blockNumber() == currentBlock)
+ break;
+ result += QLatin1Char('\n') + tmpCursor.block().text();
+ }
+ return QVariant(result);
+ }
+ case Qt::ImTextBeforeCursor:
+ {
+ int maxLength = argument.isValid() ? argument.toInt() : 1024;
+ QTextCursor tmpCursor = d->cursor;
+ int localPos = d->cursor.position() - block.position();
+ int numBlocks = 0;
+ int resultLen = localPos;
+ while (resultLen < maxLength) {
+ int currentBlock = tmpCursor.blockNumber();
+ tmpCursor.movePosition(QTextCursor::PreviousBlock);
+ if (tmpCursor.blockNumber() == currentBlock)
+ break;
+ numBlocks++;
+ resultLen += tmpCursor.block().length();
+ }
+ QString result;
+ while (numBlocks) {
+ result += tmpCursor.block().text() + QLatin1Char('\n');
+ tmpCursor.movePosition(QTextCursor::NextBlock);
+ --numBlocks;
+ }
+ result += block.text().mid(0,localPos);
+ return QVariant(result);
+ }
default:
return QVariant();
}
diff --git a/src/quick/items/qquicktextcontrol_p.h b/src/quick/items/qquicktextcontrol_p.h
index bc5371b0c3..39221ced11 100644
--- a/src/quick/items/qquicktextcontrol_p.h
+++ b/src/quick/items/qquicktextcontrol_p.h
@@ -160,6 +160,7 @@ public:
#ifndef QT_NO_IM
virtual QVariant inputMethodQuery(Qt::InputMethodQuery property) const;
+ Q_INVOKABLE QVariant inputMethodQuery(Qt::InputMethodQuery query, QVariant argument) const;
#endif
virtual QMimeData *createMimeDataFromSelection() const;
diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp
index 6fc1a3f4a5..3c4d0d4b42 100644
--- a/src/quick/items/qquicktextedit.cpp
+++ b/src/quick/items/qquicktextedit.cpp
@@ -116,11 +116,13 @@ TextEdit {
*/
/*!
- \qmlsignal QtQuick::TextEdit::onLinkActivated(string link)
+ \qmlsignal QtQuick::TextEdit::linkActivated(string link)
- This handler is called when the user clicks on a link embedded in the text.
+ This signal is emitted when the user clicks on a link embedded in the text.
The link must be in rich text or HTML format and the
\a link string provides access to the particular link.
+
+ The corresponding handler is \c onLinkActivated.
*/
// This is a pretty arbitrary figure. The idea is that we don't want to break down the document
@@ -2009,6 +2011,7 @@ void QQuickTextEditPrivate::init()
qmlobject_connect(document, QQuickTextDocumentWithImageResources, SIGNAL(redoAvailable(bool)), q, QQuickTextEdit, SIGNAL(canRedoChanged()));
qmlobject_connect(document, QQuickTextDocumentWithImageResources, SIGNAL(imagesLoaded()), q, QQuickTextEdit, SLOT(updateSize()));
QObject::connect(document, &QQuickTextDocumentWithImageResources::contentsChange, q, &QQuickTextEdit::q_contentsChange);
+ QObject::connect(document->documentLayout(), &QAbstractTextDocumentLayout::updateBlock, q, &QQuickTextEdit::invalidateBlock);
document->setDefaultFont(font);
document->setDocumentMargin(textMargin);
@@ -2243,6 +2246,11 @@ void QQuickTextEdit::updateWholeDocument()
}
}
+void QQuickTextEdit::invalidateBlock(const QTextBlock &block)
+{
+ markDirtyNodesForRange(block.position(), block.position() + block.length(), 0);
+}
+
void QQuickTextEdit::updateCursor()
{
Q_D(QQuickTextEdit);
@@ -2509,13 +2517,15 @@ bool QQuickTextEditPrivate::isLinkHoveredConnected()
}
/*!
- \qmlsignal QtQuick::TextEdit::onLinkHovered(string link)
+ \qmlsignal QtQuick::TextEdit::linkHovered(string link)
\since 5.2
- This handler is called when the user hovers a link embedded in the text.
+ This signal is emitted when the user hovers a link embedded in the text.
The link must be in rich text or HTML format and the
\a link string provides access to the particular link.
+ The corresponding handler is \c onLinkHovered.
+
\sa hoveredLink, linkAt()
*/
@@ -2527,7 +2537,7 @@ bool QQuickTextEditPrivate::isLinkHoveredConnected()
embedded in the text. The link must be in rich text or HTML format
and the link string provides access to the particular link.
- \sa onLinkHovered, linkAt()
+ \sa linkHovered, linkAt()
*/
QString QQuickTextEdit::hoveredLink() const
diff --git a/src/quick/items/qquicktextedit_p.h b/src/quick/items/qquicktextedit_p.h
index b84552d255..c6b7ce3699 100644
--- a/src/quick/items/qquicktextedit_p.h
+++ b/src/quick/items/qquicktextedit_p.h
@@ -50,6 +50,8 @@ QT_BEGIN_NAMESPACE
class QQuickTextDocument;
class QQuickTextEditPrivate;
+class QTextBlock;
+
class Q_QUICK_PRIVATE_EXPORT QQuickTextEdit : public QQuickImplicitSizeItem
{
Q_OBJECT
@@ -326,6 +328,7 @@ private Q_SLOTS:
void createCursor();
void q_canPasteChanged();
void updateWholeDocument();
+ void invalidateBlock(const QTextBlock &block);
void updateCursor();
void q_updateAlignment();
void updateSize();
diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp
index 26dda5db6b..41eb5c0bde 100644
--- a/src/quick/items/qquicktextinput.cpp
+++ b/src/quick/items/qquicktextinput.cpp
@@ -1201,23 +1201,27 @@ bool QQuickTextInput::hasAcceptableInput() const
}
/*!
- \qmlsignal QtQuick::TextInput::onAccepted()
+ \qmlsignal QtQuick::TextInput::accepted()
- This handler is called when the Return or Enter key is pressed.
+ This signal is emitted when the Return or Enter key is pressed.
Note that if there is a \l validator or \l inputMask set on the text
- input, the handler will only be emitted if the input is in an acceptable
+ input, the signal will only be emitted if the input is in an acceptable
state.
+
+ The corresponding handler is \c onAccepted.
*/
/*!
- \qmlsignal QtQuick::TextInput::onEditingFinished()
+ \qmlsignal QtQuick::TextInput::editingFinished()
\since 5.2
- This handler is called when the Return or Enter key is pressed or
+ This signal is emitted when the Return or Enter key is pressed or
the text input loses focus. Note that if there is a validator or
inputMask set on the text input and enter/return is pressed, this
- handler will only be called if the input follows
+ signal will only be emitted if the input follows
the inputMask and the validator returns an acceptable state.
+
+ The corresponding handler is \c onEditingFinished.
*/
#ifndef QT_NO_IM
@@ -2360,7 +2364,6 @@ void QQuickTextInput::setPersistentSelection(bool on)
emit persistentSelectionChanged();
}
-#ifndef QT_NO_CLIPBOARD
/*!
\qmlproperty bool QtQuick::TextInput::canPaste
@@ -2369,6 +2372,7 @@ void QQuickTextInput::setPersistentSelection(bool on)
*/
bool QQuickTextInput::canPaste() const
{
+#if !defined(QT_NO_CLIPBOARD)
Q_D(const QQuickTextInput);
if (!d->canPasteValid) {
if (const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData())
@@ -2376,8 +2380,10 @@ bool QQuickTextInput::canPaste() const
const_cast<QQuickTextInputPrivate *>(d)->canPasteValid = true;
}
return d->canPaste;
-}
+#else
+ return false;
#endif
+}
/*!
\qmlproperty bool QtQuick::TextInput::canUndo
diff --git a/src/quick/items/qquicktextinput_p.h b/src/quick/items/qquicktextinput_p.h
index 5a88273543..211aba8703 100644
--- a/src/quick/items/qquicktextinput_p.h
+++ b/src/quick/items/qquicktextinput_p.h
@@ -100,9 +100,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickTextInput : public QQuickImplicitSizeItem
Q_PROPERTY(bool selectByMouse READ selectByMouse WRITE setSelectByMouse NOTIFY selectByMouseChanged)
Q_PROPERTY(SelectionMode mouseSelectionMode READ mouseSelectionMode WRITE setMouseSelectionMode NOTIFY mouseSelectionModeChanged)
Q_PROPERTY(bool persistentSelection READ persistentSelection WRITE setPersistentSelection NOTIFY persistentSelectionChanged)
-#ifndef QT_NO_CLIPBOARD
Q_PROPERTY(bool canPaste READ canPaste NOTIFY canPasteChanged)
-#endif
Q_PROPERTY(bool canUndo READ canUndo NOTIFY canUndoChanged)
Q_PROPERTY(bool canRedo READ canRedo NOTIFY canRedoChanged)
#ifndef QT_NO_IM
@@ -261,9 +259,7 @@ public:
QRectF boundingRect() const;
QRectF clipRect() const;
-#ifndef QT_NO_CLIPBOARD
bool canPaste() const;
-#endif
bool canUndo() const;
bool canRedo() const;
diff --git a/src/quick/items/qquickview.cpp b/src/quick/items/qquickview.cpp
index 82c1b3a6ae..72c66448b4 100644
--- a/src/quick/items/qquickview.cpp
+++ b/src/quick/items/qquickview.cpp
@@ -58,16 +58,16 @@ QT_BEGIN_NAMESPACE
DEFINE_OBJECT_VTABLE(QQuickRootItemMarker);
-QQuickRootItemMarker::QQuickRootItemMarker(QQuickViewPrivate *view)
- : QV4::Object(QQmlEnginePrivate::getV4Engine(view->engine.data()))
- , view(view)
+QQuickRootItemMarker::QQuickRootItemMarker(QQmlEngine *engine, QQuickWindow *window)
+ : QV4::Object(QQmlEnginePrivate::getV4Engine(engine))
+ , window(window)
{
setVTable(staticVTable());
}
void QQuickRootItemMarker::markObjects(QV4::Managed *that, QV4::ExecutionEngine *e)
{
- QQuickItem *root = static_cast<QQuickRootItemMarker*>(that)->view->root;
+ QQuickItem *root = static_cast<QQuickRootItemMarker*>(that)->window->contentItem();
if (root) {
QQuickItemPrivate *rootPrivate = QQuickItemPrivate::get(root);
rootPrivate->markObjects(e);
@@ -91,7 +91,7 @@ void QQuickViewPrivate::init(QQmlEngine* e)
{
QV4::ExecutionEngine *v4 = QQmlEnginePrivate::getV4Engine(engine.data());
QV4::Scope scope(v4);
- QV4::Scoped<QQuickRootItemMarker> v(scope, new (v4->memoryManager) QQuickRootItemMarker(this));
+ QV4::Scoped<QQuickRootItemMarker> v(scope, new (v4->memoryManager) QQuickRootItemMarker(engine.data(), q));
rootItemMarker = v;
}
diff --git a/src/quick/items/qquickview_p.h b/src/quick/items/qquickview_p.h
index 74e40081e9..dfc8c21d0b 100644
--- a/src/quick/items/qquickview_p.h
+++ b/src/quick/items/qquickview_p.h
@@ -106,7 +106,7 @@ struct QQuickRootItemMarker : public QV4::Object
{
V4_OBJECT
- QQuickRootItemMarker(QQuickViewPrivate *view);
+ QQuickRootItemMarker(QQmlEngine *engine, QQuickWindow *window);
static void destroy(Managed *that)
{
@@ -115,7 +115,7 @@ struct QQuickRootItemMarker : public QV4::Object
static void markObjects(Managed *that, QV4::ExecutionEngine *e);
- QQuickViewPrivate *view;
+ QQuickWindow *window;
};
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index b9713c7b6a..16b48efd86 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -286,7 +286,7 @@ void QQuickWindow::update()
Q_D(QQuickWindow);
if (d->windowManager)
d->windowManager->update(this);
- else
+ else if (d->renderControl)
d->renderControl->update();
}
@@ -450,6 +450,7 @@ void QQuickWindowPrivate::init(QQuickWindow *c, QQuickRenderControl *control)
sg = renderControl->sceneGraphContext();
context = renderControl->renderContext(sg);
} else {
+ windowManager->addWindow(q);
sg = windowManager->sceneGraphContext();
context = windowManager->createRenderContext(sg);
}
@@ -975,8 +976,6 @@ void QQuickWindowPrivate::cleanup(QSGNode *n)
For easily displaying a scene from a QML file, see \l{QQuickView}.
-
-
\section1 Rendering
QQuickWindow uses a scene graph on top of OpenGL to
@@ -1031,6 +1030,9 @@ void QQuickWindowPrivate::cleanup(QSGNode *n)
scene graph and its OpenGL context being deleted. The
sceneGraphInvalidated() signal will be emitted when this happens.
+ \note All classes with QSG prefix should be used solely on the scene graph's
+ rendering thread. See \l {Scene Graph and Rendering} for more information.
+
\sa {Scene Graph - OpenGL Under QML}
*/
@@ -1077,10 +1079,12 @@ QQuickWindow::~QQuickWindow()
Q_D(QQuickWindow);
d->animationController->deleteLater();
- if (d->renderControl)
+ if (d->renderControl) {
d->renderControl->windowDestroyed();
- else
+ } else if (d->windowManager) {
+ d->windowManager->removeWindow(this);
d->windowManager->windowDestroyed(this);
+ }
QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
delete d->incubationController; d->incubationController = 0;
@@ -1090,8 +1094,6 @@ QQuickWindow::~QQuickWindow()
delete d->contentItem; d->contentItem = 0;
}
-
-
/*!
This function tries to release redundant resources currently held by the QML scene.
@@ -1289,9 +1291,11 @@ bool QQuickWindow::event(QEvent *e)
QTouchEvent *touch = static_cast<QTouchEvent*>(e);
d->translateTouchEvent(touch);
d->deliverTouchEvent(touch);
- // we consume all touch events ourselves to avoid duplicate
- // mouse delivery by QtGui mouse synthesis
- e->accept();
+ if (Q_LIKELY(qApp->testAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents))) {
+ // we consume all touch events ourselves to avoid duplicate
+ // mouse delivery by QtGui mouse synthesis
+ e->accept();
+ }
return true;
}
break;
@@ -2389,9 +2393,9 @@ void QQuickWindowPrivate::contextCreationFailureMessage(const QSurfaceFormat &fo
const bool isDebug = QLibraryInfo::isDebugBuild();
const QString eglLibName = QLatin1String(isDebug ? "libEGLd.dll" : "libEGL.dll");
const QString glesLibName = QLatin1String(isDebug ? "libGLESv2d.dll" : "libGLESv2.dll");
- //: %1 Context type (Open GL, EGL), ANGLE %2, %3 library names
+ //: %1 Context type (Open GL, EGL), %2 format, ANGLE %3, %4 library names
const char msg[] = QT_TRANSLATE_NOOP("QQuickWindow",
- "Failed to create %1 context for format %2."
+ "Failed to create %1 context for format %2.\n"
"This is most likely caused by not having the necessary graphics drivers installed.\n\n"
"Install a driver providing OpenGL 2.0 or higher, or, if this is not possible, "
"make sure the ANGLE Open GL ES 2.0 emulation libraries (%3, %4 and d3dcompiler_*.dll) "
@@ -2784,7 +2788,7 @@ void QQuickWindow::maybeUpdate()
Q_D(QQuickWindow);
if (d->renderControl)
d->renderControl->maybeUpdate();
- else
+ else if (d->windowManager)
d->windowManager->maybeUpdate(this);
}
@@ -2856,12 +2860,12 @@ QOpenGLContext *QQuickWindow::openglContext() const
/*!
\fn void QQuickWindow::sceneGraphError(SceneGraphError error, const QString &message)
- This signal is emitted when an error occurred during scene graph initialization.
+ This signal is emitted when an \a error occurred during scene graph initialization.
Applications should connect to this signal if they wish to handle errors,
like OpenGL context creation failures, in a custom way. When no slot is
connected to the signal, the behavior will be different: Quick will print
- the message, or show a message box, and terminate the application.
+ the \a message, or show a message box, and terminate the application.
This signal will be emitted from the gui thread.
@@ -2908,7 +2912,7 @@ QOpenGLContext *QQuickWindow::openglContext() const
*/
/*!
- \qmlsignal closing(CloseEvent close)
+ \qmlsignal QtQuick.Window::Window::closing(CloseEvent close)
\since 5.1
This signal is emitted when the user tries to close the window.
@@ -2917,6 +2921,8 @@ QOpenGLContext *QQuickWindow::openglContext() const
property is true by default so that the window is allowed to close; but you
can implement an onClosing() handler and set close.accepted = false if
you need to do something else before the window can be closed.
+
+ The corresponding handler is \c onClosing.
*/
@@ -3042,7 +3048,7 @@ QImage QQuickWindow::grabWindow()
QOpenGLContext context;
context.setFormat(requestedFormat());
- context.setShareContext(QSGContext::sharedOpenGLContext());
+ context.setShareContext(QOpenGLContextPrivate::globalShareContext());
context.create();
context.makeCurrent(this);
d->context->initialize(&context);
@@ -3051,7 +3057,7 @@ QImage QQuickWindow::grabWindow()
d->syncSceneGraph();
d->renderSceneGraph(size());
- QImage image = qt_gl_read_framebuffer(size(), false, false);
+ QImage image = qt_gl_read_framebuffer(size() * devicePixelRatio(), false, false);
d->cleanupNodesOnShutdown();
d->context->invalidate();
context.doneCurrent();
@@ -3059,7 +3065,11 @@ QImage QQuickWindow::grabWindow()
return image;
}
- return d->renderControl ? d->renderControl->grab() : d->windowManager->grab(this);
+ if (d->renderControl)
+ return d->renderControl->grab();
+ else if (d->windowManager)
+ return d->windowManager->grab(this);
+ return QImage();
}
/*!
@@ -3244,8 +3254,7 @@ QQmlIncubationController *QQuickWindow::incubationController() const
context in the same state as it was when the signal handler was entered. Failing to
do so can result in the scene not rendering properly.
- \sa scenegraphInvalidated()
-
+ \sa sceneGraphInvalidated()
\since 5.3
*/
@@ -3303,6 +3312,10 @@ QSGTexture *QQuickWindow::createTextureFromImage(const QImage &image) const
support QSGTexture::Repeat. Other values from CreateTextureOption are
ignored.
+ The returned texture will be using \c GL_TEXTURE_2D as texture target and
+ \c GL_RGBA as internal format. Reimplement QSGTexture to create textures
+ with different parameters.
+
\warning This function will return 0 if the scene graph has not yet been
initialized.
@@ -3314,7 +3327,7 @@ QSGTexture *QQuickWindow::createTextureFromImage(const QImage &image) const
This function can be called from any thread.
- \sa sceneGraphInitialized()
+ \sa sceneGraphInitialized(), QSGTexture
*/
QSGTexture *QQuickWindow::createTextureFromImage(const QImage &image, CreateTextureOptions options) const
@@ -3337,13 +3350,17 @@ QSGTexture *QQuickWindow::createTextureFromImage(const QImage &image, CreateText
The caller of the function is responsible for deleting the returned texture.
+ The returned texture will be using \c GL_TEXTURE_2D as texture target and
+ assumes that internal format is \c {GL_RGBA}. Reimplement QSGTexture to
+ create textures with different parameters.
+
Use \a options to customize the texture attributes. The TextureUsesAtlas
option is ignored.
\warning This function will return 0 if the scenegraph has not yet been
initialized.
- \sa sceneGraphInitialized()
+ \sa sceneGraphInitialized(), QSGTexture
*/
QSGTexture *QQuickWindow::createTextureFromId(uint id, const QSize &size, CreateTextureOptions options) const
{
diff --git a/src/quick/items/qquickwindowmodule.cpp b/src/quick/items/qquickwindowmodule.cpp
index f6c32dcac3..d06fff8c3e 100644
--- a/src/quick/items/qquickwindowmodule.cpp
+++ b/src/quick/items/qquickwindowmodule.cpp
@@ -41,6 +41,7 @@
#include "qquickwindowmodule_p.h"
#include "qquickscreen_p.h"
+#include "qquickview_p.h"
#include <QtQuick/QQuickWindow>
#include <QtCore/QCoreApplication>
#include <QtQml/QQmlEngine>
@@ -73,7 +74,7 @@ public:
void setVisible(bool visible) {
if (!m_complete)
m_visible = visible;
- else
+ else if (!transientParent() || transientParent()->isVisible())
QQuickWindow::setVisible(visible);
}
@@ -91,16 +92,41 @@ Q_SIGNALS:
protected:
void classBegin() {
+ QQmlEngine* e = qmlEngine(this);
//Give QQuickView behavior when created from QML with QQmlApplicationEngine
if (QCoreApplication::instance()->property("__qml_using_qqmlapplicationengine") == QVariant(true)) {
- QQmlEngine* e = qmlEngine(this);
if (e && !e->incubationController())
e->setIncubationController(incubationController());
}
+ Q_ASSERT(e);
+ {
+ QV4::ExecutionEngine *v4 = QQmlEnginePrivate::getV4Engine(e);
+ QV4::Scope scope(v4);
+ QV4::ScopedObject v(scope, new (v4->memoryManager) QQuickRootItemMarker(e, this));
+ rootItemMarker = v;
+ }
}
void componentComplete() {
m_complete = true;
+ if (transientParent() && !transientParent()->isVisible()) {
+ connect(transientParent(), &QQuickWindow::visibleChanged, this,
+ &QQuickWindowQmlImpl::setWindowVisibility, Qt::QueuedConnection);
+ } else {
+ setWindowVisibility();
+ }
+ }
+
+private Q_SLOTS:
+ void setWindowVisibility()
+ {
+ if (transientParent() && !transientParent()->isVisible())
+ return;
+
+ if (sender()) {
+ disconnect(transientParent(), &QWindow::visibleChanged, this,
+ &QQuickWindowQmlImpl::setWindowVisibility);
+ }
// We have deferred window creation until we have the full picture of what
// the user wanted in terms of window state, geometry, visibility, etc.
@@ -140,6 +166,7 @@ private:
bool m_complete;
bool m_visible;
Visibility m_visibility;
+ QV4::PersistentValue rootItemMarker;
};
void QQuickWindowModule::defineModule()
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
index f525c83009..c9115f35fc 100644
--- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
+++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
@@ -758,6 +758,8 @@ Renderer::Renderer(QSGRenderContext *ctx)
, m_tmpOpaqueElements(16)
, m_rebuild(FullRebuild)
, m_zRange(0)
+ , m_renderOrderRebuildLower(-1)
+ , m_renderOrderRebuildUpper(-1)
, m_currentMaterial(0)
, m_currentShader(0)
, m_currentClip(0)
@@ -1422,8 +1424,11 @@ void Renderer::invalidateBatchAndOverlappingRenderOrders(Batch *batch)
Q_ASSERT(batch);
Q_ASSERT(batch->first);
- int first = batch->first->order;
- int last = batch->lastOrderInBatch;
+ if (m_renderOrderRebuildLower < 0 || batch->first->order < m_renderOrderRebuildLower)
+ m_renderOrderRebuildLower = batch->first->order;
+ if (m_renderOrderRebuildUpper < 0 || batch->lastOrderInBatch > m_renderOrderRebuildUpper)
+ m_renderOrderRebuildUpper = batch->lastOrderInBatch;
+
batch->invalidate();
for (int i=0; i<m_alphaBatches.size(); ++i) {
@@ -1431,7 +1436,7 @@ void Renderer::invalidateBatchAndOverlappingRenderOrders(Batch *batch)
if (b->first) {
int bf = b->first->order;
int bl = b->lastOrderInBatch;
- if (bl > first && bf < last)
+ if (bl > m_renderOrderRebuildLower && bf < m_renderOrderRebuildUpper)
b->invalidate();
}
}
@@ -1444,7 +1449,7 @@ void Renderer::invalidateBatchAndOverlappingRenderOrders(Batch *batch)
*/
void Renderer::cleanupBatches(QDataBuffer<Batch *> *batches) {
if (batches->size()) {
- std::sort(&batches->first(), &batches->last() + 1, qsg_sort_batch_is_valid);
+ std::stable_sort(&batches->first(), &batches->last() + 1, qsg_sort_batch_is_valid);
int count = 0;
while (count < batches->size() && batches->at(count)->first)
++count;
@@ -2190,7 +2195,7 @@ void Renderer::renderUnmergedBatch(const Batch *batch)
if (g->drawingMode() == GL_LINE_STRIP || g->drawingMode() == GL_LINE_LOOP || g->drawingMode() == GL_LINES)
glLineWidth(g->lineWidth());
#if !defined(QT_OPENGL_ES_2)
- else if (g->drawingMode() == GL_POINTS)
+ else if (!QOpenGLContext::currentContext()->isOpenGLES() && g->drawingMode() == GL_POINTS)
glPointSize(g->lineWidth());
#endif
@@ -2430,6 +2435,8 @@ void Renderer::render()
renderBatches();
m_rebuild = 0;
+ m_renderOrderRebuildLower = -1;
+ m_renderOrderRebuildUpper = -1;
if (m_visualizeMode != VisualizeNothing)
visualize();
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
index 96b99a2918..89a33cb8c4 100644
--- a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
+++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
@@ -506,6 +506,8 @@ private:
uint m_rebuild;
qreal m_zRange;
+ int m_renderOrderRebuildLower;
+ int m_renderOrderRebuildUpper;
GLuint m_bufferStrategy;
int m_batchNodeThreshold;
diff --git a/src/quick/scenegraph/coreapi/qsggeometry.cpp b/src/quick/scenegraph/coreapi/qsggeometry.cpp
index 40e0a014ab..43ff1b6240 100644
--- a/src/quick/scenegraph/coreapi/qsggeometry.cpp
+++ b/src/quick/scenegraph/coreapi/qsggeometry.cpp
@@ -286,6 +286,9 @@ const QSGGeometry::AttributeSet &QSGGeometry::defaultAttributes_ColoredPoint2D()
\sa QSGGeometryNode, {Scene Graph - Custom Geometry}
+ \note All classes with QSG prefix should be used solely on the scene graph's
+ rendering thread. See \l {Scene Graph and Rendering} for more information.
+
*/
/*!
diff --git a/src/quick/scenegraph/coreapi/qsgmaterial.cpp b/src/quick/scenegraph/coreapi/qsgmaterial.cpp
index 4954fe20bb..22fe29959e 100644
--- a/src/quick/scenegraph/coreapi/qsgmaterial.cpp
+++ b/src/quick/scenegraph/coreapi/qsgmaterial.cpp
@@ -166,8 +166,8 @@ static bool qsg_leak_check = !qgetenv("QML_LEAK_CHECK").isEmpty();
};
\endcode
- \warning Instances of QSGMaterialShader belongs to the Scene Graph rendering
- thread, and cannot be used from the GUI thread.
+ \note All classes with QSG prefix should be used solely on the scene graph's
+ rendering thread. See \l {Scene Graph and Rendering} for more information.
*/
@@ -550,6 +550,9 @@ static void qt_print_material_count()
\ingroup qtquick-scenegraph-materials
It serves no purpose outside the QSGMaterial::type() function.
+
+ \note All classes with QSG prefix should be used solely on the scene graph's
+ rendering thread. See \l {Scene Graph and Rendering} for more information.
*/
/*!
@@ -585,8 +588,8 @@ static void qt_print_material_count()
};
\endcode
- \warning Instances of QSGMaterial belongs to the Scene Graph rendering thread,
- and cannot be used from the GUI thread.
+ \note All classes with QSG prefix should be used solely on the scene graph's
+ rendering thread. See \l {Scene Graph and Rendering} for more information.
*/
/*!
diff --git a/src/quick/scenegraph/coreapi/qsgnode.cpp b/src/quick/scenegraph/coreapi/qsgnode.cpp
index 5c196b252c..b0a4f20149 100644
--- a/src/quick/scenegraph/coreapi/qsgnode.cpp
+++ b/src/quick/scenegraph/coreapi/qsgnode.cpp
@@ -99,8 +99,8 @@ static void qt_print_node_count()
together. Nodes in a blocked subtree will not be preprocessed() and not
rendered.
- \warning Anything related to QSGNode should happen on the scene graph
- rendering thread.
+ \note All classes with QSG prefix should be used solely on the scene graph's
+ rendering thread. See \l {Scene Graph and Rendering} for more information.
*/
/*!
@@ -683,6 +683,9 @@ void qsgnode_set_description(QSGNode *node, const QString &description)
The QSGBasicGeometryNode class should not be used by itself. It is only encapsulates
shared functionality between the QSGGeometryNode and QSGClipNode classes.
+
+ \note All classes with QSG prefix should be used solely on the scene graph's
+ rendering thread. See \l {Scene Graph and Rendering} for more information.
*/
@@ -824,6 +827,9 @@ void QSGBasicGeometryNode::setGeometry(QSGGeometry *geometry)
to avoid an extra operation in the fragment shader can have significant performance
impact on embedded graphics chips. The opaque material is optional.
+ \note All classes with QSG prefix should be used solely on the scene graph's
+ rendering thread. See \l {Scene Graph and Rendering} for more information.
+
\sa QSGGeometry, QSGMaterial, QSGSimpleMaterial
*/
@@ -1036,6 +1042,9 @@ void QSGGeometryNode::setInheritedOpacity(qreal opacity)
Clip nodes must have a geometry before they can be added to the scene graph.
Clipping is usually implemented by using the stencil buffer.
+
+ \note All classes with QSG prefix should be used solely on the scene graph's
+ rendering thread. See \l {Scene Graph and Rendering} for more information.
*/
@@ -1127,6 +1136,10 @@ void QSGClipNode::setClipRect(const QRectF &rect)
transformations. However, because the renderer optimizes for 2D use-cases rather
than 3D use-cases, rendering a scene with full 3D transformations needs to
be done with some care.
+
+ \note All classes with QSG prefix should be used solely on the scene graph's
+ rendering thread. See \l {Scene Graph and Rendering} for more information.
+
*/
@@ -1264,6 +1277,8 @@ void QSGRootNode::notifyNodeChange(QSGNode *node, DirtyState state)
be marked as blocked, causing isSubtreeBlocked() to return true. This
is done for performance reasons.
+ \note All classes with QSG prefix should be used solely on the scene graph's
+ rendering thread. See \l {Scene Graph and Rendering} for more information.
*/
diff --git a/src/quick/scenegraph/coreapi/qsgrenderer_p.h b/src/quick/scenegraph/coreapi/qsgrenderer_p.h
index 55c9444365..eddd38a68f 100644
--- a/src/quick/scenegraph/coreapi/qsgrenderer_p.h
+++ b/src/quick/scenegraph/coreapi/qsgrenderer_p.h
@@ -134,6 +134,8 @@ public:
virtual void setCustomRenderMode(const QByteArray &) { };
+ void clearChangedFlag() { m_changed_emitted = false; }
+
Q_SIGNALS:
void sceneGraphChanged(); // Add, remove, ChangeFlags changes...
diff --git a/src/quick/scenegraph/qsgcontext.cpp b/src/quick/scenegraph/qsgcontext.cpp
index 9f7818a442..64506d1c26 100644
--- a/src/quick/scenegraph/qsgcontext.cpp
+++ b/src/quick/scenegraph/qsgcontext.cpp
@@ -99,13 +99,8 @@ public:
QSGContextPrivate()
: antialiasingMethod(QSGContext::UndecidedAntialiasing)
, distanceFieldDisabled(qmlDisableDistanceField())
- , distanceFieldAntialiasing(
-#if !defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2_ANGLE)
- QSGGlyphNode::HighQualitySubPixelAntialiasing
-#else
- QSGGlyphNode::GrayAntialiasing
-#endif
- )
+ , distanceFieldAntialiasing(QSGGlyphNode::HighQualitySubPixelAntialiasing)
+ , distanceFieldAntialiasingDecided(false)
{
}
@@ -117,12 +112,9 @@ public:
QSGContext::AntialiasingMethod antialiasingMethod;
bool distanceFieldDisabled;
QSGDistanceFieldGlyphNode::AntialiasingMode distanceFieldAntialiasing;
-
- static QOpenGLContext *sharedOpenGLContext;
+ bool distanceFieldAntialiasingDecided;
};
-QOpenGLContext *QSGContextPrivate::sharedOpenGLContext = 0;
-
class QSGTextureCleanupEvent : public QEvent
{
public:
@@ -161,6 +153,8 @@ QSGContext::QSGContext(QObject *parent) :
{
Q_D(QSGContext);
QByteArray mode = qgetenv("QSG_DISTANCEFIELD_ANTIALIASING");
+ if (!mode.isEmpty())
+ d->distanceFieldAntialiasingDecided = true;
if (mode == "subpixel")
d->distanceFieldAntialiasing = QSGGlyphNode::HighQualitySubPixelAntialiasing;
else if (mode == "subpixel-lowq")
@@ -179,20 +173,6 @@ QSGRenderContext *QSGContext::createRenderContext()
return new QSGRenderContext(this);
}
-/*!
- * This function is used by the Qt WebEngine to set up context sharing
- * across multiple windows. Do not use it for any other purpose.
- */
-void QSGContext::setSharedOpenGLContext(QOpenGLContext *context)
-{
- QSGContextPrivate::sharedOpenGLContext = context;
-}
-
-QOpenGLContext *QSGContext::sharedOpenGLContext()
-{
- return QSGContextPrivate::sharedOpenGLContext;
-}
-
void QSGContext::renderContextInitialized(QSGRenderContext *renderContext)
{
Q_D(QSGContext);
@@ -212,6 +192,17 @@ void QSGContext::renderContextInitialized(QSGRenderContext *renderContext)
}
}
+ // With OpenGL ES, except for Angle on Windows, use GrayAntialiasing, unless
+ // some value had been requested explicitly. This could not be decided
+ // before without a context. Now the context is ready.
+ if (!d->distanceFieldAntialiasingDecided) {
+ d->distanceFieldAntialiasingDecided = true;
+#ifndef Q_OS_WIN
+ if (renderContext->openglContext()->isOpenGLES())
+ d->distanceFieldAntialiasing = QSGGlyphNode::GrayAntialiasing;
+#endif
+ }
+
static bool dumped = false;
if (!dumped && qEnvironmentVariableIsSet("QSG_INFO")) {
dumped = true;
diff --git a/src/quick/scenegraph/qsgcontext_p.h b/src/quick/scenegraph/qsgcontext_p.h
index 2ab78ce289..ac372b9718 100644
--- a/src/quick/scenegraph/qsgcontext_p.h
+++ b/src/quick/scenegraph/qsgcontext_p.h
@@ -168,9 +168,6 @@ public:
virtual QSize minimumFBOSize() const;
virtual QSurfaceFormat defaultSurfaceFormat() const;
- static void setSharedOpenGLContext(QOpenGLContext *context);
- static QOpenGLContext *sharedOpenGLContext();
-
void setDistanceFieldEnabled(bool enabled);
bool isDistanceFieldEnabled() const;
diff --git a/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp b/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp
index a625eebd5d..48b405467b 100644
--- a/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp
+++ b/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp
@@ -231,7 +231,8 @@ void QSGDefaultDistanceFieldGlyphCache::createTexture(TextureInfo *texInfo, int
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
#if !defined(QT_OPENGL_ES_2)
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
+ if (!QOpenGLContext::currentContext()->isOpenGLES())
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
const GLint internalFormat = isCoreProfile() ? GL_R8 : GL_ALPHA;
const GLenum format = isCoreProfile() ? GL_RED : GL_ALPHA;
#else
@@ -373,7 +374,8 @@ void QSGDefaultDistanceFieldGlyphCache::resizeTexture(TextureInfo *texInfo, int
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
#if !defined(QT_OPENGL_ES_2)
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
+ if (!ctx->isOpenGLES())
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
#endif
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, oldWidth, oldHeight, 0,
GL_RGBA, GL_UNSIGNED_BYTE, NULL);
diff --git a/src/quick/scenegraph/qsgdefaultimagenode.cpp b/src/quick/scenegraph/qsgdefaultimagenode.cpp
index 926c0c1f4a..d925b1c7c4 100644
--- a/src/quick/scenegraph/qsgdefaultimagenode.cpp
+++ b/src/quick/scenegraph/qsgdefaultimagenode.cpp
@@ -307,13 +307,11 @@ void QSGDefaultImageNode::preprocess()
markDirty(DirtyMaterial);
}
-#ifdef QT_OPENGL_ES_2
inline static bool isPowerOfTwo(int x)
{
// Assumption: x >= 1
return x == (x & -x);
}
-#endif
namespace {
struct X { float x, tx; };
@@ -360,15 +358,18 @@ void QSGDefaultImageNode::updateGeometry()
bool hasTiles = hTiles != 1 || vTiles != 1;
bool fullTexture = innerSourceRect == QRectF(0, 0, 1, 1);
-#ifdef QT_OPENGL_ES_2
- QOpenGLContext *ctx = QOpenGLContext::currentContext();
- bool npotSupported = ctx->functions()->hasOpenGLFeature(QOpenGLFunctions::NPOTTextureRepeat);
- QSize size = t->textureSize();
- bool isNpot = !isPowerOfTwo(size.width()) || !isPowerOfTwo(size.height());
- bool wrapSupported = npotSupported || !isNpot;
-#else
bool wrapSupported = true;
+
+ QOpenGLContext *ctx = QOpenGLContext::currentContext();
+#ifndef QT_OPENGL_ES_2
+ if (ctx->isOpenGLES())
#endif
+ {
+ bool npotSupported = ctx->functions()->hasOpenGLFeature(QOpenGLFunctions::NPOTTextureRepeat);
+ QSize size = t->textureSize();
+ const bool isNpot = !isPowerOfTwo(size.width()) || !isPowerOfTwo(size.height());
+ wrapSupported = npotSupported || !isNpot;
+ }
// An image can be rendered as a single quad if:
// - There are no margins, and either:
diff --git a/src/quick/scenegraph/qsgdefaultrectanglenode.cpp b/src/quick/scenegraph/qsgdefaultrectanglenode.cpp
index 810a503cee..467f454d0f 100644
--- a/src/quick/scenegraph/qsgdefaultrectanglenode.cpp
+++ b/src/quick/scenegraph/qsgdefaultrectanglenode.cpp
@@ -289,10 +289,22 @@ void QSGDefaultRectangleNode::update()
if (m_dirty_geometry) {
updateGeometry();
m_dirty_geometry = false;
+
+ QSGNode::DirtyState state = QSGNode::DirtyGeometry;
+ // smoothed material is always blended, so no change in material state
+ if (material() == &m_material) {
+ bool wasBlending = (m_material.flags() & QSGMaterial::Blending);
+ bool isBlending = (m_gradient_stops.size() > 0 && !m_gradient_is_opaque)
+ || (m_color.alpha() < 255 && m_color.alpha() != 0)
+ || (m_pen_width > 0 && m_border_color.alpha() < 255);
+ if (wasBlending != isBlending) {
+ m_material.setFlag(QSGMaterial::Blending, isBlending);
+ state |= QSGNode::DirtyMaterial;
+ }
+ }
+
+ markDirty(state);
}
- m_material.setFlag(QSGMaterial::Blending, (m_gradient_stops.size() > 0 && !m_gradient_is_opaque)
- || (m_color.alpha() < 255 && m_color.alpha() != 0)
- || (m_pen_width > 0 && m_border_color.alpha() < 255));
}
void QSGDefaultRectangleNode::updateGeometry()
@@ -770,8 +782,6 @@ void QSGDefaultRectangleNode::updateGeometry()
Q_ASSERT(outerAATail == indexCount);
}
}
-
- markDirty(DirtyGeometry);
}
diff --git a/src/quick/scenegraph/qsgrenderloop.cpp b/src/quick/scenegraph/qsgrenderloop.cpp
index 00e67aa944..38de4a5c39 100644
--- a/src/quick/scenegraph/qsgrenderloop.cpp
+++ b/src/quick/scenegraph/qsgrenderloop.cpp
@@ -45,7 +45,6 @@
#include <QtCore/QCoreApplication>
#include <QtCore/QTime>
-#include <QtCore/QScopedPointer>
#include <QtCore/QLibraryInfo>
#include <QtCore/private/qabstractanimation_p.h>
@@ -82,12 +81,27 @@ extern Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_
DEFINE_BOOL_CONFIG_OPTION(qmlNoThreadedRenderer, QML_BAD_GUI_RENDER_LOOP);
DEFINE_BOOL_CONFIG_OPTION(qmlForceThreadedRenderer, QML_FORCE_THREADED_RENDERER); // Might trigger graphics driver threading bugs, use at own risk
-Q_GLOBAL_STATIC(QScopedPointer<QSGRenderLoop>, s_renderLoopInstance);
+QSGRenderLoop *QSGRenderLoop::s_instance = 0;
QSGRenderLoop::~QSGRenderLoop()
{
}
+void QSGRenderLoop::cleanup()
+{
+ if (!s_instance)
+ return;
+ foreach (QQuickWindow *w, s_instance->windows()) {
+ QQuickWindowPrivate *wd = QQuickWindowPrivate::get(w);
+ if (wd->windowManager == s_instance) {
+ s_instance->windowDestroyed(w);
+ wd->windowManager = 0;
+ }
+ }
+ delete s_instance;
+ s_instance = 0;
+}
+
class QSGGuiThreadRenderLoop : public QSGRenderLoop
{
Q_OBJECT
@@ -148,8 +162,8 @@ bool QSGRenderLoop::useConsistentTiming()
QSGRenderLoop *QSGRenderLoop::instance()
{
- if (s_renderLoopInstance->isNull()) {
- s_renderLoopInstance->reset(QSGContext::createWindowManager());
+ if (!s_instance) {
+ s_instance = QSGContext::createWindowManager();
bool info = qEnvironmentVariableIsSet("QSG_INFO");
@@ -159,7 +173,7 @@ QSGRenderLoop *QSGRenderLoop::instance()
qDebug() << "QSG: using fixed animation steps";
}
- if (s_renderLoopInstance->isNull()) {
+ if (!s_instance) {
enum RenderLoopType {
BasicRenderLoop,
@@ -191,26 +205,28 @@ QSGRenderLoop *QSGRenderLoop::instance()
switch (loopType) {
case ThreadedRenderLoop:
if (info) qDebug() << "QSG: threaded render loop";
- s_renderLoopInstance->reset(new QSGThreadedRenderLoop());
+ s_instance = new QSGThreadedRenderLoop();
break;
case WindowsRenderLoop:
if (info) qDebug() << "QSG: windows render loop";
- s_renderLoopInstance->reset(new QSGWindowsRenderLoop());
+ s_instance = new QSGWindowsRenderLoop();
break;
default:
if (info) qDebug() << "QSG: basic render loop";
- s_renderLoopInstance->reset(new QSGGuiThreadRenderLoop());
+ s_instance = new QSGGuiThreadRenderLoop();
break;
}
}
+
+ qAddPostRoutine(QSGRenderLoop::cleanup);
}
- return s_renderLoopInstance->data();
+ return s_instance;
}
void QSGRenderLoop::setInstance(QSGRenderLoop *instance)
{
- Q_ASSERT(s_renderLoopInstance->isNull());
- s_renderLoopInstance->reset(instance);
+ Q_ASSERT(!s_instance);
+ s_instance = instance;
}
void QSGRenderLoop::handleContextCreationFailure(QQuickWindow *window,
@@ -295,6 +311,8 @@ void QSGGuiThreadRenderLoop::windowDestroyed(QQuickWindow *window)
QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
delete gl;
gl = 0;
+ } else if (window == gl->surface()) {
+ gl->doneCurrent();
}
}
@@ -311,10 +329,10 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window)
if (!gl) {
gl = new QOpenGLContext();
gl->setFormat(window->requestedFormat());
- if (QSGContext::sharedOpenGLContext())
- gl->setShareContext(QSGContext::sharedOpenGLContext());
+ if (QOpenGLContextPrivate::globalShareContext())
+ gl->setShareContext(QOpenGLContextPrivate::globalShareContext());
if (!gl->create()) {
- const bool isEs = gl->isES();
+ const bool isEs = gl->isOpenGLES();
delete gl;
gl = 0;
handleContextCreationFailure(window, isEs);
@@ -361,7 +379,7 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window)
renderTime = renderTimer.nsecsElapsed() - syncTime;
if (data.grabOnly) {
- grabContent = qt_gl_read_framebuffer(window->size(), false, false);
+ grabContent = qt_gl_read_framebuffer(window->size() * window->devicePixelRatio(), false, false);
data.grabOnly = false;
}
diff --git a/src/quick/scenegraph/qsgrenderloop_p.h b/src/quick/scenegraph/qsgrenderloop_p.h
index 2418af4157..8d5312b188 100644
--- a/src/quick/scenegraph/qsgrenderloop_p.h
+++ b/src/quick/scenegraph/qsgrenderloop_p.h
@@ -44,6 +44,7 @@
#include <QtGui/QImage>
#include <private/qtquickglobal_p.h>
+#include <QtCore/QSet>
QT_BEGIN_NAMESPACE
@@ -78,6 +79,10 @@ public:
virtual void releaseResources(QQuickWindow *window) = 0;
+ void addWindow(QQuickWindow *win) { m_windows.insert(win); }
+ void removeWindow(QQuickWindow *win) { m_windows.remove(win); }
+ QSet<QQuickWindow *> windows() const { return m_windows; }
+
// ### make this less of a singleton
static QSGRenderLoop *instance();
static void setInstance(QSGRenderLoop *instance);
@@ -86,11 +91,18 @@ public:
virtual bool interleaveIncubation() const { return false; }
+ static void cleanup();
+
Q_SIGNALS:
void timeToIncubate();
protected:
void handleContextCreationFailure(QQuickWindow *window, bool isEs);
+
+private:
+ static QSGRenderLoop *s_instance;
+
+ QSet<QQuickWindow *> m_windows;
};
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp
index a5b46b7c75..1ba54ea19e 100644
--- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp
+++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp
@@ -62,6 +62,7 @@
#include <private/qquickanimatorcontroller_p.h>
#include <private/qquickprofiler_p.h>
+#include <private/qqmldebugservice_p.h>
/*
Overall design:
@@ -428,7 +429,7 @@ bool QSGRenderThread::event(QEvent *e)
QQuickWindowPrivate::get(window)->renderSceneGraph(windowSize);
QSG_RT_DEBUG(" - grabbing result...");
- *ce->image = qt_gl_read_framebuffer(windowSize, false, false);
+ *ce->image = qt_gl_read_framebuffer(windowSize * window->devicePixelRatio(), false, false);
}
QSG_RT_DEBUG(" - waking gui to handle grab result");
waitCondition.wakeOne();
@@ -513,6 +514,10 @@ void QSGRenderThread::sync(bool inExpose)
if (current) {
QQuickWindowPrivate *d = QQuickWindowPrivate::get(window);
bool hadRenderer = d->renderer != 0;
+ // If the scene graph was touched since the last sync() make sure it sends the
+ // changed signal.
+ if (d->renderer)
+ d->renderer->clearChangedFlag();
d->syncSceneGraph();
if (!hadRenderer && d->renderer) {
QSG_RT_DEBUG(" - renderer was created, hooking up changed signal");
@@ -663,6 +668,8 @@ void QSGRenderThread::run()
animatorDriver = sgrc->sceneGraphContext()->createAnimationDriver(0);
animatorDriver->install();
QUnifiedTimer::instance(true)->setConsistentTiming(QSGRenderLoop::useConsistentTiming());
+ if (QQmlDebugService::isDebuggingEnabled())
+ QQuickProfiler::registerAnimationCallback();
while (active) {
@@ -791,8 +798,6 @@ void QSGThreadedRenderLoop::startOrStopAnimationTimer()
}
}
-
-
/*
Removes this window from the list of tracked windowes in this
window manager. hide() will trigger obscure, which in turn will
@@ -873,6 +878,7 @@ void QSGThreadedRenderLoop::handleExposure(QQuickWindow *window)
QSG_GUI_DEBUG(window, " - adding window to list");
Window win;
win.window = window;
+ win.actualWindowFormat = window->format();
win.thread = new QSGRenderThread(this, QQuickWindowPrivate::get(window)->context);
win.timerId = 0;
win.updateDuringSync = false;
@@ -899,11 +905,11 @@ void QSGThreadedRenderLoop::handleExposure(QQuickWindow *window)
if (!w->thread->gl) {
w->thread->gl = new QOpenGLContext();
- if (QSGContext::sharedOpenGLContext())
- w->thread->gl->setShareContext(QSGContext::sharedOpenGLContext());
+ if (QOpenGLContextPrivate::globalShareContext())
+ w->thread->gl->setShareContext(QOpenGLContextPrivate::globalShareContext());
w->thread->gl->setFormat(w->window->requestedFormat());
if (!w->thread->gl->create()) {
- const bool isEs = w->thread->gl->isES();
+ const bool isEs = w->thread->gl->isOpenGLES();
delete w->thread->gl;
w->thread->gl = 0;
handleContextCreationFailure(w->window, isEs);
@@ -1045,7 +1051,7 @@ void QSGThreadedRenderLoop::releaseResources(Window *w, bool inDestructor)
if (!window->handle()) {
QSG_GUI_DEBUG(window, " - using fallback surface");
fallback = new QOffscreenSurface();
- fallback->setFormat(window->requestedFormat());
+ fallback->setFormat(w->actualWindowFormat);
fallback->create();
}
diff --git a/src/quick/scenegraph/qsgthreadedrenderloop_p.h b/src/quick/scenegraph/qsgthreadedrenderloop_p.h
index 970bd63040..b86b3c73a4 100644
--- a/src/quick/scenegraph/qsgthreadedrenderloop_p.h
+++ b/src/quick/scenegraph/qsgthreadedrenderloop_p.h
@@ -87,6 +87,7 @@ private:
struct Window {
QQuickWindow *window;
QSGRenderThread *thread;
+ QSurfaceFormat actualWindowFormat;
int timerId;
uint updateDuringSync : 1;
};
diff --git a/src/quick/scenegraph/qsgwindowsrenderloop.cpp b/src/quick/scenegraph/qsgwindowsrenderloop.cpp
index 32f52417bb..dc12d00490 100644
--- a/src/quick/scenegraph/qsgwindowsrenderloop.cpp
+++ b/src/quick/scenegraph/qsgwindowsrenderloop.cpp
@@ -179,11 +179,11 @@ void QSGWindowsRenderLoop::show(QQuickWindow *window)
RLDEBUG(" - creating GL context");
m_gl = new QOpenGLContext();
m_gl->setFormat(window->requestedFormat());
- if (QSGContext::sharedOpenGLContext())
- m_gl->setShareContext(QSGContext::sharedOpenGLContext());
+ if (QOpenGLContextPrivate::globalShareContext())
+ m_gl->setShareContext(QOpenGLContextPrivate::globalShareContext());
bool created = m_gl->create();
if (!created) {
- const bool isEs = m_gl->isES();
+ const bool isEs = m_gl->isOpenGLES();
delete m_gl;
m_gl = 0;
handleContextCreationFailure(window, isEs);
@@ -341,7 +341,7 @@ QImage QSGWindowsRenderLoop::grab(QQuickWindow *window)
d->syncSceneGraph();
d->renderSceneGraph(window->size());
- QImage image = qt_gl_read_framebuffer(window->size(), false, false);
+ QImage image = qt_gl_read_framebuffer(window->size() * window->devicePixelRatio(), false, false);
return image;
}
diff --git a/src/quick/scenegraph/util/qsgatlastexture.cpp b/src/quick/scenegraph/util/qsgatlastexture.cpp
index 99d1d60258..1ff7d11162 100644
--- a/src/quick/scenegraph/util/qsgatlastexture.cpp
+++ b/src/quick/scenegraph/util/qsgatlastexture.cpp
@@ -143,7 +143,13 @@ Atlas::Atlas(const QSize &size)
, m_allocated(false)
{
-#ifdef QT_OPENGL_ES
+ m_internalFormat = GL_RGBA;
+ m_externalFormat = GL_BGRA;
+
+#ifndef QT_OPENGL_ES
+ if (QOpenGLContext::currentContext()->isOpenGLES()) {
+#endif
+
#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_NO_SDK)
QString *deviceName =
static_cast<QString *>(QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("AndroidDeviceName"));
@@ -153,7 +159,7 @@ Atlas::Atlas(const QSize &size)
|| deviceName->compare(QStringLiteral("samsung SM-T215"), Qt::CaseInsensitive) == 0);
#else
static bool wrongfullyReportsBgra8888Support = false;
-#endif
+#endif // ANDROID
const char *ext = (const char *) glGetString(GL_EXTENSIONS);
if (!wrongfullyReportsBgra8888Support
@@ -165,13 +171,13 @@ Atlas::Atlas(const QSize &size)
} else if (strstr(ext, "GL_APPLE_texture_format_BGRA8888")) {
m_internalFormat = GL_RGBA;
m_externalFormat = GL_BGRA;
-#endif
+#endif // IOS
} else {
m_internalFormat = m_externalFormat = GL_RGBA;
}
-#else
- m_internalFormat = GL_RGBA;
- m_externalFormat = GL_BGRA;
+
+#ifndef QT_OPENGL_ES
+ }
#endif
m_use_bgra_fallback = qEnvironmentVariableIsSet("QSG_ATLAS_USE_BGRA_FALLBACK");
@@ -326,7 +332,8 @@ void Atlas::bind(QSGTexture::Filtering filtering)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
#if !defined(QT_OPENGL_ES_2)
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
+ if (!QOpenGLContext::currentContext()->isOpenGLES())
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
#endif
glTexImage2D(GL_TEXTURE_2D, 0, m_internalFormat, m_size.width(), m_size.height(), 0, m_externalFormat, GL_UNSIGNED_BYTE, 0);
diff --git a/src/quick/scenegraph/util/qsgdepthstencilbuffer.cpp b/src/quick/scenegraph/util/qsgdepthstencilbuffer.cpp
index 59bde0d602..f5a75fd627 100644
--- a/src/quick/scenegraph/util/qsgdepthstencilbuffer.cpp
+++ b/src/quick/scenegraph/util/qsgdepthstencilbuffer.cpp
@@ -75,8 +75,6 @@ void QSGDepthStencilBuffer::detach()
GL_RENDERBUFFER, 0);
}
-// ###TODO Remove once using Khronos OpenGL headers
-#if defined(QT_OPENGL_ES_2)
#ifndef GL_DEPTH24_STENCIL8_OES
#define GL_DEPTH24_STENCIL8_OES 0x88F0
#endif
@@ -84,7 +82,6 @@ void QSGDepthStencilBuffer::detach()
#ifndef GL_DEPTH_COMPONENT24_OES
#define GL_DEPTH_COMPONENT24_OES 0x81A6
#endif
-#endif
QSGDefaultDepthStencilBuffer::QSGDefaultDepthStencilBuffer(QOpenGLContext *context, const Format &format)
: QSGDepthStencilBuffer(context, format)
@@ -117,12 +114,10 @@ QSGDefaultDepthStencilBuffer::QSGDefaultDepthStencilBuffer(QOpenGLContext *conte
if (!m_depthBuffer && (format.attachments & DepthAttachment)) {
m_functions.glGenRenderbuffers(1, &m_depthBuffer);
m_functions.glBindRenderbuffer(GL_RENDERBUFFER, m_depthBuffer);
-#ifdef QT_OPENGL_ES
- const GLenum internalFormat = m_functions.hasOpenGLExtension(QOpenGLExtensions::Depth24)
+ GLenum internalFormat = GL_DEPTH_COMPONENT;
+ if (context->isOpenGLES())
+ internalFormat = m_functions.hasOpenGLExtension(QOpenGLExtensions::Depth24)
? GL_DEPTH_COMPONENT24_OES : GL_DEPTH_COMPONENT16;
-#else
- const GLenum internalFormat = GL_DEPTH_COMPONENT;
-#endif
if (format.samples && m_functions.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample)) {
m_functions.glRenderbufferStorageMultisample(GL_RENDERBUFFER, format.samples,
internalFormat, width, height);
@@ -136,7 +131,7 @@ QSGDefaultDepthStencilBuffer::QSGDefaultDepthStencilBuffer(QOpenGLContext *conte
#ifdef QT_OPENGL_ES
const GLenum internalFormat = GL_STENCIL_INDEX8;
#else
- const GLenum internalFormat = GL_STENCIL_INDEX;
+ const GLenum internalFormat = context->isOpenGLES() ? GL_STENCIL_INDEX8 : GL_STENCIL_INDEX;
#endif
if (format.samples && m_functions.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample)) {
m_functions.glRenderbufferStorageMultisample(GL_RENDERBUFFER, format.samples,
diff --git a/src/quick/scenegraph/util/qsgsimplematerial.cpp b/src/quick/scenegraph/util/qsgsimplematerial.cpp
index a247b37d77..ada4dd6c4f 100644
--- a/src/quick/scenegraph/util/qsgsimplematerial.cpp
+++ b/src/quick/scenegraph/util/qsgsimplematerial.cpp
@@ -142,6 +142,9 @@
the unique QSGSimpleMaterialShader implementation must be
instantiated with a unique C++ type.
+ \note All classes with QSG prefix should be used solely on the scene graph's
+ rendering thread. See \l {Scene Graph and Rendering} for more information.
+
\sa {Scene Graph - Simple Material}
*/
@@ -244,6 +247,9 @@
\inmodule QtQuick
+ \note All classes with QSG prefix should be used solely on the scene graph's
+ rendering thread. See \l {Scene Graph and Rendering} for more information.
+
\sa QSGSimpleMaterialShader
*/
diff --git a/src/quick/scenegraph/util/qsgsimpletexturenode.cpp b/src/quick/scenegraph/util/qsgsimpletexturenode.cpp
index 47cb82d01b..bbf115fa2a 100644
--- a/src/quick/scenegraph/util/qsgsimpletexturenode.cpp
+++ b/src/quick/scenegraph/util/qsgsimpletexturenode.cpp
@@ -107,6 +107,8 @@ QSGSimpleTextureNode::QSGSimpleTextureNode()
setGeometry(&m_geometry);
setMaterial(&m_material);
setOpaqueMaterial(&m_opaque_material);
+ m_material.setMipmapFiltering(QSGTexture::None);
+ m_opaque_material.setMipmapFiltering(QSGTexture::None);
#ifdef QSG_RUNTIME_DESCRIPTION
qsgnode_set_description(this, QLatin1String("simpletexture"));
#endif
diff --git a/src/quick/scenegraph/util/qsgtexture.cpp b/src/quick/scenegraph/util/qsgtexture.cpp
index 3bbcb0c112..cd0b64fe49 100644
--- a/src/quick/scenegraph/util/qsgtexture.cpp
+++ b/src/quick/scenegraph/util/qsgtexture.cpp
@@ -39,8 +39,6 @@
**
****************************************************************************/
-#define GL_GLEXT_PROTOTYPES
-
#include "qsgtexture_p.h"
#include <qopenglfunctions.h>
#include <QtQuick/private/qsgcontext_p.h>
@@ -83,7 +81,7 @@ static QElapsedTimer qsg_renderer_timer;
QT_BEGIN_NAMESPACE
-#if !defined(QT_NO_DEBUG) && defined(QT_OPENGL_ES_2)
+#ifndef QT_NO_DEBUG
inline static bool isPowerOfTwo(int x)
{
// Assumption: x >= 1
@@ -237,6 +235,9 @@ static void qt_debug_remove_texture(QSGTexture* texture)
the function removedFromAtlas() can be used to extract a
non-atlassed copy.
+ \note All classes with QSG prefix should be used solely on the scene graph's
+ rendering thread. See \l {Scene Graph and Rendering} for more information.
+
\sa {Scene Graph - Rendering FBOs}, {Scene Graph - Rendering FBOs in a thread}
*/
@@ -514,7 +515,7 @@ void QSGTexture::updateBindOptions(bool force)
}
if (force || d->wrapChanged) {
-#if !defined(QT_NO_DEBUG) && defined(QT_OPENGL_ES_2)
+#ifndef QT_NO_DEBUG
if (d->horizontalWrap == Repeat || d->verticalWrap == Repeat) {
bool npotSupported = QOpenGLFunctions(QOpenGLContext::currentContext()).hasOpenGLFeature(QOpenGLFunctions::NPOTTextures);
QSize size = textureSize();
@@ -566,6 +567,7 @@ void QSGPlainTexture::setImage(const QImage &image)
m_has_alpha = image.hasAlphaChannel();
m_dirty_texture = true;
m_dirty_bind_options = true;
+ m_mipmaps_generated = false;
}
int QSGPlainTexture::textureId() const
@@ -686,7 +688,10 @@ void QSGPlainTexture::bind()
externalFormat = GL_BGRA;
#ifdef QT_OPENGL_ES
internalFormat = GL_BGRA;
-#endif
+#else
+ if (context->isOpenGLES())
+ internalFormat = GL_BGRA;
+#endif // QT_OPENGL_ES
} else if (!wrongfullyReportsBgra8888Support
&& (context->hasExtension(QByteArrayLiteral("GL_EXT_texture_format_BGRA8888"))
|| context->hasExtension(QByteArrayLiteral("GL_IMG_texture_format_BGRA8888")))) {
@@ -765,6 +770,9 @@ void QSGPlainTexture::bind()
To update the content of the texture, call updateTexture() explicitly. Simply calling bind()
will not update the texture.
+
+ \note All classes with QSG prefix should be used solely on the scene graph's
+ rendering thread. See \l {Scene Graph and Rendering} for more information.
*/
diff --git a/src/quick/scenegraph/util/qsgtexturematerial.cpp b/src/quick/scenegraph/util/qsgtexturematerial.cpp
index df55404504..afa535d322 100644
--- a/src/quick/scenegraph/util/qsgtexturematerial.cpp
+++ b/src/quick/scenegraph/util/qsgtexturematerial.cpp
@@ -46,13 +46,11 @@
QT_BEGIN_NAMESPACE
-#ifdef QT_OPENGL_ES_2
inline static bool isPowerOfTwo(int x)
{
// Assumption: x >= 1
return x == (x & -x);
}
-#endif
QSGMaterialType QSGOpaqueTextureMaterialShader::type;
@@ -83,19 +81,20 @@ void QSGOpaqueTextureMaterialShader::updateState(const RenderState &state, QSGMa
QSGTexture *t = tx->texture();
t->setFiltering(tx->filtering());
-#ifdef QT_OPENGL_ES_2
- bool npotSupported = QOpenGLFunctions(const_cast<QOpenGLContext *>(state.context())).hasOpenGLFeature(QOpenGLFunctions::NPOTTextureRepeat);
- QSize size = t->textureSize();
- bool isNpot = !isPowerOfTwo(size.width()) || !isPowerOfTwo(size.height());
- if (!npotSupported && isNpot) {
- t->setHorizontalWrapMode(QSGTexture::ClampToEdge);
- t->setVerticalWrapMode(QSGTexture::ClampToEdge);
- } else
-#endif
- {
- t->setHorizontalWrapMode(tx->horizontalWrapMode());
- t->setVerticalWrapMode(tx->verticalWrapMode());
+
+ t->setHorizontalWrapMode(tx->horizontalWrapMode());
+ t->setVerticalWrapMode(tx->verticalWrapMode());
+ bool npotSupported = const_cast<QOpenGLContext *>(state.context())
+ ->functions()->hasOpenGLFeature(QOpenGLFunctions::NPOTTextureRepeat);
+ if (!npotSupported) {
+ QSize size = t->textureSize();
+ const bool isNpot = !isPowerOfTwo(size.width()) || !isPowerOfTwo(size.height());
+ if (isNpot) {
+ t->setHorizontalWrapMode(QSGTexture::ClampToEdge);
+ t->setVerticalWrapMode(QSGTexture::ClampToEdge);
+ }
}
+
t->setMipmapFiltering(tx->mipmapFiltering());
if (oldTx == 0 || oldTx->texture()->textureId() != t->textureId())
@@ -153,7 +152,7 @@ void QSGOpaqueTextureMaterialShader::updateState(const RenderState &state, QSGMa
QSGOpaqueTextureMaterial::QSGOpaqueTextureMaterial()
: m_texture(0)
, m_filtering(QSGTexture::Nearest)
- , m_mipmap_filtering(QSGTexture::Nearest)
+ , m_mipmap_filtering(QSGTexture::None)
, m_horizontal_wrap(QSGTexture::ClampToEdge)
, m_vertical_wrap(QSGTexture::ClampToEdge)
{
diff --git a/src/quick/util/qquickanimation.cpp b/src/quick/util/qquickanimation.cpp
index 36316e27c0..10d2176d0a 100644
--- a/src/quick/util/qquickanimation.cpp
+++ b/src/quick/util/qquickanimation.cpp
@@ -200,19 +200,21 @@ QQmlProperty QQuickAbstractAnimationPrivate::createProperty(QObject *obj, const
}
/*!
- \qmlsignal QtQuick::Animation::onStarted()
+ \qmlsignal QtQuick::Animation::started()
- This signal handler is called when the animation begins.
+ This signal is emitted when the animation begins.
It is only triggered for top-level, standalone animations. It will not be
triggered for animations in a Behavior or Transition, or animations
that are part of an animation group.
+
+ The corresponding handler is \c onStarted.
*/
/*!
- \qmlsignal QtQuick::Animation::onStopped()
+ \qmlsignal QtQuick::Animation::stopped()
- This signal handler is called when the animation ends.
+ This signal is emitted when the animation ends.
The animation may have been stopped manually, or may have run to completion.
@@ -220,8 +222,10 @@ QQmlProperty QQuickAbstractAnimationPrivate::createProperty(QObject *obj, const
triggered for animations in a Behavior or Transition, or animations
that are part of an animation group.
- If \l alwaysRunToEnd is true, onStopped will not be called until the animation
+ If \l alwaysRunToEnd is true, this signal will not be emitted until the animation
has completed its current iteration.
+
+ The corresponding handler is \c onStopped.
*/
void QQuickAbstractAnimation::setRunning(bool r)
@@ -869,6 +873,19 @@ void QActionAnimation::updateState(State newState, State oldState)
}
}
+void QActionAnimation::debugAnimation(QDebug d) const
+{
+ d << "ActionAnimation(" << hex << (void *) this << dec << ")";
+
+ if (animAction) {
+ int indentLevel = 1;
+ const QAbstractAnimationJob *job = this;
+ while ((job = job->group()))
+ ++indentLevel;
+ animAction->debugAction(d, indentLevel);
+ }
+}
+
/*!
\qmltype ScriptAction
\instantiates QQuickScriptAction
@@ -953,6 +970,22 @@ QAbstractAnimationAction* QQuickScriptActionPrivate::createAction()
return new Proxy(this);
}
+void QQuickScriptActionPrivate::debugAction(QDebug d, int indentLevel) const
+{
+ QQmlScriptString scriptStr = hasRunScriptScript ? runScriptScript : script;
+
+ if (!scriptStr.isEmpty()) {
+ QQmlExpression expr(scriptStr);
+
+ QByteArray ind(indentLevel, ' ');
+ QString exprStr = expr.expression();
+ int endOfFirstLine = exprStr.indexOf('\n');
+ d << "\n" << ind.constData() << exprStr.left(endOfFirstLine);
+ if (endOfFirstLine != -1 && endOfFirstLine < exprStr.length())
+ d << "...";
+ }
+}
+
void QQuickScriptActionPrivate::execute()
{
Q_Q(QQuickScriptAction);
@@ -1166,6 +1199,14 @@ QAbstractAnimationJob* QQuickPropertyAction::transition(QQuickStateActions &acti
QQmlPropertyPrivate::write(action.property, action.toValue, QQmlPropertyPrivate::BypassInterceptor | QQmlPropertyPrivate::DontRemoveBinding);
}
}
+ virtual void debugAction(QDebug d, int indentLevel) const {
+ QByteArray ind(indentLevel, ' ');
+ for (int ii = 0; ii < actions.count(); ++ii) {
+ const QQuickStateAction &action = actions.at(ii);
+ d << "\n" << ind.constData() << "target:" << action.property.object() << "property:" << action.property.name()
+ << "value:" << action.toValue;
+ }
+ }
};
QStringList props = d->properties.isEmpty() ? QStringList() : d->properties.split(QLatin1Char(','));
@@ -1925,6 +1966,19 @@ void QQuickBulkValueAnimator::topLevelAnimationLoopChanged()
QAbstractAnimationJob::topLevelAnimationLoopChanged();
}
+void QQuickBulkValueAnimator::debugAnimation(QDebug d) const
+{
+ d << "BulkValueAnimation(" << hex << (void *) this << dec << ")" << "duration:" << duration();
+
+ if (animValue) {
+ int indentLevel = 1;
+ const QAbstractAnimationJob *job = this;
+ while ((job = job->group()))
+ ++indentLevel;
+ animValue->debugUpdater(d, indentLevel);
+ }
+}
+
/*!
\qmltype PropertyAnimation
\instantiates QQuickPropertyAnimation
@@ -2498,6 +2552,16 @@ void QQuickAnimationPropertyUpdater::setValue(qreal v)
fromSourced = true;
}
+void QQuickAnimationPropertyUpdater::debugUpdater(QDebug d, int indentLevel) const
+{
+ QByteArray ind(indentLevel, ' ');
+ for (int i = 0; i < actions.count(); ++i) {
+ const QQuickStateAction &action = actions.at(i);
+ d << "\n" << ind.constData() << "target:" << action.property.object() << "property:" << action.property.name()
+ << "from:" << action.fromValue << "to:" << action.toValue;
+ }
+}
+
QQuickStateActions QQuickPropertyAnimation::createTransitionActions(QQuickStateActions &actions,
QQmlProperties &modified,
QObject *defaultTarget)
diff --git a/src/quick/util/qquickanimation_p_p.h b/src/quick/util/qquickanimation_p_p.h
index 127f447e5d..f2b5f6388f 100644
--- a/src/quick/util/qquickanimation_p_p.h
+++ b/src/quick/util/qquickanimation_p_p.h
@@ -79,18 +79,19 @@ class QAbstractAnimationAction
public:
virtual ~QAbstractAnimationAction() {}
virtual void doAction() = 0;
+ virtual void debugAction(QDebug, int) const {}
};
//templated animation action
//allows us to specify an action that calls a function of a class.
//(so that class doesn't have to inherit QQuickAbstractAnimationAction)
-template<class T, void (T::*method)()>
+template<class T, void (T::*method)(), void (T::*debugMethod)(QDebug, int) const>
class QAnimationActionProxy : public QAbstractAnimationAction
{
public:
QAnimationActionProxy(T *instance) : m_instance(instance) {}
virtual void doAction() { (m_instance->*method)(); }
-
+ virtual void debugAction(QDebug d, int indentLevel) const { (m_instance->*debugMethod)(d, indentLevel); }
private:
T *m_instance;
};
@@ -111,6 +112,7 @@ public:
protected:
virtual void updateCurrentTime(int);
virtual void updateState(State newState, State oldState);
+ void debugAnimation(QDebug d) const;
private:
QAbstractAnimationAction *animAction;
@@ -121,6 +123,7 @@ class QQuickBulkValueUpdater
public:
virtual ~QQuickBulkValueUpdater() {}
virtual void setValue(qreal value) = 0;
+ virtual void debugUpdater(QDebug, int) const {}
};
//animates QQuickBulkValueUpdater (assumes start and end values will be reals or compatible)
@@ -145,6 +148,7 @@ public:
protected:
void updateCurrentTime(int currentTime);
void topLevelAnimationLoopChanged();
+ void debugAnimation(QDebug d) const;
private:
QQuickBulkValueUpdater *animValue;
@@ -224,8 +228,10 @@ public:
void execute();
QAbstractAnimationAction* createAction();
+ void debugAction(QDebug d, int indentLevel) const;
typedef QAnimationActionProxy<QQuickScriptActionPrivate,
- &QQuickScriptActionPrivate::execute> Proxy;
+ &QQuickScriptActionPrivate::execute,
+ &QQuickScriptActionPrivate::debugAction> Proxy;
};
class QQuickPropertyActionPrivate : public QQuickAbstractAnimationPrivate
@@ -307,6 +313,8 @@ public:
void setValue(qreal v);
+ void debugUpdater(QDebug d, int indentLevel) const;
+
QQuickStateActions actions;
int interpolatorType; //for Number/ColorAnimation
QVariantAnimation::Interpolator interpolator;
diff --git a/src/quick/util/qquickglobal.cpp b/src/quick/util/qquickglobal.cpp
index 5ae74c2fec..4428452aa0 100644
--- a/src/quick/util/qquickglobal.cpp
+++ b/src/quick/util/qquickglobal.cpp
@@ -61,23 +61,9 @@ QT_BEGIN_NAMESPACE
class QQuickColorProvider : public QQmlColorProvider
{
public:
- static inline QColor QColorFromString(const QString &s)
- {
- // Should we also handle #rrggbb here?
- if (s.length() == 9 && s.startsWith(QLatin1Char('#'))) {
- uchar a = fromHex(s, 1);
- uchar r = fromHex(s, 3);
- uchar g = fromHex(s, 5);
- uchar b = fromHex(s, 7);
- return QColor(r, g, b, a);
- }
-
- return QColor(s);
- }
-
QVariant colorFromString(const QString &s, bool *ok)
{
- QColor c(QColorFromString(s));
+ QColor c(s);
if (c.isValid()) {
if (ok) *ok = true;
return QVariant(c);
@@ -89,7 +75,7 @@ public:
unsigned rgbaFromString(const QString &s, bool *ok)
{
- QColor c(QColorFromString(s));
+ QColor c(s);
if (c.isValid()) {
if (ok) *ok = true;
return c.rgba();
@@ -155,34 +141,6 @@ public:
return QVariant::fromValue(QColor::fromRgbF(r, g, b, a + inv_a * baseColor.alphaF()));
}
-
-private:
- static uchar fromHex(const uchar c, const uchar c2)
- {
- uchar rv = 0;
- if (c >= '0' && c <= '9')
- rv += (c - '0') * 16;
- else if (c >= 'A' && c <= 'F')
- rv += (c - 'A' + 10) * 16;
- else if (c >= 'a' && c <= 'f')
- rv += (c - 'a' + 10) * 16;
-
- if (c2 >= '0' && c2 <= '9')
- rv += (c2 - '0');
- else if (c2 >= 'A' && c2 <= 'F')
- rv += (c2 - 'A' + 10);
- else if (c2 >= 'a' && c2 <= 'f')
- rv += (c2 - 'a' + 10);
-
- return rv;
- }
-
- static inline uchar fromHex(const QString &s, int idx)
- {
- uchar c = s.at(idx).toLatin1();
- uchar c2 = s.at(idx + 1).toLatin1();
- return fromHex(c, c2);
- }
};
@@ -639,7 +597,7 @@ public:
switch (type) {
case QMetaType::QColor:
- return createFromStringTyped<QColor>(data, dataSize, QQuickColorProvider::QColorFromString(s));
+ return createFromStringTyped<QColor>(data, dataSize, QColor(s));
case QMetaType::QVector2D:
return createFromStringTyped<QVector2D>(data, dataSize, vector2DFromString(s, &ok));
case QMetaType::QVector3D:
@@ -677,7 +635,7 @@ public:
bool variantFromString(const QString &s, QVariant *v)
{
- QColor c(QQuickColorProvider::QColorFromString(s));
+ QColor c(s);
if (c.isValid()) {
*v = QVariant::fromValue(c);
return true;
@@ -725,7 +683,7 @@ public:
switch (type) {
case QMetaType::QColor:
{
- QColor c(QQuickColorProvider::QColorFromString(s));
+ QColor c(s);
*v = QVariant::fromValue(c);
return true;
}
diff --git a/src/quick/util/qquickpath.cpp b/src/quick/util/qquickpath.cpp
index 25e40d8eb6..7e8b71da63 100644
--- a/src/quick/util/qquickpath.cpp
+++ b/src/quick/util/qquickpath.cpp
@@ -320,8 +320,6 @@ void QQuickPath::endpoint(QList<AttributePoint> &attributePoints, const QString
}
}
-static QString percentString(QLatin1String("_qfx_percent"));
-
void QQuickPath::processPath()
{
Q_D(QQuickPath);
@@ -358,6 +356,8 @@ QPainterPath QQuickPath::createPath(const QPointF &startPoint, const QPointF &en
qreal startY = d->startY.isValid() ? d->startY.value : startPoint.y();
path.moveTo(startX, startY);
+ const QString percentString = QStringLiteral("_qfx_percent");
+
bool usesPercent = false;
int index = 0;
foreach (QQuickPathElement *pathElement, d->_pathElements) {
diff --git a/src/quick/util/qquickprofiler.cpp b/src/quick/util/qquickprofiler.cpp
index 0bd22d1d25..4418f6dd9c 100644
--- a/src/quick/util/qquickprofiler.cpp
+++ b/src/quick/util/qquickprofiler.cpp
@@ -72,7 +72,7 @@ void QQuickProfilerData::toByteArrays(QList<QByteArray> &messages) const
switch (decodedMessageType) {
case QQuickProfiler::Event:
if (decodedDetailType == (int)QQuickProfiler::AnimationFrame)
- ds << framerate << count;
+ ds << framerate << count << threadId;
break;
case QQuickProfiler::PixmapCacheEvent:
ds << detailUrl.toString();
@@ -137,7 +137,14 @@ void QQuickProfiler::initialize()
void animationTimerCallback(qint64 delta)
{
- Q_QUICK_PROFILE(animationFrame(delta));
+ Q_QUICK_PROFILE(animationFrame(delta,
+ QThread::currentThread() == QCoreApplication::instance()->thread() ?
+ QQuickProfiler::GuiThread : QQuickProfiler::RenderThread));
+}
+
+void QQuickProfiler::registerAnimationCallback()
+{
+ QUnifiedTimer::instance()->registerProfilerCallback(&animationTimerCallback);
}
class CallbackRegistrationHelper : public QObject {
@@ -145,7 +152,7 @@ class CallbackRegistrationHelper : public QObject {
public slots:
void registerAnimationTimerCallback()
{
- QUnifiedTimer::instance()->registerProfilerCallback(&animationTimerCallback);
+ QQuickProfiler::registerAnimationCallback();
delete this;
}
};
diff --git a/src/quick/util/qquickprofiler_p.h b/src/quick/util/qquickprofiler_p.h
index 721560b9e5..03cef951b5 100644
--- a/src/quick/util/qquickprofiler_p.h
+++ b/src/quick/util/qquickprofiler_p.h
@@ -95,9 +95,9 @@ struct Q_AUTOTEST_EXPORT QQuickProfilerData
framerate(framerate), count(count) {}
QQuickProfilerData(qint64 time, int messageType, int detailType, int framerate = 0,
- int count = 0) :
+ int count = 0, int threadId = 0) :
time(time), messageType(messageType), detailType(detailType), framerate(framerate),
- count(count) {}
+ count(count), threadId(threadId) {}
// Special ctor for scenegraph frames. Note that it's missing the QString/QUrl params.
// This is slightly ugly, but makes it easier to disambiguate between int and qint64 params.
@@ -133,7 +133,10 @@ struct Q_AUTOTEST_EXPORT QQuickProfilerData
int count; //used by animation events and for pixmaps
};
- qint64 subtime_5;
+ union {
+ qint64 subtime_5;
+ int threadId;
+ };
void toByteArrays(QList<QByteArray> &messages) const;
};
@@ -144,6 +147,11 @@ class Q_QUICK_PRIVATE_EXPORT QQuickProfiler : public QQmlAbstractProfilerAdapter
Q_OBJECT
public:
+ enum AnimationThread {
+ GuiThread,
+ RenderThread
+ };
+
template<EventType DetailType>
static void addEvent()
{
@@ -151,13 +159,14 @@ public:
1 << DetailType));
}
- static void animationFrame(qint64 delta)
+ static void animationFrame(qint64 delta, AnimationThread threadId)
{
int animCount = QUnifiedTimer::instance()->runningAnimationCount();
if (animCount > 0 && delta > 0) {
s_instance->processMessage(QQuickProfilerData(s_instance->timestamp(), 1 << Event,
- 1 << AnimationFrame, 1000 / (int)delta /* trim fps to integer */, animCount));
+ 1 << AnimationFrame, 1000 / (int)delta /* trim fps to integer */, animCount,
+ threadId));
}
}
@@ -191,6 +200,8 @@ public:
1 << PixmapCacheEvent, 1 << CountType, url, 0, 0, 0, count));
}
+ static void registerAnimationCallback();
+
qint64 timestamp() { return m_timer.nsecsElapsed(); }
qint64 sendMessages(qint64 until, QList<QByteArray> &messages);
diff --git a/src/quick/util/qquickpropertychanges.cpp b/src/quick/util/qquickpropertychanges.cpp
index b2f490e3c8..1786317356 100644
--- a/src/quick/util/qquickpropertychanges.cpp
+++ b/src/quick/util/qquickpropertychanges.cpp
@@ -46,9 +46,9 @@
#include <qqmlinfo.h>
#include <private/qqmlcustomparser_p.h>
-#include <private/qqmlscript_p.h>
#include <qqmlexpression.h>
#include <private/qqmlbinding_p.h>
+#include <private/qqmlcompiler_p.h>
#include <qqmlcontext.h>
#include <private/qqmlproperty_p.h>
#include <private/qqmlcontext_p.h>
@@ -205,6 +205,7 @@ public:
QPointer<QObject> object;
QByteArray data;
+ QQmlRefPointer<QQmlCompiledData> cdata;
bool decoded : 1;
bool restore : 1;
@@ -259,9 +260,8 @@ void QQuickPropertyChangesParser::compileList(QList<QPair<QString, const QV4::Co
list << qMakePair(propName, binding);
}
-QByteArray QQuickPropertyChangesParser::compile(const QV4::CompiledData::QmlUnit *qmlUnit, int objectIndex, const QList<const QV4::CompiledData::Binding *> &props)
+QByteArray QQuickPropertyChangesParser::compile(const QV4::CompiledData::QmlUnit *qmlUnit, const QList<const QV4::CompiledData::Binding *> &props)
{
- Q_UNUSED(objectIndex)
QList<QPair<QString, const QV4::CompiledData::Binding *> > data;
for (int ii = 0; ii < props.count(); ++ii)
compileList(data, QString(), qmlUnit, props.at(ii));
@@ -272,12 +272,13 @@ QByteArray QQuickPropertyChangesParser::compile(const QV4::CompiledData::QmlUnit
ds << data.count();
for (int ii = 0; ii < data.count(); ++ii) {
const QV4::CompiledData::Binding *binding = data.at(ii).second;
+ ds << data.at(ii).first << int(binding->type);
QVariant var;
- bool isScript = binding->type == QV4::CompiledData::Binding::Type_Script;
- QQmlBinding::Identifier id = QQmlBinding::Invalid;
switch (binding->type) {
case QV4::CompiledData::Binding::Type_Script:
- // ### pre-compile binding
+ ds << bindingIdentifier(binding);
+ // Fall through as we also need the expression string.
+ // Signal handlers still need to be constructed by string ;(
case QV4::CompiledData::Binding::Type_String:
var = binding->valueAsString(&qmlUnit->header);
break;
@@ -289,13 +290,12 @@ QByteArray QQuickPropertyChangesParser::compile(const QV4::CompiledData::QmlUnit
break;
case QV4::CompiledData::Binding::Type_Translation:
case QV4::CompiledData::Binding::Type_TranslationById:
- Q_UNREACHABLE();
+ ds << binding->value.translationData.commentIndex << binding->value.translationData.number;
+ var = binding->stringIndex;
default:
break;
}
- ds << data.at(ii).first << isScript << var;
- if (isScript)
- ds << id;
+ ds << var;
}
return rv;
@@ -313,36 +313,30 @@ void QQuickPropertyChangesPrivate::decode()
ds >> count;
for (int ii = 0; ii < count; ++ii) {
QString name;
- bool isScript;
+ int type;
QVariant data;
QQmlBinding::Identifier id = QQmlBinding::Invalid;
+ QV4::CompiledData::TranslationData tsd;
ds >> name;
- ds >> isScript;
- ds >> data;
- if (isScript)
+ ds >> type;
+
+ if (type == QV4::CompiledData::Binding::Type_Script) {
ds >> id;
+ } else if (type == QV4::CompiledData::Binding::Type_Translation
+ || type == QV4::CompiledData::Binding::Type_TranslationById) {
+ ds >> tsd.commentIndex >> tsd.number;
+ }
+
+ ds >> data;
QQmlProperty prop = property(name); //### better way to check for signal property?
if (prop.type() & QQmlProperty::SignalProperty) {
- QString expression = data.toString();
- QUrl url = QUrl();
- int line = -1;
- int column = -1;
-
- QQmlData *ddata = QQmlData::get(q);
- if (ddata && ddata->outerContext && !ddata->outerContext->url.isEmpty()) {
- url = ddata->outerContext->url;
- line = ddata->lineNumber;
- column = ddata->columnNumber;
- }
-
QQuickReplaceSignalHandler *handler = new QQuickReplaceSignalHandler;
handler->property = prop;
handler->expression.take(new QQmlBoundSignalExpression(object, QQmlPropertyPrivate::get(prop)->signalIndex(),
- QQmlContextData::get(qmlContext(q)), object, expression,
- url.toString(), line, column));
+ QQmlContextData::get(qmlContext(q)), object, cdata->functionForBindingId(id)));
signalReplacements << handler;
- } else if (isScript) { // binding
+ } else if (type == QV4::CompiledData::Binding::Type_Script) { // binding
QString expression = data.toString();
QUrl url = QUrl();
int line = -1;
@@ -357,6 +351,14 @@ void QQuickPropertyChangesPrivate::decode()
expressions << ExpressionChange(name, id, expression, url, line, column);
} else {
+ if (type == QV4::CompiledData::Binding::Type_Translation
+ || type == QV4::CompiledData::Binding::Type_TranslationById) {
+ QV4::CompiledData::Binding tmpBinding;
+ tmpBinding.type = type;
+ tmpBinding.stringIndex = data.toInt();
+ tmpBinding.value.translationData = tsd;
+ data = tmpBinding.valueAsString(&cdata->qmlUnit->header);
+ }
properties << qMakePair(name, data);
}
}
@@ -364,12 +366,12 @@ void QQuickPropertyChangesPrivate::decode()
data.clear();
}
-void QQuickPropertyChangesParser::setCustomData(QObject *object,
- const QByteArray &data)
+void QQuickPropertyChangesParser::setCustomData(QObject *object, const QByteArray &data, QQmlCompiledData *cdata)
{
QQuickPropertyChangesPrivate *p =
static_cast<QQuickPropertyChangesPrivate *>(QObjectPrivate::get(object));
p->data = data;
+ p->cdata = cdata;
p->decoded = false;
}
diff --git a/src/quick/util/qquickpropertychanges_p.h b/src/quick/util/qquickpropertychanges_p.h
index 6d238f5ca5..3eed151d11 100644
--- a/src/quick/util/qquickpropertychanges_p.h
+++ b/src/quick/util/qquickpropertychanges_p.h
@@ -94,8 +94,8 @@ public:
void compileList(QList<QPair<QString, const QV4::CompiledData::Binding *> > &list, const QString &pre, const QV4::CompiledData::QmlUnit *qmlUnit, const QV4::CompiledData::Binding *binding);
- virtual QByteArray compile(const QV4::CompiledData::QmlUnit *qmlUnit, int objectIndex, const QList<const QV4::CompiledData::Binding *> &props);
- virtual void setCustomData(QObject *, const QByteArray &);
+ virtual QByteArray compile(const QV4::CompiledData::QmlUnit *qmlUnit, const QList<const QV4::CompiledData::Binding *> &props);
+ virtual void setCustomData(QObject *, const QByteArray &, QQmlCompiledData *);
};
diff --git a/src/quick/util/qquicksmoothedanimation.cpp b/src/quick/util/qquicksmoothedanimation.cpp
index a0e6c36830..a23f7a5df6 100644
--- a/src/quick/util/qquicksmoothedanimation.cpp
+++ b/src/quick/util/qquicksmoothedanimation.cpp
@@ -313,6 +313,13 @@ void QSmoothedAnimation::init()
}
}
+void QSmoothedAnimation::debugAnimation(QDebug d) const
+{
+ d << "SmoothedAnimationJob(" << hex << (void *) this << dec << ")" << "duration:" << userDuration
+ << "velocity:" << velocity << "target:" << target.object() << "property:" << target.name()
+ << "to:" << to << "current velocity:" << trackVelocity;
+}
+
/*!
\qmltype SmoothedAnimation
\instantiates QQuickSmoothedAnimation
diff --git a/src/quick/util/qquicksmoothedanimation_p_p.h b/src/quick/util/qquicksmoothedanimation_p_p.h
index 7835d0328b..3c85f09b04 100644
--- a/src/quick/util/qquicksmoothedanimation_p_p.h
+++ b/src/quick/util/qquicksmoothedanimation_p_p.h
@@ -105,6 +105,7 @@ public:
protected:
virtual void updateCurrentTime(int);
virtual void updateState(QAbstractAnimationJob::State, QAbstractAnimationJob::State);
+ void debugAnimation(QDebug d) const;
private:
qreal easeFollow(qreal);
diff --git a/src/quick/util/qquickspringanimation.cpp b/src/quick/util/qquickspringanimation.cpp
index f237c09bf9..4b1abcef8c 100644
--- a/src/quick/util/qquickspringanimation.cpp
+++ b/src/quick/util/qquickspringanimation.cpp
@@ -101,6 +101,7 @@ public:
protected:
virtual void updateCurrentTime(int time);
virtual void updateState(QAbstractAnimationJob::State, QAbstractAnimationJob::State);
+ void debugAnimation(QDebug d) const;
private:
QQuickSpringAnimationPrivate *animationTemplate;
@@ -320,6 +321,15 @@ void QSpringAnimation::updateState(QAbstractAnimationJob::State newState, QAbstr
init();
}
+void QSpringAnimation::debugAnimation(QDebug d) const
+{
+ d << "SpringAnimationJob(" << hex << (void *) this << dec << ")" << "velocity:" << maxVelocity
+ << "spring:" << spring << "damping:" << damping << "epsilon:" << epsilon << "modulus:" << modulus
+ << "mass:" << mass << "target:" << target.object() << "property:" << target.name()
+ << "to:" << to << "current velocity:" << velocity;
+}
+
+
void QQuickSpringAnimationPrivate::updateMode()
{
if (spring == 0. && maxVelocity == 0.)
diff --git a/src/quick/util/qquickstyledtext.cpp b/src/quick/util/qquickstyledtext.cpp
index f2b2d2af06..80586bd45b 100644
--- a/src/quick/util/qquickstyledtext.cpp
+++ b/src/quick/util/qquickstyledtext.cpp
@@ -89,7 +89,7 @@ public:
QQmlContext *context,
bool preloadImages,
bool *fontSizeModified)
- : text(t), layout(l), imgTags(&imgTags), baseFont(layout.font()), baseUrl(baseUrl), hasNewLine(false), nbImages(0), updateImagePositions(false)
+ : text(t), layout(l), imgTags(&imgTags), baseFont(layout.font()), baseUrl(baseUrl), hasNewLine(true), nbImages(0), updateImagePositions(false)
, preFormat(false), prependSpace(false), hasSpace(true), preloadImages(preloadImages), fontSizeModified(fontSizeModified), context(context)
{
}
diff --git a/src/quick/util/qquicktimeline.cpp b/src/quick/util/qquicktimeline.cpp
index 94e1f30215..f9928c4d00 100644
--- a/src/quick/util/qquicktimeline.cpp
+++ b/src/quick/util/qquicktimeline.cpp
@@ -723,6 +723,11 @@ void QQuickTimeLine::updateCurrentTime(int v)
}
}
+void QQuickTimeLine::debugAnimation(QDebug d) const
+{
+ d << "QuickTimeLine(" << hex << (void *) this << dec << ")";
+}
+
bool operator<(const QPair<int, Update> &lhs,
const QPair<int, Update> &rhs)
{
diff --git a/src/quick/util/qquicktimeline_p_p.h b/src/quick/util/qquicktimeline_p_p.h
index a99a515f0a..0172ecbfcf 100644
--- a/src/quick/util/qquicktimeline_p_p.h
+++ b/src/quick/util/qquicktimeline_p_p.h
@@ -109,6 +109,7 @@ Q_SIGNALS:
protected:
virtual void updateCurrentTime(int);
+ void debugAnimation(QDebug d) const;
private:
void remove(QQuickTimeLineObject *);