Merge remote-tracking branch 'origin/5.8' into dev
Conflicts: .qmake.conf Change-Id: I9d87ed86e95b5901a86cc3aa65d7ac39b0b708c2
This commit is contained in:
commit
60300fda46
|
@ -75,9 +75,21 @@ This example builds on:
|
|||
|
||||
Shows how to use \l {QQmlEngine::}{qmlRegisterExtendedType()} to provide an \l {Registering
|
||||
Extension Objects}{extension object} to a \l QLineEdit without modifying or
|
||||
subclassing. The QML engine instantiates a \l QLineEdit and sets a property that
|
||||
only exists on the extension type. The extension type performs calls on the \l
|
||||
QLineEdit that otherwise will not be accessible to the QML engine.
|
||||
subclassing.
|
||||
|
||||
\snippet referenceexamples/extended/main.cpp 0
|
||||
|
||||
The QML engine instantiates a \l QLineEdit
|
||||
|
||||
\snippet referenceexamples/extended/main.cpp 1
|
||||
|
||||
and sets a property that oly exists on the extension type.
|
||||
|
||||
\snippet referenceexamples/extended/example.qml 0
|
||||
|
||||
The QML engine instantiates a \l QLineEdit and sets a property that
|
||||
only exists on the extension type. The extension type performs calls on the
|
||||
\l QLineEdit that otherwise will not be accessible to the QML engine.
|
||||
|
||||
*/
|
||||
|
||||
|
@ -293,12 +305,20 @@ This example builds on:
|
|||
|
||||
This example builds on:
|
||||
\list
|
||||
\li \l {Extending QML - Default Property Example}
|
||||
\li \l {Extending QML - Inheritance and Coercion Example}
|
||||
\li \l {Extending QML - Object and List Property Types Example}
|
||||
\li \l {Extending QML - Adding Types Example}
|
||||
\endlist
|
||||
|
||||
The Methods Example has an additional method in the \c BirthdayParty class: \c invite().
|
||||
\c invite() is declared with \l Q_INVOKABLE so that it can be
|
||||
called from QML.
|
||||
|
||||
\snippet referenceexamples/methods/birthdayparty.h 0
|
||||
|
||||
In \c example.qml, the \c invite() method is called in the \l [QML]{QtQml::Component::completed()}{Component.onCompleted} signal handler:
|
||||
|
||||
\snippet referenceexamples/methods/example.qml 0
|
||||
*/
|
||||
|
||||
/*!
|
||||
|
|
|
@ -48,11 +48,15 @@ int main(int argc, char ** argv)
|
|||
{
|
||||
QApplication app(argc, argv);
|
||||
|
||||
// ![0]
|
||||
qmlRegisterExtendedType<QLineEdit, LineEditExtension>("People", 1,0, "QLineEdit");
|
||||
// ![0]
|
||||
|
||||
// ![1]
|
||||
QQmlEngine engine;
|
||||
QQmlComponent component(&engine, QUrl("qrc:example.qml"));
|
||||
QLineEdit *edit = qobject_cast<QLineEdit *>(component.create());
|
||||
// ![1]
|
||||
|
||||
if (edit) {
|
||||
edit->show();
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
**
|
||||
****************************************************************************/
|
||||
|
||||
// ![0]
|
||||
import QtQuick 2.0
|
||||
import People 1.0
|
||||
|
||||
|
@ -52,7 +53,6 @@ BirthdayParty {
|
|||
Person { name: "Anne Brown" }
|
||||
]
|
||||
|
||||
// ![0]
|
||||
Component.onCompleted: invite("William Green")
|
||||
// ![0]
|
||||
}
|
||||
// ![0]
|
||||
|
|
|
@ -102,7 +102,7 @@ QSGNode *Graph::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
|
|||
n->background = new NoisyNode(window());
|
||||
n->grid = new GridNode();
|
||||
n->line = new LineNode(10, 0.5, QColor("steelblue"));
|
||||
n->shadow = new LineNode(20, 0.2, QColor::fromRgbF(0.2, 0.2, 0.2, 0.4));
|
||||
n->shadow = new LineNode(20, 0.2f, QColor::fromRgbF(0.2, 0.2, 0.2, 0.4));
|
||||
|
||||
n->appendChildNode(n->background);
|
||||
n->appendChildNode(n->grid);
|
||||
|
|
|
@ -762,9 +762,11 @@ bool QQuickLayout::shouldIgnoreItem(QQuickItem *child, QQuickLayoutAttached *&in
|
|||
void QQuickLayout::itemChange(ItemChange change, const ItemChangeData &value)
|
||||
{
|
||||
if (change == ItemChildAddedChange) {
|
||||
Q_D(QQuickLayout);
|
||||
QQuickItem *item = value.item;
|
||||
qmlobject_connect(item, QQuickItem, SIGNAL(baselineOffsetChanged(qreal)), this, QQuickLayout, SLOT(invalidateSenderItem()));
|
||||
QQuickItemPrivate::get(item)->addItemChangeListener(this, QQuickItemPrivate::SiblingOrder | QQuickItemPrivate::ImplicitWidth | QQuickItemPrivate::ImplicitHeight | QQuickItemPrivate::Destroyed | QQuickItemPrivate::Visibility);
|
||||
d->m_hasItemChangeListeners = true;
|
||||
if (isReady())
|
||||
updateLayoutItems();
|
||||
} else if (change == ItemChildRemovedChange) {
|
||||
|
@ -802,6 +804,30 @@ bool QQuickLayout::isReady() const
|
|||
return d_func()->m_isReady;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief QQuickLayout::deactivateRecur
|
||||
* \internal
|
||||
*
|
||||
* Call this from the dtor of the top-level layout.
|
||||
* Otherwise, it will trigger lots of unneeded item change listeners (itemVisibleChanged()) for all its descendants
|
||||
* that will have its impact thrown away.
|
||||
*/
|
||||
void QQuickLayout::deactivateRecur()
|
||||
{
|
||||
if (d_func()->m_hasItemChangeListeners) {
|
||||
for (int i = 0; i < itemCount(); ++i) {
|
||||
QQuickItem *item = itemAt(i);
|
||||
// When deleting a layout with children, there is no reason for the children to inform the layout that their
|
||||
// e.g. visibility got changed. The layout already knows that all its children will eventually become invisible, so
|
||||
// we therefore remove its change listener.
|
||||
QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::SiblingOrder | QQuickItemPrivate::ImplicitWidth | QQuickItemPrivate::ImplicitHeight | QQuickItemPrivate::Destroyed | QQuickItemPrivate::Visibility);
|
||||
if (QQuickLayout *layout = qobject_cast<QQuickLayout*>(item))
|
||||
layout->deactivateRecur();
|
||||
}
|
||||
d_func()->m_hasItemChangeListeners = false;
|
||||
}
|
||||
}
|
||||
|
||||
void QQuickLayout::itemSiblingOrderChanged(QQuickItem *item)
|
||||
{
|
||||
Q_UNUSED(item);
|
||||
|
|
|
@ -95,6 +95,7 @@ public:
|
|||
void itemChange(ItemChange change, const ItemChangeData &value) Q_DECL_OVERRIDE;
|
||||
void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) Q_DECL_OVERRIDE;
|
||||
bool isReady() const;
|
||||
void deactivateRecur();
|
||||
|
||||
|
||||
/* QQuickItemChangeListener */
|
||||
|
@ -134,6 +135,7 @@ public:
|
|||
protected:
|
||||
unsigned m_isReady : 1;
|
||||
unsigned m_disableRearrange : 1;
|
||||
unsigned m_hasItemChangeListeners : 1; // if false, we don't need to remove its item change listeners...
|
||||
mutable QSet<QQuickItem *> m_ignoredItems;
|
||||
};
|
||||
|
||||
|
|
|
@ -305,11 +305,7 @@ QQuickGridLayoutBase::~QQuickGridLayoutBase()
|
|||
|
||||
// Remove item listeners so we do not act on signalling unnecessarily
|
||||
// (there is no point, as the layout will be torn down anyway).
|
||||
for (int i = 0; i < itemCount(); ++i) {
|
||||
QQuickItem *item = itemAt(i);
|
||||
QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::SiblingOrder | QQuickItemPrivate::ImplicitWidth | QQuickItemPrivate::ImplicitHeight | QQuickItemPrivate::Destroyed | QQuickItemPrivate::Visibility);
|
||||
}
|
||||
|
||||
deactivateRecur();
|
||||
delete d->styleInfo;
|
||||
}
|
||||
|
||||
|
|
|
@ -407,6 +407,11 @@ bool CompilationUnit::loadFromDisk(const QUrl &url, EvalISelFactory *iselFactory
|
|||
const Unit * const oldDataPtr = (data && !(data->flags & QV4::CompiledData::Unit::StaticData)) ? data : nullptr;
|
||||
QScopedValueRollback<const Unit *> dataPtrChange(data, mappedUnit);
|
||||
|
||||
if (sourcePath != QQmlFile::urlToLocalFileOrQrc(stringAt(data->sourceFileIndex))) {
|
||||
*errorString = QStringLiteral("QML source file has moved to a different location.");
|
||||
return false;
|
||||
}
|
||||
|
||||
{
|
||||
const QString foundArchitecture = stringAt(data->architectureIndex);
|
||||
const QString expectedArchitecture = QSysInfo::buildAbi();
|
||||
|
|
|
@ -32,4 +32,40 @@
|
|||
|
||||
The list of examples demonstrating how to extend C++ to QML or the other way
|
||||
around.
|
||||
|
||||
\noautolist
|
||||
|
||||
\table
|
||||
\row
|
||||
\li \l {Extending QML - Adding Types Example}
|
||||
\li Exporting C++ Classes
|
||||
\row
|
||||
\li \l {Extending QML - Object and List Property Types Example}
|
||||
\li Exporting C++ Properties
|
||||
\row
|
||||
\li \l {Extending QML - Extension Objects Example}
|
||||
\li Extension Objects
|
||||
\row
|
||||
\li \l {Extending QML - Inheritance and Coercion Example}
|
||||
\li C++ Inheritance and Coercion
|
||||
\row
|
||||
\li \l {Extending QML - Methods Example}
|
||||
\li Methods Support
|
||||
\row
|
||||
\li \l {Extending QML - Attached Properties Example}
|
||||
\li Attached Properties
|
||||
\row
|
||||
\li \l {Extending QML - Signal Support Example}
|
||||
\li Signal Support
|
||||
\row
|
||||
\li \l {Extending QML - Property Value Source Example}
|
||||
\li Property Value Source
|
||||
\row
|
||||
\li \l {Extending QML - Default Property Example}
|
||||
\li Default Property
|
||||
\row
|
||||
\li \l {Extending QML - Grouped Properties Example}
|
||||
\li Grouped Properties
|
||||
\endtable
|
||||
|
||||
*/
|
||||
|
|
|
@ -73,7 +73,8 @@
|
|||
For the object-based types (including Date and RegExp), use the
|
||||
newT() functions in QJSEngine (e.g. QJSEngine::newObject())
|
||||
to create a QJSValue of the desired type. For the primitive types,
|
||||
use one of the QJSValue constructor overloads.
|
||||
use one of the QJSValue constructor overloads. For other types, e.g.
|
||||
registered gadget types such as QPoint, you can use QJSEngine::toScriptValue.
|
||||
|
||||
The methods named isT() (e.g. isBool(), isUndefined()) can be
|
||||
used to test if a value is of a certain type. The methods named
|
||||
|
|
|
@ -158,8 +158,6 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
|
|||
}
|
||||
Q_ASSERT(maxCallDepth > 0);
|
||||
|
||||
MemoryManager::GCBlocker gcBlocker(memoryManager);
|
||||
|
||||
if (!factory) {
|
||||
#if QT_CONFIG(qml_interpreter)
|
||||
bool jitDisabled = true;
|
||||
|
|
|
@ -88,8 +88,6 @@ void Script::parse()
|
|||
ExecutionEngine *v4 = scope->engine();
|
||||
Scope valueScope(v4);
|
||||
|
||||
MemoryManager::GCBlocker gcBlocker(v4->memoryManager);
|
||||
|
||||
IR::Module module(v4->debugger() != 0);
|
||||
|
||||
QQmlJS::Engine ee, *engine = ⅇ
|
||||
|
|
|
@ -565,16 +565,6 @@ void MemoryManager::sweep(bool lastSweep)
|
|||
}
|
||||
}
|
||||
|
||||
bool MemoryManager::isGCBlocked() const
|
||||
{
|
||||
return m_d->gcBlocked;
|
||||
}
|
||||
|
||||
void MemoryManager::setGCBlocked(bool blockGC)
|
||||
{
|
||||
m_d->gcBlocked = blockGC;
|
||||
}
|
||||
|
||||
void MemoryManager::runGC()
|
||||
{
|
||||
if (m_d->gcBlocked) {
|
||||
|
|
|
@ -76,26 +76,6 @@ class Q_QML_EXPORT MemoryManager
|
|||
public:
|
||||
struct Data;
|
||||
|
||||
class GCBlocker
|
||||
{
|
||||
public:
|
||||
GCBlocker(MemoryManager *mm)
|
||||
: mm(mm)
|
||||
, wasBlocked(mm->isGCBlocked())
|
||||
{
|
||||
mm->setGCBlocked(true);
|
||||
}
|
||||
|
||||
~GCBlocker()
|
||||
{
|
||||
mm->setGCBlocked(wasBlocked);
|
||||
}
|
||||
|
||||
private:
|
||||
MemoryManager *mm;
|
||||
bool wasBlocked;
|
||||
};
|
||||
|
||||
public:
|
||||
MemoryManager(ExecutionEngine *engine);
|
||||
~MemoryManager();
|
||||
|
@ -309,8 +289,6 @@ public:
|
|||
return t->d();
|
||||
}
|
||||
|
||||
bool isGCBlocked() const;
|
||||
void setGCBlocked(bool blockGC);
|
||||
void runGC();
|
||||
|
||||
void dumpStats() const;
|
||||
|
|
|
@ -199,7 +199,10 @@ void QQmlBoundSignalExpression::evaluate(void **a)
|
|||
// for several cases (such as QVariant type and QObject-derived types)
|
||||
//args[ii] = engine->metaTypeToJS(type, a[ii + 1]);
|
||||
if (type == qMetaTypeId<QJSValue>()) {
|
||||
callData->args[ii] = *QJSValuePrivate::getValue(reinterpret_cast<QJSValue *>(a[ii + 1]));
|
||||
if (QV4::Value *v4Value = QJSValuePrivate::getValue(reinterpret_cast<QJSValue *>(a[ii + 1])))
|
||||
callData->args[ii] = *v4Value;
|
||||
else
|
||||
callData->args[ii] = QV4::Encode::undefined();
|
||||
} else if (type == QMetaType::QVariant) {
|
||||
callData->args[ii] = scope.engine->fromVariant(*((QVariant *)a[ii + 1]));
|
||||
} else if (type == QMetaType::Int) {
|
||||
|
|
|
@ -47,8 +47,6 @@
|
|||
#include "qqml.h"
|
||||
#include "qqmlengine.h"
|
||||
#include "qqmlbinding_p.h"
|
||||
#include <private/qqmldebugconnector_p.h>
|
||||
#include <private/qqmldebugserviceinterfaces_p.h>
|
||||
#include "qqmlincubator.h"
|
||||
#include "qqmlincubator_p.h"
|
||||
#include <private/qqmljavascriptexpression_p.h>
|
||||
|
@ -876,15 +874,6 @@ QQmlComponentPrivate::beginCreate(QQmlContextData *context)
|
|||
depthIncreased = false;
|
||||
}
|
||||
|
||||
if (rv) {
|
||||
if (QQmlEngineDebugService *service =
|
||||
QQmlDebugConnector::service<QQmlEngineDebugService>()) {
|
||||
if (!context->isInternal)
|
||||
context->asQQmlContextPrivate()->instances.append(rv);
|
||||
service->objectCreated(engine, rv);
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
|
@ -117,4 +117,14 @@ void QQmlExtensionPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
|
|||
Q_UNUSED(uri);
|
||||
}
|
||||
|
||||
/*!
|
||||
\class QQmlExtensionInterface
|
||||
\internal
|
||||
\inmodule QtQml
|
||||
|
||||
\class QQmlTypesExtensionInterface
|
||||
\internal
|
||||
\inmodule QtQml
|
||||
*/
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
|
@ -335,7 +335,7 @@ int QQmlListReference::count() const
|
|||
\since 5.0
|
||||
\inmodule QtQml
|
||||
\brief The QQmlListProperty class allows applications to expose list-like
|
||||
properties to QML.
|
||||
properties of QObject-derived classes to QML.
|
||||
|
||||
QML has many list properties, where more than one object value can be assigned.
|
||||
The use of a list property from QML looks like this:
|
||||
|
@ -369,7 +369,8 @@ QML list properties are type-safe - in this case \c {Fruit} is a QObject type th
|
|||
|
||||
The \l {Qt Quick 1} version of this class is named QDeclarativeListProperty.
|
||||
|
||||
\note QQmlListProperty can only be used for lists of QObject-derived object pointers.
|
||||
\sa {Extending QML - Object and List Property Types Example}
|
||||
|
||||
*/
|
||||
|
||||
/*!
|
||||
|
|
|
@ -53,6 +53,8 @@
|
|||
#include <private/qqmlscriptstring_p.h>
|
||||
#include <private/qqmlpropertyvalueinterceptor_p.h>
|
||||
#include <private/qqmlvaluetypeproxybinding_p.h>
|
||||
#include <private/qqmldebugconnector_p.h>
|
||||
#include <private/qqmldebugserviceinterfaces_p.h>
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
|
@ -216,6 +218,17 @@ QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlI
|
|||
|
||||
phase = ObjectsCreated;
|
||||
|
||||
if (instance) {
|
||||
if (QQmlEngineDebugService *service
|
||||
= QQmlDebugConnector::service<QQmlEngineDebugService>()) {
|
||||
if (!parentContext->isInternal)
|
||||
parentContext->asQQmlContextPrivate()->instances.append(instance);
|
||||
service->objectCreated(engine, instance);
|
||||
} else if (!parentContext->isInternal && QQmlDebugConnector::service<QV4DebugService>()) {
|
||||
parentContext->asQQmlContextPrivate()->instances.append(instance);
|
||||
}
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
|
|
@ -766,7 +766,6 @@ QSGNode *QQuickCanvasItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData
|
|||
if (!texture) {
|
||||
delete node;
|
||||
d->node = 0;
|
||||
delete d->nodeTexture;
|
||||
d->nodeTexture = 0;
|
||||
if (d->textureProvider) {
|
||||
d->textureProvider->tex = 0;
|
||||
|
|
|
@ -137,6 +137,7 @@ Item {
|
|||
\li Qt.AltModifier - An Alt key on the keyboard is pressed.
|
||||
\li Qt.MetaModifier - A Meta key on the keyboard is pressed.
|
||||
\li Qt.KeypadModifier - A keypad button is pressed.
|
||||
\li Qt.GroupSwitchModifier - X11 only. A Mode_switch key on the keyboard is pressed.
|
||||
\endlist
|
||||
|
||||
For example, to react to a Shift key + Enter key combination:
|
||||
|
|
|
@ -341,7 +341,7 @@ bool QQuickMouseAreaPrivate::propagateHelper(QQuickMouseEvent *ev, QQuickItem *i
|
|||
position of the release of the click, and whether the click was held.
|
||||
|
||||
When handling this signal, changing the \l {MouseEvent::}{accepted} property of the \a mouse
|
||||
parameter has no effect.
|
||||
parameter has no effect, unless the \l propagateComposedEvents property is \c true.
|
||||
|
||||
The corresponding handler is \c onClicked.
|
||||
*/
|
||||
|
@ -385,7 +385,7 @@ bool QQuickMouseAreaPrivate::propagateHelper(QQuickMouseEvent *ev, QQuickItem *i
|
|||
position of the press, and which button is pressed.
|
||||
|
||||
When handling this signal, changing the \l {MouseEvent::}{accepted} property of the \a mouse
|
||||
parameter has no effect.
|
||||
parameter has no effect, unless the \l propagateComposedEvents property is \c true.
|
||||
|
||||
The corresponding handler is \c onPressAndHold.
|
||||
*/
|
||||
|
|
|
@ -1729,7 +1729,9 @@ void QQuickTextEdit::select(int start, int end)
|
|||
|
||||
// QTBUG-11100
|
||||
updateSelection();
|
||||
#if QT_CONFIG(im)
|
||||
updateInputMethod();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
|
@ -2083,11 +2083,12 @@ void QQuickWindowPrivate::flushFrameSynchronousEvents()
|
|||
ut->startAnimations();
|
||||
}
|
||||
|
||||
// Once per frame, send a synthetic hover, in case items have changed position.
|
||||
// Once per frame, if any items are dirty, send a synthetic hover,
|
||||
// in case items have changed position, visibility, etc.
|
||||
// For instance, during animation (including the case of a ListView
|
||||
// whose delegates contain MouseAreas), a MouseArea needs to know
|
||||
// whether it has moved into a position where it is now under the cursor.
|
||||
if (!q->mouseGrabberItem() && !lastMousePosition.isNull()) {
|
||||
if (!q->mouseGrabberItem() && !lastMousePosition.isNull() && dirtyItemList) {
|
||||
bool accepted = false;
|
||||
bool delivered = deliverHoverEvent(contentItem, lastMousePosition, lastMousePosition, QGuiApplication::keyboardModifiers(), 0, accepted);
|
||||
if (!delivered)
|
||||
|
|
|
@ -979,6 +979,10 @@ void Renderer::nodeChangedBatchRoot(Node *node, Node *root)
|
|||
e->root = root;
|
||||
e->boundsComputed = false;
|
||||
}
|
||||
} else if (node->type() == QSGNode::RenderNodeType) {
|
||||
RenderNodeElement *e = node->renderNodeElement();
|
||||
if (e)
|
||||
e->root = root;
|
||||
}
|
||||
|
||||
SHADOWNODE_TRAVERSE(node)
|
||||
|
@ -2022,6 +2026,8 @@ Renderer::ClipType Renderer::updateStencilClip(const QSGClipNode *clip)
|
|||
}
|
||||
|
||||
ClipType clipType = NoClip;
|
||||
GLuint vbo = 0;
|
||||
int vboSize = 0;
|
||||
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
|
||||
|
@ -2106,7 +2112,21 @@ Renderer::ClipType Renderer::updateStencilClip(const QSGClipNode *clip)
|
|||
const QSGGeometry *g = clip->geometry();
|
||||
Q_ASSERT(g->attributeCount() > 0);
|
||||
const QSGGeometry::Attribute *a = g->attributes();
|
||||
glVertexAttribPointer(0, a->tupleSize, a->type, GL_FALSE, g->sizeOfVertex(), g->vertexData());
|
||||
|
||||
if (!vbo)
|
||||
glGenBuffers(1, &vbo);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
||||
|
||||
const int vertexByteSize = g->sizeOfVertex() * g->vertexCount();
|
||||
if (vboSize < vertexByteSize) {
|
||||
vboSize = vertexByteSize;
|
||||
glBufferData(GL_ARRAY_BUFFER, vertexByteSize, g->vertexData(), GL_STATIC_DRAW);
|
||||
} else {
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, vertexByteSize, g->vertexData());
|
||||
}
|
||||
|
||||
glVertexAttribPointer(0, a->tupleSize, a->type, GL_FALSE, g->sizeOfVertex(), 0);
|
||||
|
||||
m_clipProgram.setUniformValue(m_clipMatrixId, m);
|
||||
if (g->indexCount()) {
|
||||
|
@ -2115,12 +2135,17 @@ Renderer::ClipType Renderer::updateStencilClip(const QSGClipNode *clip)
|
|||
glDrawArrays(g->drawingMode(), 0, g->vertexCount());
|
||||
}
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
++m_currentStencilValue;
|
||||
}
|
||||
|
||||
clip = clip->clipList();
|
||||
}
|
||||
|
||||
if (vbo)
|
||||
glDeleteBuffers(1, &vbo);
|
||||
|
||||
if (clipType & StencilClip) {
|
||||
m_clipProgram.disableAttributeArray(0);
|
||||
glStencilFunc(GL_EQUAL, m_currentStencilValue, 0xff); // stencil test, ref, test mask
|
||||
|
@ -2778,8 +2803,13 @@ void Renderer::renderRenderNode(Batch *batch)
|
|||
|
||||
updateClip(rd->m_clip_list, batch);
|
||||
|
||||
RenderNodeState state;
|
||||
QMatrix4x4 pm = projectionMatrix();
|
||||
if (m_useDepthBuffer) {
|
||||
pm(2, 2) = m_zRange;
|
||||
pm(2, 3) = 1.0f - e->order * m_zRange;
|
||||
}
|
||||
|
||||
RenderNodeState state;
|
||||
state.m_projectionMatrix = ±
|
||||
state.m_scissorEnabled = m_currentClipType & ScissorClip;
|
||||
state.m_stencilEnabled = m_currentClipType & StencilClip;
|
||||
|
|
|
@ -160,10 +160,7 @@ QSGRenderNode::StateFlags QSGRenderNode::changedStates() const
|
|||
\list
|
||||
\li glDepthMask(false)
|
||||
\li glDisable(GL_DEPTH_TEST)
|
||||
\li glStencilMask(0)
|
||||
\li glEnable(GL_STENCIL_TEST)/glDisable(GL_STENCIL_TEST) depending on clip
|
||||
\li glStencilFunc(GL_EQUAL, state.stencilValue, 0xff) depending on clip
|
||||
\li glEnable(GL_SCISSOR_TEST)/glDisable(GL_SCISSOR_TEST) depending on clip
|
||||
\li glScissor(state.scissorRect.x(), state.scissorRect.y(),
|
||||
state.scissorRect.width(), state.scissorRect.height()) depending on clip
|
||||
\li glEnable(GL_BLEND)
|
||||
|
|
|
@ -50,6 +50,7 @@ QT_BEGIN_NAMESPACE
|
|||
\inqmlmodule QtQuick
|
||||
\since 5.2
|
||||
\ingroup qtquick-transitions-animations
|
||||
\inherits Animation
|
||||
\brief Is the base of all QML animators.
|
||||
|
||||
Animator types are a special type of animation which operate
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#include <QtQml/qqmlcomponent.h>
|
||||
#include <QtQml/qqmlexpression.h>
|
||||
#include <QtQml/qqmlproperty.h>
|
||||
#include <QtQml/qqmlincubator.h>
|
||||
#include <QtQuick/qquickitem.h>
|
||||
|
||||
#include <QtNetwork/qhostaddress.h>
|
||||
|
@ -136,6 +137,7 @@ private slots:
|
|||
|
||||
void regression_QTCREATORBUG_7451();
|
||||
void queryObjectWithNonStreamableTypes();
|
||||
void asynchronousCreate();
|
||||
};
|
||||
|
||||
QmlDebugObjectReference tst_QQmlEngineDebugService::findRootObject(
|
||||
|
@ -1220,6 +1222,32 @@ void tst_QQmlEngineDebugService::queryObjectTree()
|
|||
QCOMPARE(findProperty(animation.properties,"duration").value.toInt(), 100);
|
||||
}
|
||||
|
||||
void tst_QQmlEngineDebugService::asynchronousCreate() {
|
||||
QmlDebugObjectReference object;
|
||||
auto connection = connect(m_dbg, &QQmlEngineDebugClient::newObject, this, [&](int objectId) {
|
||||
object.debugId = objectId;
|
||||
});
|
||||
|
||||
QByteArray asynchronousComponent = "import QtQuick 2.5\n"
|
||||
"Rectangle { id: asyncRect }";
|
||||
QQmlComponent component(m_engine);
|
||||
component.setData(asynchronousComponent, QUrl::fromLocalFile(""));
|
||||
QVERIFY(component.isReady()); // fails if bad syntax
|
||||
QQmlIncubator incubator(QQmlIncubator::Asynchronous);
|
||||
component.create(incubator);
|
||||
|
||||
QVERIFY(m_dbg->object().idString != QLatin1String("asyncRect"));
|
||||
|
||||
QTRY_VERIFY(object.debugId != -1);
|
||||
disconnect(connection);
|
||||
|
||||
bool success = false;
|
||||
m_dbg->queryObject(object, &success);
|
||||
QVERIFY(success);
|
||||
|
||||
QTRY_COMPARE(m_dbg->object().idString, QLatin1String("asyncRect"));
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int _argc = argc + 1;
|
||||
|
|
|
@ -489,7 +489,9 @@ void QQmlEngineDebugClient::messageReceived(const QByteArray &data)
|
|||
return;
|
||||
|
||||
} else if (type == "OBJECT_CREATED") {
|
||||
emit newObjects();
|
||||
int engineId, objectId, parentId;
|
||||
ds >> engineId >> objectId >> parentId;
|
||||
emit newObject(objectId);
|
||||
return;
|
||||
} else if (type == "SET_BINDING_R") {
|
||||
ds >> m_valid;
|
||||
|
|
|
@ -213,7 +213,7 @@ public:
|
|||
bool valid() { return m_valid; }
|
||||
|
||||
signals:
|
||||
void newObjects();
|
||||
void newObject(int objectId);
|
||||
void valueChanged(QByteArray,QVariant);
|
||||
void result();
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@ private slots:
|
|||
void registerImportForImplicitComponent();
|
||||
void basicVersionChecks();
|
||||
void recompileAfterChange();
|
||||
void recompileAfterDirectoryChange();
|
||||
void fileSelectors();
|
||||
void localAliases();
|
||||
void cacheResources();
|
||||
|
@ -95,11 +96,17 @@ struct TestCompiler
|
|||
TestCompiler(QQmlEngine *engine)
|
||||
: engine(engine)
|
||||
, tempDir()
|
||||
, testFilePath(tempDir.path() + QStringLiteral("/test.qml"))
|
||||
, cacheFilePath(tempDir.path() + QStringLiteral("/test.qmlc"))
|
||||
, mappedFile(cacheFilePath)
|
||||
, currentMapping(nullptr)
|
||||
{
|
||||
init(tempDir.path());
|
||||
}
|
||||
|
||||
void init(const QString &baseDirectory)
|
||||
{
|
||||
closeMapping();
|
||||
testFilePath = baseDirectory + QStringLiteral("/test.qml");
|
||||
cacheFilePath = baseDirectory + QStringLiteral("/test.qmlc");
|
||||
mappedFile.setFileName(cacheFilePath);
|
||||
}
|
||||
|
||||
bool compile(const QByteArray &contents)
|
||||
|
@ -187,8 +194,8 @@ struct TestCompiler
|
|||
|
||||
QQmlEngine *engine;
|
||||
const QTemporaryDir tempDir;
|
||||
const QString testFilePath;
|
||||
const QString cacheFilePath;
|
||||
QString testFilePath;
|
||||
QString cacheFilePath;
|
||||
QString lastErrorString;
|
||||
QFile mappedFile;
|
||||
uchar *currentMapping;
|
||||
|
@ -441,6 +448,47 @@ void tst_qmldiskcache::recompileAfterChange()
|
|||
}
|
||||
}
|
||||
|
||||
void tst_qmldiskcache::recompileAfterDirectoryChange()
|
||||
{
|
||||
QQmlEngine engine;
|
||||
TestCompiler testCompiler(&engine);
|
||||
|
||||
QVERIFY(testCompiler.tempDir.isValid());
|
||||
|
||||
QVERIFY(QDir(testCompiler.tempDir.path()).mkdir("source1"));
|
||||
testCompiler.init(testCompiler.tempDir.path() + QLatin1String("/source1"));
|
||||
|
||||
{
|
||||
const QByteArray contents = QByteArrayLiteral("import QtQml 2.0\n"
|
||||
"QtObject {\n"
|
||||
" property int blah: 42;\n"
|
||||
"}");
|
||||
|
||||
testCompiler.clearCache();
|
||||
QVERIFY2(testCompiler.compile(contents), qPrintable(testCompiler.lastErrorString));
|
||||
QVERIFY2(testCompiler.verify(), qPrintable(testCompiler.lastErrorString));
|
||||
testCompiler.closeMapping();
|
||||
}
|
||||
|
||||
const QDateTime initialCacheTimeStamp = QFileInfo(testCompiler.cacheFilePath).lastModified();
|
||||
|
||||
QDir(testCompiler.tempDir.path()).rename(QStringLiteral("source1"), QStringLiteral("source2"));
|
||||
waitForFileSystem();
|
||||
|
||||
testCompiler.init(testCompiler.tempDir.path() + QLatin1String("/source2"));
|
||||
|
||||
{
|
||||
CleanlyLoadingComponent component(&engine, testCompiler.testFilePath);
|
||||
QScopedPointer<QObject> obj(component.create());
|
||||
QVERIFY(!obj.isNull());
|
||||
QCOMPARE(obj->property("blah").toInt(), 42);
|
||||
}
|
||||
|
||||
QFile cacheFile(testCompiler.cacheFilePath);
|
||||
QVERIFY2(cacheFile.exists(), qPrintable(cacheFile.fileName()));
|
||||
QVERIFY(QFileInfo(testCompiler.cacheFilePath).lastModified() > initialCacheTimeStamp);
|
||||
}
|
||||
|
||||
void tst_qmldiskcache::fileSelectors()
|
||||
{
|
||||
QQmlEngine engine;
|
||||
|
|
|
@ -15,4 +15,6 @@ MyQmlObject
|
|||
onMySignal: { intProperty = a; realProperty = b; colorProperty = c; variantProperty = d; enumProperty = e; qtEnumProperty = f; }
|
||||
|
||||
onBasicSignal: root.mySignal(10, 19.2, Qt.rgba(1, 1, 0, 1), Qt.rgba(1, 0, 1, 1), MyQmlObject.EnumValue3, Qt.LeftButton)
|
||||
|
||||
onQjsValueEmittingSignal: {}
|
||||
}
|
||||
|
|
|
@ -244,6 +244,7 @@ signals:
|
|||
void signalWithGlobalName(int parseInt);
|
||||
void intChanged();
|
||||
void qjsvalueChanged();
|
||||
void qjsValueEmittingSignal(QJSValue value);
|
||||
|
||||
public slots:
|
||||
void deleteMe() { delete this; }
|
||||
|
|
|
@ -1410,6 +1410,7 @@ void tst_qqmlecmascript::signalParameterTypes()
|
|||
QVERIFY(object != 0);
|
||||
|
||||
emit object->basicSignal();
|
||||
emit object->qjsValueEmittingSignal(QJSValue());
|
||||
|
||||
QCOMPARE(object->property("intProperty").toInt(), 10);
|
||||
QCOMPARE(object->property("realProperty").toReal(), 19.2);
|
||||
|
|
|
@ -802,6 +802,27 @@ Item {
|
|||
layout.destroy() // Do not crash
|
||||
}
|
||||
|
||||
Component {
|
||||
id: rectangle_Component
|
||||
Rectangle {
|
||||
width: 100
|
||||
height: 50
|
||||
}
|
||||
}
|
||||
|
||||
function test_destroyImplicitInvisibleLayout()
|
||||
{
|
||||
var root = rectangle_Component.createObject(container)
|
||||
root.visible = false
|
||||
var layout = layout_deleteLayout.createObject(root)
|
||||
layout.visible = true
|
||||
// at this point the layout is still invisible because root is invisible
|
||||
layout.destroy()
|
||||
// Do not crash when destructing the layout
|
||||
waitForRendering(container) // should ideally call gc(), but does not work
|
||||
root.destroy()
|
||||
}
|
||||
|
||||
function test_sizeHintWithHiddenChildren(data) {
|
||||
var layout = layout_sizeHint_Component.createObject(container)
|
||||
var grid = layout.children[0]
|
||||
|
|
|
@ -741,7 +741,7 @@ void sigSegvHandler(int) {
|
|||
void printUsage(const QString &appName)
|
||||
{
|
||||
std::cerr << qPrintable(QString(
|
||||
"Usage: %1 [-v] [-noinstantiate] [-defaultplatform] [-[non]relocatable] [-dependencies <dependencies.json>] [-merge <file-to-merge.qmltypes>] [-noforceqtquick] module.uri version [module/import/path]\n"
|
||||
"Usage: %1 [-v] [-noinstantiate] [-defaultplatform] [-[non]relocatable] [-dependencies <dependencies.json>] [-merge <file-to-merge.qmltypes>] [-output <output-file.qmltypes>] [-noforceqtquick] module.uri version [module/import/path]\n"
|
||||
" %1 [-v] [-noinstantiate] -path path/to/qmldir/directory [version]\n"
|
||||
" %1 [-v] -builtins\n"
|
||||
"Example: %1 Qt.labs.folderlistmodel 2.0 /home/user/dev/qt-install/imports").arg(
|
||||
|
@ -998,6 +998,7 @@ int main(int argc, char *argv[])
|
|||
return EXIT_INVALIDARGUMENTS;
|
||||
}
|
||||
|
||||
QString outputFilename;
|
||||
QString pluginImportUri;
|
||||
QString pluginImportVersion;
|
||||
bool relocatable = true;
|
||||
|
@ -1051,6 +1052,13 @@ int main(int argc, char *argv[])
|
|||
} else if (arg == QLatin1String("--noforceqtquick")
|
||||
|| arg == QLatin1String("-noforceqtquick")){
|
||||
forceQtQuickDependency = false;
|
||||
} else if (arg == QLatin1String("--output")
|
||||
|| arg == QLatin1String("-output")) {
|
||||
if (++iArg == args.size()) {
|
||||
std::cerr << "missing output file" << std::endl;
|
||||
return EXIT_INVALIDARGUMENTS;
|
||||
}
|
||||
outputFilename = args.at(iArg);
|
||||
} else if (arg == QLatin1String("--defaultplatform")
|
||||
|| arg == QLatin1String("-defaultplatform")) {
|
||||
continue;
|
||||
|
@ -1306,7 +1314,15 @@ int main(int argc, char *argv[])
|
|||
qml.writeEndObject();
|
||||
qml.writeEndDocument();
|
||||
|
||||
std::cout << bytes.constData() << std::flush;
|
||||
if (!outputFilename.isEmpty()) {
|
||||
QFile file(outputFilename);
|
||||
if (file.open(QIODevice::WriteOnly)) {
|
||||
QTextStream stream(&file);
|
||||
stream << bytes.constData();
|
||||
}
|
||||
} else {
|
||||
std::cout << bytes.constData() << std::flush;
|
||||
}
|
||||
|
||||
// workaround to avoid crashes on exit
|
||||
QTimer timer;
|
||||
|
|
Loading…
Reference in New Issue