diff options
Diffstat (limited to 'src/quick')
310 files changed, 5791 insertions, 3409 deletions
diff --git a/src/quick/accessible/qaccessiblequickitem.cpp b/src/quick/accessible/qaccessiblequickitem.cpp index 2d6bb02af4..87e581384b 100644 --- a/src/quick/accessible/qaccessiblequickitem.cpp +++ b/src/quick/accessible/qaccessiblequickitem.cpp @@ -92,7 +92,7 @@ QAccessibleInterface *QAccessibleQuickItem::childAt(int x, int y) const { if (item()->clip()) { if (!rect().contains(x, y)) - return 0; + return nullptr; } const QList<QQuickItem*> kids = accessibleUnignoredChildren(item(), true); @@ -106,14 +106,14 @@ QAccessibleInterface *QAccessibleQuickItem::childAt(int x, int y) const } } - return 0; + return nullptr; } QAccessibleInterface *QAccessibleQuickItem::parent() const { QQuickItem *parent = item()->parentItem(); QQuickWindow *window = item()->window(); - QQuickItem *ci = window ? window->contentItem() : 0; + QQuickItem *ci = window ? window->contentItem() : nullptr; while (parent && !QQuickItemPrivate::get(parent)->isAccessible && parent != ci) parent = parent->parentItem(); @@ -131,7 +131,7 @@ QAccessibleInterface *QAccessibleQuickItem::parent() const return QAccessible::queryAccessibleInterface(parent); } } - return 0; + return nullptr; } QAccessibleInterface *QAccessibleQuickItem::child(int index) const @@ -139,7 +139,7 @@ QAccessibleInterface *QAccessibleQuickItem::child(int index) const QList<QQuickItem *> children = childItems(); if (index < 0 || index >= children.count()) - return 0; + return nullptr; QQuickItem *child = children.at(index); return QAccessible::queryAccessibleInterface(child); @@ -458,7 +458,7 @@ QTextDocument *QAccessibleQuickItem::textDocument() const QQuickTextDocument *qqdoc = docVariant.value<QQuickTextDocument*>(); return qqdoc->textDocument(); } - return 0; + return nullptr; } int QAccessibleQuickItem::characterCount() const diff --git a/src/quick/accessible/qaccessiblequickview.cpp b/src/quick/accessible/qaccessiblequickview.cpp index b3d1b6fc0f..3bb40546be 100644 --- a/src/quick/accessible/qaccessiblequickview.cpp +++ b/src/quick/accessible/qaccessiblequickview.cpp @@ -78,7 +78,7 @@ QAccessibleInterface *QAccessibleQuickWindow::child(int index) const const QList<QQuickItem*> &kids = rootItems(); if (index >= 0 && index < kids.count()) return QAccessible::queryAccessibleInterface(kids.at(index)); - return 0; + return nullptr; } QAccessibleInterface *QAccessibleQuickWindow::focusChild() const @@ -133,7 +133,7 @@ QAccessibleInterface *QAccessibleQuickWindow::childAt(int x, int y) const return childIface; } } - return 0; + return nullptr; } int QAccessibleQuickWindow::indexOfChild(const QAccessibleInterface *iface) const diff --git a/src/quick/accessible/qquickaccessiblefactory.cpp b/src/quick/accessible/qquickaccessiblefactory.cpp index a1fa695e5a..1aacf8e8bd 100644 --- a/src/quick/accessible/qquickaccessiblefactory.cpp +++ b/src/quick/accessible/qquickaccessiblefactory.cpp @@ -55,11 +55,11 @@ QAccessibleInterface *qQuickAccessibleFactory(const QString &classname, QObject Q_ASSERT(item); QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item); if (!itemPrivate->isAccessible) - return 0; + return nullptr; return new QAccessibleQuickItem(item); } - return 0; + return nullptr; } #endif diff --git a/src/quick/configure.json b/src/quick/configure.json index 65ad5b810b..7004ea7f7b 100644 --- a/src/quick/configure.json +++ b/src/quick/configure.json @@ -139,6 +139,14 @@ "privateFeature" ] }, + "quick-repeater": { + "label": "Repeater item", + "purpose": "Provides the Repeater item.", + "section": "Qt Quick", + "output": [ + "privateFeature" + ] + }, "quick-shadereffect": { "label": "ShaderEffect item", "purpose": "Provides Shader effects.", @@ -171,6 +179,7 @@ "quick-path", "quick-pathview", "quick-positioners", + "quick-repeater", "quick-shadereffect", "quick-sprite" ] diff --git a/src/quick/designer/qqmldesignermetaobject.cpp b/src/quick/designer/qqmldesignermetaobject.cpp index 33ea442b76..09493c30d6 100644 --- a/src/quick/designer/qqmldesignermetaobject.cpp +++ b/src/quick/designer/qqmldesignermetaobject.cpp @@ -50,7 +50,7 @@ QT_BEGIN_NAMESPACE static QHash<QDynamicMetaObjectData *, bool> nodeInstanceMetaObjectList; -static void (*notifyPropertyChangeCallBack)(QObject*, const QQuickDesignerSupport::PropertyName &propertyName) = 0; +static void (*notifyPropertyChangeCallBack)(QObject*, const QQuickDesignerSupport::PropertyName &propertyName) = nullptr; struct MetaPropertyData { inline QPair<QVariant, bool> &getDataRef(int idx) { @@ -127,7 +127,7 @@ void QQmlDesignerMetaObject::init(QObject *object, QQmlEngine *engine) } QQmlDesignerMetaObject::QQmlDesignerMetaObject(QObject *object, QQmlEngine *engine) - : QQmlVMEMetaObject(QQmlEnginePrivate::getV4Engine(engine), object, cacheForObject(object, engine), /*qml compilation unit*/nullptr, /*qmlObjectId*/-1), + : QQmlVMEMetaObject(engine->handle(), object, cacheForObject(object, engine), /*qml compilation unit*/nullptr, /*qmlObjectId*/-1), m_context(engine->contextForObject(object)), m_data(new MetaPropertyData) { @@ -174,7 +174,7 @@ void QQmlDesignerMetaObject::setValue(int id, const QVariant &value) QPair<QVariant, bool> &prop = m_data->getDataRef(id); prop.first = propertyWriteValue(id, value); prop.second = true; - QMetaObject::activate(myObject(), id + m_type->signalOffset(), 0); + QMetaObject::activate(myObject(), id + m_type->signalOffset(), nullptr); } QVariant QQmlDesignerMetaObject::propertyWriteValue(int, const QVariant &value) @@ -187,7 +187,7 @@ const QAbstractDynamicMetaObject *QQmlDesignerMetaObject::dynamicMetaObjectParen if (QQmlVMEMetaObject::parent.isT1()) return QQmlVMEMetaObject::parent.asT1()->toDynamicMetaObject(QQmlVMEMetaObject::object); else - return 0; + return nullptr; } const QMetaObject *QQmlDesignerMetaObject::metaObjectParent() const @@ -218,7 +218,7 @@ int QQmlDesignerMetaObject::openMetaCall(QObject *o, QMetaObject::Call call, int prop.first = propertyWriteValue(propId, *reinterpret_cast<QVariant *>(a[0])); prop.second = true; //propertyWritten(propId); - activate(myObject(), m_type->signalOffset() + propId, 0); + activate(myObject(), m_type->signalOffset() + propId, nullptr); } } return -1; diff --git a/src/quick/designer/qquickdesignercustomobjectdata.cpp b/src/quick/designer/qquickdesignercustomobjectdata.cpp index ca9c1259fd..59e086b5a3 100644 --- a/src/quick/designer/qquickdesignercustomobjectdata.cpp +++ b/src/quick/designer/qquickdesignercustomobjectdata.cpp @@ -180,7 +180,7 @@ void QQuickDesignerCustomObjectData::doResetProperty(QQmlContext *context, const QQmlAbstractBinding *binding = QQmlPropertyPrivate::binding(property); if (binding && !(hasValidResetBinding(propertyName) && getResetBinding(propertyName) == binding)) { - binding->setEnabled(false, 0); + binding->setEnabled(false, nullptr); } diff --git a/src/quick/designer/qquickdesignersupport.cpp b/src/quick/designer/qquickdesignersupport.cpp index 88971e3172..1851c25a77 100644 --- a/src/quick/designer/qquickdesignersupport.cpp +++ b/src/quick/designer/qquickdesignersupport.cpp @@ -78,7 +78,7 @@ QQuickDesignerSupport::~QQuickDesignerSupport() void QQuickDesignerSupport::refFromEffectItem(QQuickItem *referencedItem, bool hide) { - if (referencedItem == 0) + if (referencedItem == nullptr) return; QQuickItemPrivate::get(referencedItem)->refFromEffectItem(hide); @@ -114,7 +114,7 @@ void QQuickDesignerSupport::refFromEffectItem(QQuickItem *referencedItem, bool h void QQuickDesignerSupport::derefFromEffectItem(QQuickItem *referencedItem, bool unhide) { - if (referencedItem == 0) + if (referencedItem == nullptr) return; delete m_itemTextureHash.take(referencedItem); @@ -123,7 +123,7 @@ void QQuickDesignerSupport::derefFromEffectItem(QQuickItem *referencedItem, bool QImage QQuickDesignerSupport::renderImageForItem(QQuickItem *referencedItem, const QRectF &boundingRect, const QSize &imageSize) { - if (referencedItem == 0 || referencedItem->parentItem() == 0) { + if (referencedItem == nullptr || referencedItem->parentItem() == nullptr) { qDebug() << __FILE__ << __LINE__ << "Warning: Item can be rendered."; return QImage(); } @@ -131,7 +131,7 @@ QImage QQuickDesignerSupport::renderImageForItem(QQuickItem *referencedItem, con QSGLayer *renderTexture = m_itemTextureHash.value(referencedItem); Q_ASSERT(renderTexture); - if (renderTexture == 0) + if (renderTexture == nullptr) return QImage(); renderTexture->setRect(boundingRect); renderTexture->setSize(imageSize); @@ -150,7 +150,7 @@ QImage QQuickDesignerSupport::renderImageForItem(QQuickItem *referencedItem, con bool QQuickDesignerSupport::isDirty(QQuickItem *referencedItem, DirtyType dirtyType) { - if (referencedItem == 0) + if (referencedItem == nullptr) return false; return QQuickItemPrivate::get(referencedItem)->dirtyAttributes & dirtyType; @@ -158,7 +158,7 @@ bool QQuickDesignerSupport::isDirty(QQuickItem *referencedItem, DirtyType dirtyT void QQuickDesignerSupport::addDirty(QQuickItem *referencedItem, QQuickDesignerSupport::DirtyType dirtyType) { - if (referencedItem == 0) + if (referencedItem == nullptr) return; QQuickItemPrivate::get(referencedItem)->dirtyAttributes |= dirtyType; @@ -166,7 +166,7 @@ void QQuickDesignerSupport::addDirty(QQuickItem *referencedItem, QQuickDesignerS void QQuickDesignerSupport::resetDirty(QQuickItem *referencedItem) { - if (referencedItem == 0) + if (referencedItem == nullptr) return; QQuickItemPrivate::get(referencedItem)->dirtyAttributes = 0x0; @@ -175,7 +175,7 @@ void QQuickDesignerSupport::resetDirty(QQuickItem *referencedItem) QTransform QQuickDesignerSupport::windowTransform(QQuickItem *referencedItem) { - if (referencedItem == 0) + if (referencedItem == nullptr) return QTransform(); return QQuickItemPrivate::get(referencedItem)->itemToWindowTransform(); @@ -183,7 +183,7 @@ QTransform QQuickDesignerSupport::windowTransform(QQuickItem *referencedItem) QTransform QQuickDesignerSupport::parentTransform(QQuickItem *referencedItem) { - if (referencedItem == 0) + if (referencedItem == nullptr) return QTransform(); QTransform parentTransform; @@ -294,31 +294,31 @@ bool QQuickDesignerSupport::hasAnchor(QQuickItem *item, const QString &name) return false; if (name == QLatin1String("anchors.fill")) - return anchors(item)->fill() != 0; + return anchors(item)->fill() != nullptr; if (name == QLatin1String("anchors.centerIn")) - return anchors(item)->centerIn() != 0; + return anchors(item)->centerIn() != nullptr; if (name == QLatin1String("anchors.right")) - return anchors(item)->right().item != 0; + return anchors(item)->right().item != nullptr; if (name == QLatin1String("anchors.top")) - return anchors(item)->top().item != 0; + return anchors(item)->top().item != nullptr; if (name == QLatin1String("anchors.left")) - return anchors(item)->left().item != 0; + return anchors(item)->left().item != nullptr; if (name == QLatin1String("anchors.bottom")) - return anchors(item)->bottom().item != 0; + return anchors(item)->bottom().item != nullptr; if (name == QLatin1String("anchors.horizontalCenter")) - return anchors(item)->horizontalCenter().item != 0; + return anchors(item)->horizontalCenter().item != nullptr; if (name == QLatin1String("anchors.verticalCenter")) - return anchors(item)->verticalCenter().item != 0; + return anchors(item)->verticalCenter().item != nullptr; if (name == QLatin1String("anchors.baseline")) - return anchors(item)->baseline().item != 0; + return anchors(item)->baseline().item != nullptr; return anchors(item)->usedAnchors().testFlag(anchorLineFlagForName(name)); } @@ -337,7 +337,7 @@ QQuickItem *QQuickDesignerSupport::anchorCenterInTargetItem(QQuickItem *item) QPair<QString, QObject*> QQuickDesignerSupport::anchorLineTarget(QQuickItem *item, const QString &name, QQmlContext *context) { - QObject *targetObject = 0; + QObject *targetObject = nullptr; QString targetName; if (name == QLatin1String("anchors.fill")) { diff --git a/src/quick/designer/qquickdesignersupportitems.cpp b/src/quick/designer/qquickdesignersupportitems.cpp index 38ba46e702..9fadbb2122 100644 --- a/src/quick/designer/qquickdesignersupportitems.cpp +++ b/src/quick/designer/qquickdesignersupportitems.cpp @@ -55,11 +55,11 @@ QT_BEGIN_NAMESPACE -static void (*fixResourcePathsForObjectCallBack)(QObject*) = 0; +static void (*fixResourcePathsForObjectCallBack)(QObject*) = nullptr; static void stopAnimation(QObject *object) { - if (object == 0) + if (object == nullptr) return; QQuickTransition *transition = qobject_cast<QQuickTransition*>(object); @@ -203,7 +203,7 @@ QObject *QQuickDesignerSupportItems::createPrimitive(const QString &typeName, in Q_UNUSED(disableComponentComplete) - QObject *object = 0; + QObject *object = nullptr; QQmlType type = QQmlMetaType::qmlType(typeName, majorNumber, minorNumber); if (isCrashingType(type)) { @@ -214,7 +214,7 @@ QObject *QQuickDesignerSupportItems::createPrimitive(const QString &typeName, in } else { if (type.typeName() == "QQmlComponent") { - object = new QQmlComponent(context->engine(), 0); + object = new QQmlComponent(context->engine(), nullptr); } else { object = type.create(); } @@ -235,7 +235,7 @@ QObject *QQuickDesignerSupportItems::createPrimitive(const QString &typeName, in tweakObjects(object); - if (object && QQmlEngine::contextForObject(object) == 0) + if (object && QQmlEngine::contextForObject(object) == nullptr) QQmlEngine::setContextForObject(object, context); QQmlEngine::setObjectOwnership(object, QQmlEngine::CppOwnership); diff --git a/src/quick/designer/qquickdesignersupportmetainfo.cpp b/src/quick/designer/qquickdesignersupportmetainfo.cpp index b398bae55d..9c8a642837 100644 --- a/src/quick/designer/qquickdesignersupportmetainfo.cpp +++ b/src/quick/designer/qquickdesignersupportmetainfo.cpp @@ -47,7 +47,7 @@ QT_BEGIN_NAMESPACE bool QQuickDesignerSupportMetaInfo::isSubclassOf(QObject *object, const QByteArray &superTypeName) { - if (object == 0) + if (object == nullptr) return false; const QMetaObject *metaObject = object->metaObject(); diff --git a/src/quick/designer/qquickdesignersupportproperties.cpp b/src/quick/designer/qquickdesignersupportproperties.cpp index a4d1fd0dc1..674f811f8f 100644 --- a/src/quick/designer/qquickdesignersupportproperties.cpp +++ b/src/quick/designer/qquickdesignersupportproperties.cpp @@ -134,7 +134,7 @@ QQuickDesignerSupport::PropertyNameList QQuickDesignerSupportProperties::propert QObjectList localObjectList; - if (inspectedObjects == 0) + if (inspectedObjects == nullptr) inspectedObjects = &localObjectList; @@ -191,7 +191,7 @@ QQuickDesignerSupport::PropertyNameList QQuickDesignerSupportProperties::allProp QObjectList localObjectList; - if (inspectedObjects == 0) + if (inspectedObjects == nullptr) inspectedObjects = &localObjectList; diff --git a/src/quick/designer/qquickdesignersupportproperties_p.h b/src/quick/designer/qquickdesignersupportproperties_p.h index a2872be060..02e75ea886 100644 --- a/src/quick/designer/qquickdesignersupportproperties_p.h +++ b/src/quick/designer/qquickdesignersupportproperties_p.h @@ -92,10 +92,10 @@ public: static bool isPropertyBlackListed(const QQuickDesignerSupport::PropertyName &propertyName); static QQuickDesignerSupport::PropertyNameList propertyNameListForWritableProperties(QObject *object, const QQuickDesignerSupport::PropertyName &baseName = QQuickDesignerSupport::PropertyName(), - QObjectList *inspectedObjects = 0); + QObjectList *inspectedObjects = nullptr); static QQuickDesignerSupport::PropertyNameList allPropertyNames(QObject *object, const QQuickDesignerSupport::PropertyName &baseName = QQuickDesignerSupport::PropertyName(), - QObjectList *inspectedObjects = 0); + QObjectList *inspectedObjects = nullptr); static bool hasFullImplementedListInterface(const QQmlListReference &list); }; diff --git a/src/quick/designer/qquickdesignersupportpropertychanges.cpp b/src/quick/designer/qquickdesignersupportpropertychanges.cpp index 5cafcfc360..0ee8857325 100644 --- a/src/quick/designer/qquickdesignersupportpropertychanges.cpp +++ b/src/quick/designer/qquickdesignersupportpropertychanges.cpp @@ -59,7 +59,7 @@ QObject *QQuickDesignerSupportPropertyChanges::targetObject(QObject *propertyCha QQuickPropertyChanges *propertyChange = qobject_cast<QQuickPropertyChanges*>(propertyChanges); if (!propertyChange) - return 0; + return nullptr; return propertyChange->object(); } @@ -114,7 +114,7 @@ QObject *QQuickDesignerSupportPropertyChanges::stateObject(QObject *propertyChan QQuickPropertyChanges *propertyChange = qobject_cast<QQuickPropertyChanges*>(propertyChanges); if (!propertyChange) - return 0; + return nullptr; return propertyChange->state(); } diff --git a/src/quick/doc/images/animatedsprite-loading-frames.png b/src/quick/doc/images/animatedsprite-loading-frames.png Binary files differnew file mode 100644 index 0000000000..924e7f0bac --- /dev/null +++ b/src/quick/doc/images/animatedsprite-loading-frames.png diff --git a/src/quick/doc/images/animatedsprite-loading-interpolated.gif b/src/quick/doc/images/animatedsprite-loading-interpolated.gif Binary files differnew file mode 100644 index 0000000000..e4512cd3be --- /dev/null +++ b/src/quick/doc/images/animatedsprite-loading-interpolated.gif diff --git a/src/quick/doc/images/animatedsprite-loading.gif b/src/quick/doc/images/animatedsprite-loading.gif Binary files differnew file mode 100644 index 0000000000..1eaf7ad892 --- /dev/null +++ b/src/quick/doc/images/animatedsprite-loading.gif diff --git a/src/quick/doc/images/animatedsprite-loading.png b/src/quick/doc/images/animatedsprite-loading.png Binary files differnew file mode 100644 index 0000000000..ff2bbbd140 --- /dev/null +++ b/src/quick/doc/images/animatedsprite-loading.png diff --git a/src/quick/doc/qtquick.qdocconf b/src/quick/doc/qtquick.qdocconf index 028b30dba1..7ce0dfcf09 100644 --- a/src/quick/doc/qtquick.qdocconf +++ b/src/quick/doc/qtquick.qdocconf @@ -33,7 +33,7 @@ qhp.QtQuick.subprojects.examples.selectors = fake:example tagfile = ../../../doc/qtquick/qtquick.tags -depends += qtcore qtxmlpatterns qtqml qtgui qtlinguist qtquickcontrols qtdoc qtquickdialogs qtsensors qtwidgets qmake qtmultimedia qtgraphicaleffects +depends += qtcore qtxmlpatterns qtqml qtqmltest qtgui qtlinguist qtquickcontrols qtquickcontrols2 qtdoc qtquickdialogs qtsensors qtwidgets qmake qtmultimedia qtgraphicaleffects qtsql headerdirs += ..\ ../../quickwidgets diff --git a/src/quick/doc/snippets/pointerHandlers/dragHandler.qml b/src/quick/doc/snippets/pointerHandlers/dragHandler.qml index 349cdcb95f..78a7db5b0c 100644 --- a/src/quick/doc/snippets/pointerHandlers/dragHandler.qml +++ b/src/quick/doc/snippets/pointerHandlers/dragHandler.qml @@ -1,12 +1,22 @@ /**************************************************************************** ** ** Copyright (C) 2017 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the documentation of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are diff --git a/src/quick/doc/snippets/pointerHandlers/dragHandlerDifferentTarget.qml b/src/quick/doc/snippets/pointerHandlers/dragHandlerDifferentTarget.qml index e8f2a04e6a..4c4168de83 100644 --- a/src/quick/doc/snippets/pointerHandlers/dragHandlerDifferentTarget.qml +++ b/src/quick/doc/snippets/pointerHandlers/dragHandlerDifferentTarget.qml @@ -1,12 +1,22 @@ /**************************************************************************** ** ** Copyright (C) 2017 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the documentation of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are diff --git a/src/quick/doc/snippets/pointerHandlers/dragHandlerNullTarget.qml b/src/quick/doc/snippets/pointerHandlers/dragHandlerNullTarget.qml index e210ce0952..09429ec1d2 100644 --- a/src/quick/doc/snippets/pointerHandlers/dragHandlerNullTarget.qml +++ b/src/quick/doc/snippets/pointerHandlers/dragHandlerNullTarget.qml @@ -1,12 +1,22 @@ /**************************************************************************** ** ** Copyright (C) 2017 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the documentation of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are diff --git a/src/quick/doc/snippets/pointerHandlers/pinchHandler.qml b/src/quick/doc/snippets/pointerHandlers/pinchHandler.qml index 841e401da1..955047d115 100644 --- a/src/quick/doc/snippets/pointerHandlers/pinchHandler.qml +++ b/src/quick/doc/snippets/pointerHandlers/pinchHandler.qml @@ -1,12 +1,22 @@ /**************************************************************************** ** ** Copyright (C) 2017 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the documentation of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are diff --git a/src/quick/doc/snippets/pointerHandlers/pinchHandlerDifferentTarget.qml b/src/quick/doc/snippets/pointerHandlers/pinchHandlerDifferentTarget.qml index 211c370da6..a5255a64e3 100644 --- a/src/quick/doc/snippets/pointerHandlers/pinchHandlerDifferentTarget.qml +++ b/src/quick/doc/snippets/pointerHandlers/pinchHandlerDifferentTarget.qml @@ -1,12 +1,22 @@ /**************************************************************************** ** ** Copyright (C) 2017 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the documentation of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are diff --git a/src/quick/doc/snippets/pointerHandlers/pinchHandlerNullTarget.qml b/src/quick/doc/snippets/pointerHandlers/pinchHandlerNullTarget.qml index b0139d7194..7d21efcb84 100644 --- a/src/quick/doc/snippets/pointerHandlers/pinchHandlerNullTarget.qml +++ b/src/quick/doc/snippets/pointerHandlers/pinchHandlerNullTarget.qml @@ -1,12 +1,22 @@ /**************************************************************************** ** ** Copyright (C) 2017 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the documentation of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are diff --git a/src/quick/doc/snippets/qml/localstorage/dbtransaction.js b/src/quick/doc/snippets/pointerHandlers/pointHandler.qml index aafe10c5f1..262eb607b6 100644 --- a/src/quick/doc/snippets/qml/localstorage/dbtransaction.js +++ b/src/quick/doc/snippets/pointerHandlers/pointHandler.qml @@ -1,9 +1,9 @@ - /**************************************************************************** +/**************************************************************************** ** ** Copyright (C) 2017 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the examples of the Qt Toolkit. +** This file is part of the documentation of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:BSD$ ** Commercial License Usage @@ -47,61 +47,33 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ - -//![0] -var db = LocalStorage.openDatabaseSync("ActivityTrackDB", "", "Database tracking sports activities", 1000000); -db.transaction( - try { - function(tx) { - tx.executeSql("INSERT INTO trip_log VALUES(?, ?, ?)", - [ "01/10/2016","Sylling - Vikersund", "53" ]); - } - } catch (err) { - console.log("Error inserting into table trip_log: " + err); - } -) //![0] +import QtQuick 2.10 +import QtQuick.Window 2.2 +import Qt.labs.handlers 1.0 + +Window { + width: 480 + height: 320 + visible: true -//![1] -// Retrieve activity date, description and distance based on minimum -// distance parameter Pdistance -function db_distance_select(Pdistance) -{ -var db = LocalStorage.openDatabaseSync("ActivityTrackDB", "", "Database tracking sports activities", 1000000); -db.transaction( - function(tx) { - var results = tx.executeSql("SELECT rowid, - date, - trip_desc, - distance FROM trip_log - where distance >= ?",[Pdistance]); - for (var i = 0; i < results.rows.length; i++) { - listModel.append({"id": results.rows.item(i).rowid, - "date": results.rows.item(i).date, - "trip_desc": results.rows.item(i).trip_desc, - "distance": results.rows.item(i).distance}); + Item { + id: glassPane + z: 10000 + anchors.fill: parent + + PointHandler { + id: handler + acceptedDevices: PointerDevice.TouchScreen | PointerDevice.TouchPad + target: Rectangle { + parent: glassPane + color: "red" + visible: handler.active + x: handler.point.position.x - width / 2 + y: handler.point.position.y - height / 2 + width: 20; height: width; radius: width / 2 + } } } } -//![1] -//![2] -var db = LocalStorage.openDatabaseSync("ActivityTrackDB", "", "Database tracking sports activities", 1000000); -if (db.version == "0.1") { - db.changeVersion("0.1", "0.2", function(tx) { - tx.executeSql("INSERT INTO trip_log VALUES(?, ?, ?)", - [ "01/10/2016","Sylling - Vikersund", "53" ]); - } -}); -//![2] -//![3] -create table trip_log(date text, data text) -//![3] -//![4] -var obj = {description = "Vikersund - Noresund", distance = "60"} -//![4] -//![5] -db.transaction(function(tx) { - result = tx.executeSQL("insert into trip_log values (?,?)", - ["01/11/2016", JSON.stringify(obj)]) -} -//![5] +//![0] diff --git a/src/quick/doc/snippets/qml/layout-simple.qml b/src/quick/doc/snippets/qml/layout-simple.qml new file mode 100644 index 0000000000..6afdbe3ec9 --- /dev/null +++ b/src/quick/doc/snippets/qml/layout-simple.qml @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.9 +import QtQuick.Layouts 1.2 +import QtQuick.Window 2.2 + +//! [1] +Window { + RowLayout { + anchors.fill: parent + //! [spacing] + spacing: 6 + //! [spacing] + Rectangle { + color: 'azure' + Layout.preferredWidth: 100 + Layout.preferredHeight: 150 + } + Rectangle { + color: "plum" + Layout.fillWidth: true + Layout.fillHeight: true + } + } +} +//! [1] diff --git a/src/quick/doc/snippets/qml/path/arcrotation.qml b/src/quick/doc/snippets/qml/path/arcrotation.qml index c73d67ff17..985ac51d8a 100644 --- a/src/quick/doc/snippets/qml/path/arcrotation.qml +++ b/src/quick/doc/snippets/qml/path/arcrotation.qml @@ -1,12 +1,22 @@ /**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the documentation of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are diff --git a/src/quick/doc/src/concepts/layouts/qtquicklayouts-overview.qdoc b/src/quick/doc/src/concepts/layouts/qtquicklayouts-overview.qdoc index 05e4465f2a..06ebe2d3d1 100644 --- a/src/quick/doc/src/concepts/layouts/qtquicklayouts-overview.qdoc +++ b/src/quick/doc/src/concepts/layouts/qtquicklayouts-overview.qdoc @@ -74,8 +74,31 @@ \endlist + \section1 A Simple Layout + + \snippet qml/layout-simple.qml 1 + + As the intention of using a layout is to rearrange its children whenever the layout changes + size, the application should make sure that the layout gets resized. In the above snippet the + RowLayout ensures that by specifying \c{anchors.fill: parent}. However, it can also be by other + means, such as directly specifying \l{Item::width}{width} and \l{Item::height}{height} + properties. In the same snippet, the \c azure Rectangle has a fixed size of \c{(100, 150)} + pixels, and the \c plum Rectangle will expand to occupy all the space it gets allocated. + + \note A layout is responsible for its children's geometry. You should + therefore not specify \l{Item::width}{width}, \l{Item::height}{height}, \l{Item::x}{x}, + \l{Item::y}{y} or any other properties that might influence those properties (such as + \l{Item::anchors}{anchors}) on those items. Otherwise there would be a conflict of interest, + and the result is undefined. This is also the case if the child item is a layout. Therefore, + only layouts with no parent layout can have \c{anchors.fill: parent}. + + All items in the layout will have 6 pixels of spacing between them: + + \snippet qml/layout-simple.qml spacing + + + \section2 Size Constraints - \section1 Size Constraints Since an item can be resized by its layout, the layout needs to know the \l{Layout::minimumWidth}{minimum}, \l{Layout::preferredWidth}{preferred}, and \l{Layout::maximumWidth}{maximum} sizes of all items where \l{Layout::fillWidth}{Layout.fillWidth} or diff --git a/src/quick/doc/src/concepts/modelviewsdata/cppmodels.qdoc b/src/quick/doc/src/concepts/modelviewsdata/cppmodels.qdoc index 27c8e51381..2705ca5e34 100644 --- a/src/quick/doc/src/concepts/modelviewsdata/cppmodels.qdoc +++ b/src/quick/doc/src/concepts/modelviewsdata/cppmodels.qdoc @@ -41,6 +41,10 @@ QObjectList or a \l QAbstractItemModel. The first three are useful for exposing simpler datasets, while QAbstractItemModel provides a more flexible solution for more complex models. +For a video tutorial that takes you through the whole process of exposing a C++ +model to QML, see the +\l {https://youtu.be/9BcAYDlpuT8}{Using C++ Models in QML Tutorial}. + \section2 QStringList-based Model A model may be a simple \l QStringList, which provides the contents of the list diff --git a/src/quick/doc/src/concepts/pointerhandlers/qtquickhandlers-index.qdoc b/src/quick/doc/src/concepts/pointerhandlers/qtquickhandlers-index.qdoc index b17c5ab728..fc1fd5fbc1 100644 --- a/src/quick/doc/src/concepts/pointerhandlers/qtquickhandlers-index.qdoc +++ b/src/quick/doc/src/concepts/pointerhandlers/qtquickhandlers-index.qdoc @@ -67,7 +67,7 @@ \list \li \l{Qt Quick} - \li \l{Qt Quick Pointer Handlers Overview} + \li \l{Qt Quick Pointer Handlers} \li \l{Qt Quick Pointer Handlers QML Types}{Qt Quick Pointer Handlers QML Types} \endlist */ diff --git a/src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc b/src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc index 27576d488c..99175ab94e 100644 --- a/src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc +++ b/src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the documentation of the Qt Toolkit. @@ -176,8 +176,8 @@ attach application code. This can be used to add custom scene graph content or render raw OpenGL content. The integration points are defined by the render loop. -For detailed description of how the scene graph renderer works, see -\l {Qt Quick Scene Graph Renderer}. +For detailed description of how the scene graph renderer for OpenGL +works, see \l {Qt Quick Scene Graph OpenGL Renderer}. There are three render loop variants available: \c basic, \c windows, and \c threaded. Out of these, \c basic and \c windows are @@ -413,10 +413,11 @@ with multiple windows. */ /*! - \title Qt Quick Scene Graph Renderer + \title Qt Quick Scene Graph OpenGL Renderer \page qtquick-visualcanvas-scenegraph-renderer.html - This document explains how the scene graph renderer works internally + This document explains how the scene graph renderer for OpenGL + works internally so that one can write code that uses it in an optimal fashion, both performance-wise and feature-wise. @@ -428,7 +429,7 @@ with multiple windows. \note Even in the case where every frame is unique and everything is uploaded from scratch, the default renderer will perform well. - The Qt Quick items in a QML scene populates a tree of QSGNode + The Qt Quick items in a QML scene populate a tree of QSGNode instances. Once created, this tree is a complete description of how a certain frame should be rendered. It does not contain any references back to the Qt Quick items at all and will on most @@ -441,11 +442,11 @@ with multiple windows. If needed, the renderer can be completely replaced using the internal scene graph back-end API. This is mostly interesting for platform vendors who wish to take advantage of non-standard hardware - features. For majority of use cases, the default renderer will be + features. For the majority of use cases, the default renderer will be sufficient. The default renderer focuses on two primary strategies to optimize - the rendering. Batching of draw calls and retention of geometry on + the rendering: Batching of draw calls, and retention of geometry on the GPU. \section1 Batching @@ -458,7 +459,7 @@ with multiple windows. \image visualcanvas_list.png - The simplest way of drawing this list is on a cell-by-cell basis. First + The simplest way of drawing this list is on a cell-by-cell basis. First, the background is drawn. This is a rectangle of a specific color. In OpenGL terms this means selecting a shader program to do solid color fills, setting up the fill color, setting the transformation matrix @@ -495,8 +496,8 @@ with multiple windows. batches. From Qt Quick core item set, this includes Rectangle items with opaque colors and fully opaque images, such as JPEGs or BMPs. - Another benefit of using opaque primitives, is that opaque - primitives does not require \c GL_BLEND to be enabled which can be + Another benefit of using opaque primitives is that opaque + primitives do not require \c GL_BLEND to be enabled, which can be quite costly, especially on mobile and embedded GPUs. Opaque primitives are rendered in a front-to-back manner with @@ -533,7 +534,7 @@ with multiple windows. and the two text elements in another call, as the texts only overlap a background which they are stacked in front of. In the right-most case, the background of "Item 4" overlaps the text of "Item 3" so in - this case, each of backgrounds and texts need to be drawn using + this case, each of backgrounds and texts needs to be drawn using separate calls. Z-wise, the alpha primitives are interleaved with the opaque nodes @@ -550,7 +551,7 @@ with multiple windows. The renderer modifies the vertex shader returned from QSGMaterialShader::vertexShader() and compresses the z values of the - vertex after the model-view and projection matrices has been applied + vertex after the model-view and projection matrices have been applied and then adds a small translation on the z to position it the correct z position. @@ -561,7 +562,7 @@ with multiple windows. The active texture is a unique OpenGL state, which means that multiple primitives using different OpenGL textures cannot be - batched. The Qt Quick scene graph for this reason allows multiple + batched. The Qt Quick scene graph, for this reason, allows multiple QSGTexture instances to be allocated as smaller sub-regions of a larger texture; a texture atlas. @@ -603,10 +604,10 @@ with multiple windows. Each Qt Quick Item inserts a QSGTransformNode into the scene graph tree to manage its x, y, scale or rotation. Child items will be populated under this transform node. The default renderer tracks - the state of transform nodes between frames, and will look at + the state of transform nodes between frames and will look at subtrees to decide if a transform node is a good candidate to become a root for a set of batches. A transform node which changes between - frames and which has a fairly complex subtree, can become a batch + frames and which has a fairly complex subtree can become a batch root. QSGGeometryNodes in the subtree of a batch root are pre-transformed @@ -621,7 +622,7 @@ with multiple windows. removed nodes when panning through a grid or list. Another benefit of identifying transform nodes as batch roots is - that it allows the renderer to retain the parts of the tree that has + that it allows the renderer to retain the parts of the tree that have not changed. For instance, say a UI consists of a list and a button row. When the list is being scrolled and delegates are being added and removed, the rest of the UI, the button row, is unchanged and @@ -684,7 +685,7 @@ with multiple windows. to either \c vertex or \c {msaa}. Vertex antialiasing can produce seams between edges of adjacent - primitives, even when the two edges are mathmatically the same. + primitives, even when the two edges are mathematically the same. Multisample antialiasing does not. @@ -722,7 +723,7 @@ with multiple windows. job when creating batches and can rely on early-z to avoid overdraw. When multisample antialiasing is used, content rendered into - framebuffer objects, need additional extensions to support multisampling + framebuffer objects need additional extensions to support multisampling of framebuffers. Typically \c GL_EXT_framebuffer_multisample and \c GL_EXT_framebuffer_blit. Most desktop chips have these extensions present, but they are less common in embedded chips. When framebuffer @@ -736,7 +737,7 @@ with multiple windows. As stated in the beginning, understanding the finer details of the renderer is not required to get good performance. It is written to optimize for common use cases and will perform quite well under - almost any circumstance. + almost any circumstances. \list @@ -744,7 +745,7 @@ with multiple windows. as possible of the geometry being uploaded again and again. By setting the environment variable \c {QSG_RENDERER_DEBUG=render}, the renderer will output statistics on how well the batching goes, how - many batches, which batches are retained and which are opaque and + many batches are used, which batches are retained and which are opaque and not. When striving for optimal performance, uploads should happen only when really needed, batches should be fewer than 10 and at least 3-4 of them should be opaque. @@ -772,16 +773,16 @@ with multiple windows. QQuickWindow::createTextureFromImage(), let the image have QImage::Format_RGB32, when possible. - \li Be aware of that overlapping compond items, like in the - illustration above, can not be batched. + \li Be aware of that overlapping compound items, like in the + illustration above, cannot be batched. \li Clipping breaks batching. Never use on a per-item basis, inside - tables cells, item delegates or similar. Instead of clipping text, + table cells, item delegates or similar. Instead of clipping text, use eliding. Instead of clipping an image, create a QQuickImageProvider that returns a cropped image. \li Batching only works for 16-bit indices. All built-in items use - 16-bit indices, but custom geometry is free to also use 32-bit + 16-bit indices, but a custom geometry is free to also use 32-bit indices. \li Some material flags prevent batching, the most limiting one @@ -792,7 +793,7 @@ with multiple windows. QQuickWindow::setColor() will be used in a call to \c glClear(), which is potentially faster. - \li Mipmapped Image items are not placed in global atlas and will + \li Mipmapped Image items are not placed in the global atlas and will not be batched. \endlist diff --git a/src/quick/doc/src/qmltypereference.qdoc b/src/quick/doc/src/qmltypereference.qdoc index 16bb4e2a30..f5b189c580 100644 --- a/src/quick/doc/src/qmltypereference.qdoc +++ b/src/quick/doc/src/qmltypereference.qdoc @@ -894,5 +894,5 @@ import QtTest 1.1 \endcode For more information about how to use these types, see -\l{Qt Quick Test Reference Documentation}. +\l{Qt Quick Test}. */ diff --git a/src/quick/doc/src/qtquick.qdoc b/src/quick/doc/src/qtquick.qdoc index e2d4f16dae..ece66cb589 100644 --- a/src/quick/doc/src/qtquick.qdoc +++ b/src/quick/doc/src/qtquick.qdoc @@ -89,7 +89,8 @@ To find out more about using the QML language, see the \l{Qt QML} module documen \section1 Licenses and Attributions Qt Quick is available under commercial licenses from \l{The Qt Company}. -In addition, it is available under the +In addition, it is available under free software licenses. Since Qt 5.4, +these free software licenses are \l{GNU Lesser General Public License, version 3}, or the \l{GNU General Public License, version 2}. See \l{Qt Licensing} for further details. diff --git a/src/quick/handlers/handlers.pri b/src/quick/handlers/handlers.pri index 9e32b9278c..8bd74d95da 100644 --- a/src/quick/handlers/handlers.pri +++ b/src/quick/handlers/handlers.pri @@ -5,6 +5,7 @@ HEADERS += \ $$PWD/qquickpinchhandler_p.h \ $$PWD/qquickpointerdevicehandler_p.h \ $$PWD/qquickpointerhandler_p.h \ + $$PWD/qquickpointhandler_p.h \ $$PWD/qquicksinglepointhandler_p.h \ $$PWD/qquicktaphandler_p.h \ @@ -15,6 +16,7 @@ SOURCES += \ $$PWD/qquickpinchhandler.cpp \ $$PWD/qquickpointerdevicehandler.cpp \ $$PWD/qquickpointerhandler.cpp \ + $$PWD/qquickpointhandler.cpp \ $$PWD/qquicksinglepointhandler.cpp \ $$PWD/qquicktaphandler.cpp \ diff --git a/src/quick/handlers/qquickdraghandler.cpp b/src/quick/handlers/qquickdraghandler.cpp index 12f1a29bca..041780257a 100644 --- a/src/quick/handlers/qquickdraghandler.cpp +++ b/src/quick/handlers/qquickdraghandler.cpp @@ -53,20 +53,21 @@ QT_BEGIN_NAMESPACE DragHandler is a handler that is used to interactively move an Item. Like other Pointer Handlers, by default it is fully functional, and - manipulates its \l target. + manipulates its \l {PointerHandler::target} {target}. \snippet pointerHandlers/dragHandler.qml 0 It has properties to restrict the range of dragging. - If it is declared within one Item but is assigned a different \l target, - then it handles events within the bounds of the \l parent Item but + If it is declared within one Item but is assigned a different + \l {PointerHandler::target} {target}, then it handles events within the + bounds of the \l {PointerHandler::parent} {parent} Item but manipulates the \c target Item instead: \snippet pointerHandlers/dragHandlerDifferentTarget.qml 0 - A third way to use it is to set \l target to \c null and react to property - changes in some other way: + A third way to use it is to set \l {PointerHandler::target} {target} to + \c null and react to property changes in some other way: \snippet pointerHandlers/dragHandlerNullTarget.qml 0 @@ -91,19 +92,44 @@ bool QQuickDragHandler::wantsEventPoint(QQuickEventPoint *point) || QQuickSinglePointHandler::wantsEventPoint(point)); } +bool QQuickDragHandler::targetContains(QQuickEventPoint *point) +{ + Q_ASSERT(parentItem() && target()); + return target()->contains(localTargetPosition(point)); +} + +QPointF QQuickDragHandler::localTargetPosition(QQuickEventPoint *point) +{ + QPointF pos = point->position(); + if (target() != parentItem()) + pos = parentItem()->mapToItem(target(), pos); + return pos; +} + void QQuickDragHandler::onGrabChanged(QQuickPointerHandler *grabber, QQuickEventPoint::GrabState stateChange, QQuickEventPoint *point) { - if (grabber == this && stateChange == QQuickEventPoint::GrabExclusive) - // In case the grab got handled over from another grabber, we might not get the Press - initializeTargetStartPos(point); - enforceConstraints(); + if (grabber == this && stateChange == QQuickEventPoint::GrabExclusive) { + // In case the grab got handed over from another grabber, we might not get the Press. + if (!m_pressedInsideTarget) { + if (target()) + m_pressTargetPos = QPointF(target()->width(), target()->height()) / 2; + m_pressScenePos = point->scenePosition(); + } else if (m_pressTargetPos.isNull()) { + if (target()) + m_pressTargetPos = localTargetPosition(point); + m_pressScenePos = point->scenePosition(); + } + } QQuickSinglePointHandler::onGrabChanged(grabber, stateChange, point); } void QQuickDragHandler::onActiveChanged() { - if (!active()) - m_targetStartPos = QPointF(); + if (!active()) { + m_pressTargetPos = QPointF(); + m_pressScenePos = m_pressTargetPos; + m_pressedInsideTarget = false; + } } void QQuickDragHandler::handleEventPoint(QQuickEventPoint *point) @@ -111,25 +137,40 @@ void QQuickDragHandler::handleEventPoint(QQuickEventPoint *point) point->setAccepted(); switch (point->state()) { case QQuickEventPoint::Pressed: - initializeTargetStartPos(point); + if (target()) { + m_pressedInsideTarget = targetContains(point); + m_pressTargetPos = localTargetPosition(point); + } + m_pressScenePos = point->scenePosition(); setPassiveGrab(point); break; case QQuickEventPoint::Updated: { - QPointF delta = point->scenePosition() - point->scenePressPosition(); - if (!m_xAxis.enabled()) - delta.setX(0); - if (!m_yAxis.enabled()) - delta.setY(0); + QVector2D accumulatedDragDelta = QVector2D(point->scenePosition() - m_pressScenePos); if (active()) { - setTranslation(QVector2D(delta)); + // update translation property. Make sure axis is respected for it. + if (!m_xAxis.enabled()) + accumulatedDragDelta.setX(0); + if (!m_yAxis.enabled()) + accumulatedDragDelta.setY(0); + setTranslation(accumulatedDragDelta); + if (target() && target()->parentItem()) { - QPointF pos = target()->parentItem()->mapFromScene(m_targetStartPos + delta); + const QPointF newTargetTopLeft = localTargetPosition(point) - m_pressTargetPos; + const QPointF xformOrigin = target()->transformOriginPoint(); + const QPointF targetXformOrigin = newTargetTopLeft + xformOrigin; + QPointF pos = target()->parentItem()->mapFromItem(target(), targetXformOrigin); + pos -= xformOrigin; + QPointF targetItemPos = target()->position(); + if (!m_xAxis.enabled()) + pos.setX(targetItemPos.x()); + if (!m_yAxis.enabled()) + pos.setY(targetItemPos.y()); enforceAxisConstraints(&pos); moveTarget(pos, point); } } else if (!point->exclusiveGrabber() && - ((m_xAxis.enabled() && QQuickWindowPrivate::dragOverThreshold(delta.x(), Qt::XAxis, point)) || - (m_yAxis.enabled() && QQuickWindowPrivate::dragOverThreshold(delta.y(), Qt::YAxis, point)))) { + ((m_xAxis.enabled() && QQuickWindowPrivate::dragOverThreshold(accumulatedDragDelta.x(), Qt::XAxis, point)) || + (m_yAxis.enabled() && QQuickWindowPrivate::dragOverThreshold(accumulatedDragDelta.y(), Qt::YAxis, point)))) { setExclusiveGrab(point); if (auto parent = parentItem()) { if (point->pointerEvent()->asPointerTouchEvent()) @@ -165,23 +206,6 @@ void QQuickDragHandler::enforceAxisConstraints(QPointF *localPos) localPos->setY(qBound(m_yAxis.minimum(), localPos->y(), m_yAxis.maximum())); } -void QQuickDragHandler::initializeTargetStartPos(QQuickEventPoint *point) -{ - if (target() && target()->parentItem() && m_targetStartPos.isNull()) { // prefer the m_targetStartPos we got when it got Pressed. - m_targetStartPos = target()->parentItem()->mapToScene(target()->position()); - if (!target()->contains(point->position())) { - // If pressed outside of target item, move the target item so that the touchpoint is in its center, - // while still respecting the axis constraints. - const QPointF center = target()->parentItem()->mapFromScene(point->scenePosition()); - const QPointF pointCenteredInItemPos = target()->parentItem()->mapToScene(center - QPointF(target()->width(), target()->height())/2); - if (m_xAxis.enabled()) - m_targetStartPos.setX(pointCenteredInItemPos.x()); - if (m_yAxis.enabled()) - m_targetStartPos.setY(pointCenteredInItemPos.y()); - } - } -} - void QQuickDragHandler::setTranslation(const QVector2D &trans) { if (trans == m_translation) // fuzzy compare? @@ -192,23 +216,33 @@ void QQuickDragHandler::setTranslation(const QVector2D &trans) /*! \qmlpropertygroup QtQuick::DragHandler::xAxis + \qmlproperty real QtQuick::DragHandler::xAxis.minimum + \qmlproperty real QtQuick::DragHandler::xAxis.maximum + \qmlproperty bool QtQuick::DragHandler::xAxis.enabled + + \c xAxis controls the constraints for horizontal dragging. + + \c minimum is the minimum acceptable value of \l {Item::x}{x} to be + applied to the \l {PointerHandler::target} {target}. + \c maximum is the maximum acceptable value of \l {Item::x}{x} to be + applied to the \l {PointerHandler::target} {target}. + If \c enabled is true, horizontal dragging is allowed. + */ + +/*! \qmlpropertygroup QtQuick::DragHandler::yAxis - \qmlproperty real QtQuick::DragHandler::DragAxis::minimum - \qmlproperty real QtQuick::DragHandler::DragAxis::maximum - \qmlproperty real QtQuick::DragHandler::DragAxis::enabled - - \c xAxis and yAxis control the constraints for horizontal and vertical - dragging, respectively. - - \value minimum - The minimum acceptable value of \l {Item::x}{x} or \l {Item::y}{y} - to be applied to the \l target - \value maximum - The maximum acceptable value of \l {Item::x}{x} or \l {Item::y}{y} - to be applied to the \l target - \value enabled - Whether dragging in this direction is allowed at all -*/ + \qmlproperty real QtQuick::DragHandler::yAxis.minimum + \qmlproperty real QtQuick::DragHandler::yAxis.maximum + \qmlproperty bool QtQuick::DragHandler::yAxis.enabled + + \c yAxis controls the constraints for vertical dragging. + + \c minimum is the minimum acceptable value of \l {Item::y}{y} to be + applied to the \l {PointerHandler::target} {target}. + \c maximum is the maximum acceptable value of \l {Item::y}{y} to be + applied to the \l {PointerHandler::target} {target}. + If \c enabled is true, vertical dragging is allowed. + */ QQuickDragAxis::QQuickDragAxis() : m_minimum(-DBL_MAX) , m_maximum(DBL_MAX) diff --git a/src/quick/handlers/qquickdraghandler_p.h b/src/quick/handlers/qquickdraghandler_p.h index d10084c654..363df31a64 100644 --- a/src/quick/handlers/qquickdraghandler_p.h +++ b/src/quick/handlers/qquickdraghandler_p.h @@ -93,7 +93,7 @@ class Q_AUTOTEST_EXPORT QQuickDragHandler : public QQuickSinglePointHandler Q_PROPERTY(QVector2D translation READ translation NOTIFY translationChanged) public: - explicit QQuickDragHandler(QObject *parent = 0); + explicit QQuickDragHandler(QObject *parent = nullptr); ~QQuickDragHandler(); void handleEventPoint(QQuickEventPoint *point) override; @@ -118,13 +118,19 @@ protected: private: void ungrab(); void enforceAxisConstraints(QPointF *localPos); - void initializeTargetStartPos(QQuickEventPoint *point); + bool targetContains(QQuickEventPoint *point); + QPointF localTargetPosition(QQuickEventPoint *point); private: - QPointF m_targetStartPos; + QPointF m_pressScenePos; + QPointF m_pressTargetPos; // We must also store the local targetPos, because we cannot deduce + // the press target pos from the scene pos in case there was e.g a + // flick in one of the ancestors during the drag. QVector2D m_translation; + QQuickDragAxis m_xAxis; QQuickDragAxis m_yAxis; + bool m_pressedInsideTarget = false; friend class QQuickDragAxis; }; diff --git a/src/quick/handlers/qquickhandlersmodule.cpp b/src/quick/handlers/qquickhandlersmodule.cpp index 8472c6a062..c9e08fe4f2 100644 --- a/src/quick/handlers/qquickhandlersmodule.cpp +++ b/src/quick/handlers/qquickhandlersmodule.cpp @@ -41,6 +41,7 @@ #include "qquickpointerhandler_p.h" #include "qquickdraghandler_p.h" #include "qquickpinchhandler_p.h" +#include "qquickpointhandler_p.h" #include "qquicktaphandler_p.h" static void initResources() @@ -82,6 +83,7 @@ static void qt_quickhandlers_defineModule(const char *uri, int major, int minor) qmlRegisterUncreatableType<QQuickPointerHandler>(uri,major,minor,"PointerHandler", QQuickPointerHandler::tr("PointerHandler is an abstract base class")); + qmlRegisterType<QQuickPointHandler>(uri,major,minor,"PointHandler"); qmlRegisterType<QQuickDragHandler>(uri,major,minor,"DragHandler"); qmlRegisterUncreatableType<QQuickDragAxis>(uri, major, minor, "DragAxis", QQuickDragHandler::tr("DragAxis is only available as a grouped property of DragHandler")); diff --git a/src/quick/handlers/qquickmultipointhandler.cpp b/src/quick/handlers/qquickmultipointhandler.cpp index ff4914394c..b126b93211 100644 --- a/src/quick/handlers/qquickmultipointhandler.cpp +++ b/src/quick/handlers/qquickmultipointhandler.cpp @@ -298,17 +298,18 @@ void QQuickMultiPointHandler::acceptPoints(const QVector<QQuickEventPoint *> &po bool QQuickMultiPointHandler::grabPoints(QVector<QQuickEventPoint *> points) { - bool canGrab = true; + bool allowed = true; for (QQuickEventPoint* point : points) { - auto grabber = point->grabberItem(); - if (grabber && (grabber->keepMouseGrab() || grabber->keepTouchGrab())) - canGrab = false; + if (!canGrab(point)) { + allowed = false; + break; + } } - if (canGrab) { + if (allowed) { for (QQuickEventPoint* point : points) setExclusiveGrab(point); } - return canGrab; + return allowed; } QT_END_NAMESPACE diff --git a/src/quick/handlers/qquickmultipointhandler_p.h b/src/quick/handlers/qquickmultipointhandler_p.h index 05c3876246..67e550d387 100644 --- a/src/quick/handlers/qquickmultipointhandler_p.h +++ b/src/quick/handlers/qquickmultipointhandler_p.h @@ -65,7 +65,7 @@ class Q_AUTOTEST_EXPORT QQuickMultiPointHandler : public QQuickPointerDeviceHand Q_PROPERTY(qreal pointDistanceThreshold READ pointDistanceThreshold WRITE setPointDistanceThreshold NOTIFY pointDistanceThresholdChanged) public: - explicit QQuickMultiPointHandler(QObject *parent = 0, int minimumPointCount = 2); + explicit QQuickMultiPointHandler(QObject *parent = nullptr, int minimumPointCount = 2); ~QQuickMultiPointHandler(); int minimumPointCount() const { return m_minimumPointCount; } diff --git a/src/quick/handlers/qquickpinchhandler.cpp b/src/quick/handlers/qquickpinchhandler.cpp index 84c4e912d1..155822197f 100644 --- a/src/quick/handlers/qquickpinchhandler.cpp +++ b/src/quick/handlers/qquickpinchhandler.cpp @@ -248,8 +248,8 @@ bool QQuickPinchHandler::wantsPointerEvent(QQuickPointerEvent *event) if (!QQuickMultiPointHandler::wantsPointerEvent(event)) return false; - if (minimumPointCount() == 2) { - if (const auto gesture = event->asPointerNativeGestureEvent()) { + if (const auto gesture = event->asPointerNativeGestureEvent()) { + if (minimumPointCount() == 2) { switch (gesture->type()) { case Qt::BeginNativeGesture: case Qt::EndNativeGesture: @@ -259,6 +259,8 @@ bool QQuickPinchHandler::wantsPointerEvent(QQuickPointerEvent *event) default: return false; } + } else { + return false; } } @@ -349,13 +351,18 @@ void QQuickPinchHandler::handlePointerEventImpl(QQuickPointerEvent *event) } } else { bool containsReleasedPoints = event->isReleaseEvent(); - if (!active() && !containsReleasedPoints) { + if (!active()) { // Verify that at least one of the points has moved beyond threshold needed to activate the handler for (QQuickEventPoint *point : qAsConst(m_currentPoints)) { - if (QQuickWindowPrivate::dragOverThreshold(point)) { - if (grabPoints(m_currentPoints)) - setActive(true); + if (!containsReleasedPoints && QQuickWindowPrivate::dragOverThreshold(point) && grabPoints(m_currentPoints)) { + setActive(true); break; + } else { + setPassiveGrab(point); + } + if (point->state() == QQuickEventPoint::Pressed) { + point->setAccepted(false); // don't stop propagation + setPassiveGrab(point); } } if (!active()) diff --git a/src/quick/handlers/qquickpinchhandler_p.h b/src/quick/handlers/qquickpinchhandler_p.h index 7d6b7d9509..9a17971416 100644 --- a/src/quick/handlers/qquickpinchhandler_p.h +++ b/src/quick/handlers/qquickpinchhandler_p.h @@ -82,7 +82,7 @@ public: }; Q_ENUM(PinchOrigin) - explicit QQuickPinchHandler(QObject *parent = 0); + explicit QQuickPinchHandler(QObject *parent = nullptr); ~QQuickPinchHandler(); qreal minimumScale() const { return m_minimumScale; } diff --git a/src/quick/handlers/qquickpointerdevicehandler.cpp b/src/quick/handlers/qquickpointerdevicehandler.cpp index 1521b58d57..06831613b6 100644 --- a/src/quick/handlers/qquickpointerdevicehandler.cpp +++ b/src/quick/handlers/qquickpointerdevicehandler.cpp @@ -75,7 +75,8 @@ QQuickPointerDeviceHandler::~QQuickPointerDeviceHandler() The types of pointing devices that can activate this Pointer Handler. - By default, this property is set to \l PointerDevice.AllDevices. + By default, this property is set to + \l{QtQuick::PointerDevice::type} {PointerDevice.AllDevices}. If you set it to an OR combination of device types, it will ignore events from non-matching devices. @@ -110,7 +111,8 @@ void QQuickPointerDeviceHandler::setAcceptedDevices(QQuickPointerDevice::DeviceT The types of pointing instruments (finger, stylus, eraser, etc.) that can activate this Pointer Handler. - By default, this property is set to \l PointerDevice.AllPointerTypes. + By default, this property is set to + \l {QtQuick::PointerDevice::pointerType} {PointerDevice.AllPointerTypes}. If you set it to an OR combination of device types, it will ignore events from non-matching events. diff --git a/src/quick/handlers/qquickpointerdevicehandler_p.h b/src/quick/handlers/qquickpointerdevicehandler_p.h index 9e30fa0be4..1638604ea7 100644 --- a/src/quick/handlers/qquickpointerdevicehandler_p.h +++ b/src/quick/handlers/qquickpointerdevicehandler_p.h @@ -63,7 +63,7 @@ class Q_AUTOTEST_EXPORT QQuickPointerDeviceHandler : public QQuickPointerHandler Q_PROPERTY(Qt::KeyboardModifiers acceptedModifiers READ acceptedModifiers WRITE setAcceptedModifiers NOTIFY acceptedModifiersChanged) public: - explicit QQuickPointerDeviceHandler(QObject *parent = 0); + explicit QQuickPointerDeviceHandler(QObject *parent = nullptr); ~QQuickPointerDeviceHandler(); QQuickPointerDevice::DeviceTypes acceptedDevices() const { return m_acceptedDevices; } diff --git a/src/quick/handlers/qquickpointerhandler.cpp b/src/quick/handlers/qquickpointerhandler.cpp index faebdf3621..959030b8fe 100644 --- a/src/quick/handlers/qquickpointerhandler.cpp +++ b/src/quick/handlers/qquickpointerhandler.cpp @@ -42,6 +42,7 @@ QT_BEGIN_NAMESPACE Q_LOGGING_CATEGORY(lcPointerHandlerDispatch, "qt.quick.handler.dispatch") +Q_LOGGING_CATEGORY(lcPointerHandlerGrab, "qt.quick.handler.grab") Q_LOGGING_CATEGORY(lcPointerHandlerActive, "qt.quick.handler.active") /*! @@ -67,6 +68,7 @@ QQuickPointerHandler::QQuickPointerHandler(QObject *parent) , m_targetExplicitlySet(false) , m_hadKeepMouseGrab(false) , m_hadKeepTouchGrab(false) + , m_grabPermissions(CanTakeOverFromItems | CanTakeOverFromHandlersOfDifferentType | ApprovesTakeOverByAnything) { } @@ -94,7 +96,7 @@ QQuickPointerHandler::~QQuickPointerHandler() */ void QQuickPointerHandler::onGrabChanged(QQuickPointerHandler *grabber, QQuickEventPoint::GrabState stateChange, QQuickEventPoint *point) { - qCDebug(lcPointerHandlerDispatch) << point << stateChange << grabber; + qCDebug(lcPointerHandlerGrab) << point << stateChange << grabber; Q_ASSERT(point); if (grabber == this) { bool wasCanceled = false; @@ -145,7 +147,7 @@ void QQuickPointerHandler::onGrabChanged(QQuickPointerHandler *grabber, QQuickEv */ void QQuickPointerHandler::setPassiveGrab(QQuickEventPoint *point, bool grab) { - qCDebug(lcPointerHandlerDispatch) << point << grab; + qCDebug(lcPointerHandlerGrab) << point << grab; if (grab) { point->setGrabberPointerHandler(this, false); } else { @@ -153,14 +155,124 @@ void QQuickPointerHandler::setPassiveGrab(QQuickEventPoint *point, bool grab) } } -void QQuickPointerHandler::setExclusiveGrab(QQuickEventPoint *point, bool grab) +/*! + Check whether it's OK to take an exclusive grab of the \a point. + + The default implementation will call approveGrabTransition() to check this + handler's \l grabPermissions. If grabbing can be done only by taking over + the exclusive grab from an Item, approveGrabTransition() checks the Item's + \l keepMouseGrab or \l keepTouchGrab flags appropriately. If grabbing can + be done only by taking over another handler's exclusive grab, canGrab() + also calls approveGrabTransition() on the handler which is about to lose + its grab. Either one can deny the takeover. +*/ +bool QQuickPointerHandler::canGrab(QQuickEventPoint *point) { - // TODO m_hadKeepMouseGrab m_hadKeepTouchGrab - qCDebug(lcPointerHandlerDispatch) << point << grab; - // Don't allow one handler to cancel another's grab, unless it is stealing it for itself - if (!grab && point->grabberPointerHandler() != this) + QQuickPointerHandler *existingPhGrabber = point->grabberPointerHandler(); + return approveGrabTransition(point, this) && + (existingPhGrabber ? existingPhGrabber->approveGrabTransition(point, this) : true); +} + +/*! + Check this handler's rules to see if \l proposedGrabber will be allowed to take + the exclusive grab. This function may be called twice: once on the instance which + will take the grab, and once on the instance which would thereby lose its grab, + in case of a takeover scenario. +*/ +bool QQuickPointerHandler::approveGrabTransition(QQuickEventPoint *point, QObject *proposedGrabber) +{ + bool allowed = false; + if (proposedGrabber == this) { + QObject* existingGrabber = point->exclusiveGrabber(); + allowed = (existingGrabber == nullptr) || ((m_grabPermissions & CanTakeOverFromAnything) == CanTakeOverFromAnything); + if (existingGrabber) { + if (QQuickPointerHandler *existingPhGrabber = point->grabberPointerHandler()) { + if (!allowed && (m_grabPermissions & CanTakeOverFromHandlersOfDifferentType) && + existingPhGrabber->metaObject()->className() != metaObject()->className()) + allowed = true; + if (!allowed && (m_grabPermissions & CanTakeOverFromHandlersOfSameType) && + existingPhGrabber->metaObject()->className() == metaObject()->className()) + allowed = true; + } else if ((m_grabPermissions & CanTakeOverFromItems)) { + QQuickItem * existingItemGrabber = point->grabberItem(); + if (existingItemGrabber && !((existingItemGrabber->keepMouseGrab() && point->pointerEvent()->asPointerMouseEvent()) || + (existingItemGrabber->keepTouchGrab() && point->pointerEvent()->asPointerTouchEvent()))) + allowed = true; + } + } + } else { + // proposedGrabber is different: that means this instance will lose its grab + if (proposedGrabber) { + if ((m_grabPermissions & ApprovesTakeOverByAnything) == ApprovesTakeOverByAnything) + allowed = true; + if (!allowed && (m_grabPermissions & ApprovesTakeOverByHandlersOfDifferentType) && + proposedGrabber->metaObject()->className() != metaObject()->className()) + allowed = true; + if (!allowed && (m_grabPermissions & ApprovesTakeOverByHandlersOfSameType) && + proposedGrabber->metaObject()->className() == metaObject()->className()) + allowed = true; + if (!allowed && (m_grabPermissions & ApprovesTakeOverByItems) && proposedGrabber->inherits("QQuickItem")) + allowed = true; + } else { + if (!allowed && (m_grabPermissions & ApprovesCancellation)) + allowed = true; + } + } + qCDebug(lcPointerHandlerGrab) << "point" << hex << point->pointId() << "permission" << + QMetaEnum::fromType<GrabPermissions>().valueToKeys(grabPermissions()) << + ':' << this << (allowed ? "approved to" : "denied to") << proposedGrabber; + return allowed; +} + +/*! + \qmlproperty bool QtQuick::PointerHandler::grabPermission + + This property specifies the permissions when this handler's logic decides + to take over the exclusive grab, or when it is asked to approve grab + takeover or cancellation by another handler. + + The default is + \c {CanTakeOverFromItems | CanTakeOverFromHandlersOfDifferentType | ApprovesTakeOverByAnything} + which allows most takeover scenarios but avoids e.g. two PinchHandlers fighting + over the same touchpoints. +*/ +void QQuickPointerHandler::setGrabPermissions(GrabPermissions grabPermission) +{ + if (m_grabPermissions == grabPermission) return; - point->setGrabberPointerHandler(grab ? this : nullptr, true); + + m_grabPermissions = grabPermission; + emit grabPermissionChanged(); +} + +/*! + \internal + Acquire or give up the exclusive grab of the given \a point, according to + the \a grab state, and subject to the rules: canGrab(), and the rule not to + relinquish another handler's grab. Returns true if permission is granted, + or if the exclusive grab has already been acquired or relinquished as + specified. Returns false if permission is denied either by this handler or + by the handler or item from which this handler would take over +*/ +bool QQuickPointerHandler::setExclusiveGrab(QQuickEventPoint *point, bool grab) +{ + if ((grab && point->exclusiveGrabber() == this) || (!grab && point->exclusiveGrabber() != this)) + return true; + // TODO m_hadKeepMouseGrab m_hadKeepTouchGrab + bool allowed = true; + if (grab) { + allowed = canGrab(point); + } else { + QQuickPointerHandler *existingPhGrabber = point->grabberPointerHandler(); + // Ask before allowing one handler to cancel another's grab + if (existingPhGrabber && existingPhGrabber != this && !existingPhGrabber->approveGrabTransition(point, nullptr)) + allowed = false; + } + qCDebug(lcPointerHandlerGrab) << point << (grab ? "grab" : "ungrab") << (allowed ? "allowed" : "forbidden") << + point->exclusiveGrabber() << "->" << (grab ? this : nullptr); + if (allowed) + point->setGrabberPointerHandler(grab ? this : nullptr, true); + return allowed; } /*! @@ -169,7 +281,7 @@ void QQuickPointerHandler::setExclusiveGrab(QQuickEventPoint *point, bool grab) */ void QQuickPointerHandler::cancelAllGrabs(QQuickEventPoint *point) { - qCDebug(lcPointerHandlerDispatch) << point; + qCDebug(lcPointerHandlerGrab) << point; point->cancelAllGrabs(this); } @@ -207,7 +319,7 @@ void QQuickPointerHandler::setEnabled(bool enabled) The Item which this handler will manipulate. - By default, it is the same as the \l parent: the Item within which + By default, it is the same as the \l [QML] {parent}, the Item within which the handler is declared. However, it can sometimes be useful to set the target to a different Item, in order to handle events within one item but manipulate another; or to \c null, to disable the default behavior @@ -219,7 +331,9 @@ void QQuickPointerHandler::setTarget(QQuickItem *target) if (m_target == target) return; + QQuickItem *oldTarget = m_target; m_target = target; + onTargetChanged(oldTarget); emit targetChanged(); } @@ -288,10 +402,10 @@ void QQuickPointerHandler::handlePointerEventImpl(QQuickPointerEvent *event) The \l Item which is the scope of the handler; the Item in which it was declared. The handler will handle events on behalf of this Item, which means a pointer event is relevant if at least one of its event points occurs within - the Item's interior. Initially \l target() is the same, but target() + the Item's interior. Initially \l [QML] {target} {target()} is the same, but it can be reassigned. - \sa QQuick::PointerHandler::target(), QObject::parent() + \sa {target}, QObject::parent() */ /*! diff --git a/src/quick/handlers/qquickpointerhandler_p.h b/src/quick/handlers/qquickpointerhandler_p.h index 24a058275d..9ea6a8b5e2 100644 --- a/src/quick/handlers/qquickpointerhandler_p.h +++ b/src/quick/handlers/qquickpointerhandler_p.h @@ -60,18 +60,36 @@ QT_BEGIN_NAMESPACE Q_DECLARE_LOGGING_CATEGORY(lcPointerHandlerDispatch) -class Q_QUICK_PRIVATE_EXPORT QQuickPointerHandler : public QObject +class Q_QUICK_PRIVATE_EXPORT QQuickPointerHandler : public QObject, public QQmlParserStatus { Q_OBJECT + Q_INTERFACES(QQmlParserStatus) + Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged) Q_PROPERTY(bool active READ active NOTIFY activeChanged) Q_PROPERTY(QQuickItem * target READ target WRITE setTarget NOTIFY targetChanged) Q_PROPERTY(QQuickItem * parent READ parentItem CONSTANT) + Q_PROPERTY(GrabPermissions grabPermissions READ grabPermissions WRITE setGrabPermissions NOTIFY grabPermissionChanged) public: - explicit QQuickPointerHandler(QObject *parent = 0); + explicit QQuickPointerHandler(QObject *parent = nullptr); virtual ~QQuickPointerHandler(); + enum GrabPermission { + TakeOverForbidden = 0x0, + CanTakeOverFromHandlersOfSameType = 0x01, + CanTakeOverFromHandlersOfDifferentType= 0x02, + CanTakeOverFromItems = 0x04, + CanTakeOverFromAnything = 0x0F, + ApprovesTakeOverByHandlersOfSameType = 0x10, + ApprovesTakeOverByHandlersOfDifferentType= 0x20, + ApprovesTakeOverByItems = 0x40, + ApprovesCancellation = 0x80, + ApprovesTakeOverByAnything = 0xF0 + }; + Q_DECLARE_FLAGS(GrabPermissions, GrabPermission) + Q_FLAG(GrabPermissions) + public: bool enabled() const { return m_enabled; } void setEnabled(bool enabled); @@ -85,11 +103,18 @@ public: void handlePointerEvent(QQuickPointerEvent *event); + GrabPermissions grabPermissions() const { return static_cast<GrabPermissions>(m_grabPermissions); } + void setGrabPermissions(GrabPermissions grabPermissions); + + void classBegin() override { } + void componentComplete() override { } + Q_SIGNALS: void enabledChanged(); void activeChanged(); void targetChanged(); void grabChanged(QQuickEventPoint *point); + void grabPermissionChanged(); void canceled(QQuickEventPoint *point); protected: @@ -97,10 +122,13 @@ protected: virtual bool wantsPointerEvent(QQuickPointerEvent *event); virtual void handlePointerEventImpl(QQuickPointerEvent *event); void setActive(bool active); + virtual void onTargetChanged(QQuickItem *oldTarget) { Q_UNUSED(oldTarget); } virtual void onActiveChanged() { } virtual void onGrabChanged(QQuickPointerHandler *grabber, QQuickEventPoint::GrabState stateChange, QQuickEventPoint *point); + virtual bool canGrab(QQuickEventPoint *point); + virtual bool approveGrabTransition(QQuickEventPoint *point, QObject *proposedGrabber); void setPassiveGrab(QQuickEventPoint *point, bool grab = true); - void setExclusiveGrab(QQuickEventPoint *point, bool grab = true); + bool setExclusiveGrab(QQuickEventPoint *point, bool grab = true); void cancelAllGrabs(QQuickEventPoint *point); QPointF eventPos(const QQuickEventPoint *point) const; bool parentContains(const QQuickEventPoint *point) const; @@ -113,11 +141,15 @@ private: bool m_targetExplicitlySet : 1; bool m_hadKeepMouseGrab : 1; // some handlers override target()->setKeepMouseGrab(); this remembers previous state bool m_hadKeepTouchGrab : 1; // some handlers override target()->setKeepTouchGrab(); this remembers previous state + uint m_reserved : 19; + uint8_t m_grabPermissions : 8; friend class QQuickEventPoint; friend class QQuickWindowPrivate; }; +Q_DECLARE_OPERATORS_FOR_FLAGS(QQuickPointerHandler::GrabPermissions) + QT_END_NAMESPACE QML_DECLARE_TYPE(QQuickPointerHandler) diff --git a/src/quick/handlers/qquickpointhandler.cpp b/src/quick/handlers/qquickpointhandler.cpp new file mode 100644 index 0000000000..7e2d40452c --- /dev/null +++ b/src/quick/handlers/qquickpointhandler.cpp @@ -0,0 +1,164 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickpointhandler_p.h" +#include <private/qquickwindow_p.h> +#include <QDebug> + +QT_BEGIN_NAMESPACE + +/*! + \qmltype PointHandler + \instantiates QQuickPointHandler + \inherits SinglePointHandler + \inqmlmodule Qt.labs.handlers + \ingroup qtquick-handlers + \brief Handler for reacting to a single touchpoint. + + PointHandler can be used to show feedback about a touchpoint or the mouse + position, or to otherwise react to pointer events. + + When a press event occurs, each instance of PointHandler chooses a + single point which is not yet "taken" at that moment: if the press + occurs within the bounds of the \l {PointerHandler::parent}, and + no sibling PointHandler within the same \l {PointerHandler::parent} + has yet acquired a passive grab on that point, and if the other + constraints such as \l {SinglePointHandler::acceptedButtons}, + \l {PointerDeviceHandler::acceptedDevices} etc. are satisfied, it's + eligible, and the PointHandler then acquires a passive grab. In + this way, the \l {PointerHandler::parent} acts like an exclusive + group: there can be multiple instances of PointHandler, and the + set of pressed touchpoints will be distributed among them. Each + PointHandler which has chosen a point to track has its \l active + property \c true. It then continues to track its chosen point + until release: the properties of the \l point will be kept + up-to-date. Any Item can bind to these properties, and thereby + follow the point's movements. + + By being only a passive grabber, it has the ability to keep independent + oversight of all movements. The passive grab cannot be stolen or overridden + even when other gestures are detected and exclusive grabs occur. + + If your goal is orthogonal surveillance of eventpoints, an older + alternative was QObject::installEventFilter(), but that has never been a + built-in QtQuick feature: it requires some C++ code, such as a QQuickItem + subclass. PointHandler is more efficient than that, because only pointer + events will be delivered to it, during the course of normal event delivery + in QQuickWindow; whereas an event filter needs to filter all QEvents of all + types, and thus sets itself up as a potential event delivery bottleneck. + + One possible use case is to add this handler to a transparent Item which is + on top of the rest of the scene (by having a high \l{Item::z} {z} value), + so that when a point is freshly pressed, it will be delivered to that Item + and its handlers first, providing the opportunity to take the passive grab + as early as possible. Such an item (like a pane of glass over the whole UI) + can be a convenient parent for other Items which visualize the kind of reactive + feedback which must always be on top; and likewise it can be the parent for + popups, popovers, dialogs and so on. If it will be used in that way, it can + be helpful for your main.cpp to use QQmlContext::setContextProperty() to + make the "glass pane" accessible by ID to the entire UI, so that other + Items and PointHandlers can be reparented to it. + + \snippet pointerHandlers/pointHandler.qml 0 + + Like all pointer handlers, a PointHandler has a \l target property, which + may be used as a convenient place to put a point-tracking Item; but + PointHandler will not automatically manipulate the \c target item in any way. + You need to use bindings to make it react to the \l point. + + \note On macOS, PointHandler does not react to the trackpad by default. + That is because macOS can provide either native gesture recognition, or raw + touchpoints, but not both. We prefer to use the native gesture event in + PinchHandler, so we do not want to disable it by enabling touch. However + MultiPointTouchArea does enable touch, thus disabling native gesture + recognition within the entire window; so it's an alternative if you only + want to react to all the touchpoints but do not require the smooth + native-gesture experience. + + \sa MultiPointTouchArea +*/ + +QQuickPointHandler::QQuickPointHandler(QObject *parent) + : QQuickSinglePointHandler(parent) +{ + setIgnoreAdditionalPoints(); +} + +QQuickPointHandler::~QQuickPointHandler() +{ +} + +bool QQuickPointHandler::wantsEventPoint(QQuickEventPoint *pt) +{ + // On press, we want it unless a sibling of the same type also does. + if (pt->state() == QQuickEventPoint::Pressed && QQuickSinglePointHandler::wantsEventPoint(pt)) { + for (const QQuickPointerHandler *grabber : pt->passiveGrabbers()) { + if (grabber && grabber->parent() == parent() && + grabber->metaObject()->className() == metaObject()->className()) + return false; + } + return true; + } + // If we've already been interested in a point, stay interested, even if it has strayed outside bounds. + return (pt->state() != QQuickEventPoint::Pressed && point().id() == pt->pointId()); +} + +void QQuickPointHandler::handleEventPoint(QQuickEventPoint *point) +{ + switch (point->state()) { + case QQuickEventPoint::Pressed: + setPassiveGrab(point); + setActive(true); + break; + case QQuickEventPoint::Released: + setActive(false); + break; + default: + break; + } + point->setAccepted(false); // Just lurking... don't interfere with propagation + emit translationChanged(); +} + +QVector2D QQuickPointHandler::translation() const +{ + return QVector2D(point().position() - point().pressPosition()); +} + +QT_END_NAMESPACE diff --git a/src/quick/handlers/qquickpointhandler_p.h b/src/quick/handlers/qquickpointhandler_p.h new file mode 100644 index 0000000000..5babab0c4d --- /dev/null +++ b/src/quick/handlers/qquickpointhandler_p.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKPONTHANDLER_H +#define QQUICKPONTHANDLER_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qquicksinglepointhandler_p.h" + +QT_BEGIN_NAMESPACE + +class Q_AUTOTEST_EXPORT QQuickPointHandler : public QQuickSinglePointHandler +{ + Q_OBJECT + Q_PROPERTY(QVector2D translation READ translation NOTIFY translationChanged) + +public: + explicit QQuickPointHandler(QObject *parent = 0); + ~QQuickPointHandler(); + + QVector2D translation() const; + +Q_SIGNALS: + void translationChanged(); + +protected: + bool wantsEventPoint(QQuickEventPoint *pt) override; + void handleEventPoint(QQuickEventPoint *point) override; +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickPointHandler) + +#endif // QQUICKPONTHANDLER_H diff --git a/src/quick/handlers/qquicksinglepointhandler.cpp b/src/quick/handlers/qquicksinglepointhandler.cpp index dee168a8e4..1a5537b732 100644 --- a/src/quick/handlers/qquicksinglepointhandler.cpp +++ b/src/quick/handlers/qquicksinglepointhandler.cpp @@ -217,7 +217,7 @@ void QQuickSinglePointHandler::moveTarget(QPointF pos, QQuickEventPoint *point) The mouse buttons which can activate this Pointer Handler. - By default, this property is set to \l Qt.LeftButton. + By default, this property is set to \l {QtQuick::MouseEvent::button} {Qt.LeftButton}. It can be set to an OR combination of mouse buttons, and will ignore events from other buttons. @@ -360,7 +360,8 @@ void QQuickHandlerPoint::reset() \qmlproperty QPointF QtQuick::HandlerPoint::position \brief The position within the \c parent Item - This is the position of the event point relative to the bounds of the \l parent. + This is the position of the event point relative to the bounds of + the \l {PointerHandler::parent} {parent}. */ /*! @@ -378,7 +379,7 @@ void QQuickHandlerPoint::reset() \brief The pressed position within the \c parent Item This is the position at which this point was pressed, relative to the - bounds of the \l parent. + bounds of the \l {PointerHandler::parent} {parent}. */ /*! @@ -469,7 +470,7 @@ void QQuickHandlerPoint::reset() If the contact patch is unknown, or the device is not a touchscreen, these values will be zero. - \sa QtQuick::EventPoint::ellipseDiameters, QtQuick::TouchPoint::ellipseDiameters, QTouchEvent::TouchPoint::ellipseDiameters + \sa QtQuick::EventTouchPoint::ellipseDiameters, QtQuick::TouchPoint::ellipseDiameters, QTouchEvent::TouchPoint::ellipseDiameters */ QT_END_NAMESPACE diff --git a/src/quick/handlers/qquicksinglepointhandler_p.h b/src/quick/handlers/qquicksinglepointhandler_p.h index 386cea253a..7606b4f7ba 100644 --- a/src/quick/handlers/qquicksinglepointhandler_p.h +++ b/src/quick/handlers/qquicksinglepointhandler_p.h @@ -111,7 +111,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickSinglePointHandler : public QQuickPointerDevi Q_PROPERTY(Qt::MouseButtons acceptedButtons READ acceptedButtons WRITE setAcceptedButtons NOTIFY acceptedButtonsChanged) Q_PROPERTY(QQuickHandlerPoint point READ point NOTIFY pointChanged) public: - explicit QQuickSinglePointHandler(QObject *parent = 0); + explicit QQuickSinglePointHandler(QObject *parent = nullptr); virtual ~QQuickSinglePointHandler() { } Qt::MouseButtons acceptedButtons() const { return m_acceptedButtons; } diff --git a/src/quick/handlers/qquicktaphandler.cpp b/src/quick/handlers/qquicktaphandler.cpp index e5b728db0f..902ff0df10 100644 --- a/src/quick/handlers/qquicktaphandler.cpp +++ b/src/quick/handlers/qquicktaphandler.cpp @@ -61,14 +61,20 @@ int QQuickTapHandler::m_touchMultiTapDistanceSquared(-1); TapHandler is a handler for taps on a touchscreen or clicks on a mouse. - Detection of a valid tap gesture depends on \l gesturePolicy. + Detection of a valid tap gesture depends on \l gesturePolicy. The default + value is DragThreshold, which requires the press and release to be close + together in both space and time. In this case, DragHandler is able to + function using only a passive grab, and therefore does not interfere with + event delivery to any other Items or Pointer Handlers. So the default + gesturePolicy is useful when you want to modify behavior of an existing + control or Item by adding a TapHandler with bindings and/or JavaScript + callbacks. + Note that buttons (such as QPushButton) are often implemented not to care whether the press and release occur close together: if you press the button and then change your mind, you need to drag all the way off the edge of the - button in order to cancel the click. Therefore the default - \l gesturePolicy is \c TapHandler.ReleaseWithinBounds. If you want to require - that the press and release are close together in both space and time, - set it to \c TapHandler.DragThreshold. + button in order to cancel the click. For this use case, set the + \l gesturePolicy to \c TapHandler.ReleaseWithinBounds. For multi-tap gestures (double-tap, triple-tap etc.), the distance moved must not exceed QPlatformTheme::MouseDoubleClickDistance with mouse and @@ -81,7 +87,7 @@ int QQuickTapHandler::m_touchMultiTapDistanceSquared(-1); QQuickTapHandler::QQuickTapHandler(QObject *parent) : QQuickSinglePointHandler(parent) , m_pressed(false) - , m_gesturePolicy(ReleaseWithinBounds) + , m_gesturePolicy(DragThreshold) , m_tapCount(0) , m_longPressThreshold(-1) , m_lastTapTimestamp(0.0) @@ -165,7 +171,7 @@ void QQuickTapHandler::handleEventPoint(QQuickEventPoint *point) } /*! - \qmlproperty real TapHandler::longPressThreshold + \qmlproperty real QtQuick::TapHandler::longPressThreshold The time in seconds that an event point must be pressed in order to trigger a long press gesture and emit the \l longPressed() signal. @@ -203,39 +209,53 @@ void QQuickTapHandler::timerEvent(QTimerEvent *event) } /*! - \qmlproperty enumeration TapHandler::gesturePolicy + \qmlsignal QtQuick::TapHandler::tapped() + + This signal is emitted when the pointer device taps the item. + */ + +/*! + \qmlsignal QtQuick::TapHandler::longPressed() + + This signal is emitted when a press occurs that is longer than the + \l {TapHandler::longPressThreshold} {long press threshold}. + */ + +/*! + \qmlproperty enumeration QtQuick::TapHandler::gesturePolicy The spatial constraint for a tap or long press gesture to be recognized, in addition to the constraint that the release must occur before \l longPressThreshold has elapsed. If these constraints are not satisfied, the \l tapped signal is not emitted, and \l tapCount is not incremented. - If the spatial constraint is violated, \l isPressed transitions immediately + If the spatial constraint is violated, \l pressed transitions immediately from true to false, regardless of the time held. \value TapHandler.DragThreshold - The event point must not move significantly. If the mouse, finger - or stylus moves past the system-wide drag threshold - (QStyleHints::startDragDistance), the tap gesture is canceled, even - if the button or finger is still pressed. This policy can be useful - whenever TapHandler needs to cooperate with other pointer handlers - (for example \l DragHandler), because in this case TapHandler will - never grab. + (the default value) The event point must not move significantly. + If the mouse, finger or stylus moves past the system-wide drag + threshold (QStyleHints::startDragDistance), the tap gesture is + canceled, even if the button or finger is still pressed. This policy + can be useful whenever TapHandler needs to cooperate with other + pointer handlers (for example \l DragHandler) or event-handling Items + (for example QtQuick Controls), because in this case TapHandler + will not take the exclusive grab, but merely a passive grab. \value TapHandler.WithinBounds If the event point leaves the bounds of the \l target item, the tap - gesture is canceled. The TapHandler will grab on press, but release - the grab as soon as the boundary constraint is no longer satisfied. + gesture is canceled. The TapHandler will take the exclusive grab on + press, but will release the grab as soon as the boundary constraint + is no longer satisfied. \value TapHandler.ReleaseWithinBounds - (the default value) At the time of release (the mouse button is - released or the finger is lifted), if the event point is outside - the bounds of the \l target item, a tap gesture is not recognized. - This is the default value, because it corresponds to typical button - behavior: you can cancel a click by dragging outside the button, - and you can also change your mind by dragging back inside the button - before release. Note that it's necessary for TapHandler to grab on - press and retain it until release (greedy grab) in order to detect - this gesture. + At the time of release (the mouse button is released or the finger + is lifted), if the event point is outside the bounds of the + \l target item, a tap gesture is not recognized. This corresponds to + typical behavior for button widgets: you can cancel a click by + dragging outside the button, and you can also change your mind by + dragging back inside the button before release. Note that it's + necessary for TapHandler take the exclusive grab on press and retain + it until release in order to detect this gesture. */ void QQuickTapHandler::setGesturePolicy(QQuickTapHandler::GesturePolicy gesturePolicy) { @@ -247,7 +267,7 @@ void QQuickTapHandler::setGesturePolicy(QQuickTapHandler::GesturePolicy gestureP } /*! - \qmlproperty bool TapHandler::pressed + \qmlproperty bool QtQuick::TapHandler::pressed \readonly Holds true whenever the mouse or touch point is pressed, @@ -290,6 +310,10 @@ void QQuickTapHandler::setPressed(bool press, bool cancel, QQuickEventPoint *poi qCDebug(lcTapHandler) << objectName() << "tapped" << m_tapCount << "times"; emit tapped(); emit tapCountChanged(); + if (m_tapCount == 1) + emit singleTapped(); + else if (m_tapCount == 2) + emit doubleTapped(); m_lastTapTimestamp = ts; m_lastTapPos = point->scenePosition(); } else { @@ -301,6 +325,8 @@ void QQuickTapHandler::setPressed(bool press, bool cancel, QQuickEventPoint *poi // on release, ungrab after emitting changed signals setExclusiveGrab(point, press); } + if (cancel) + emit canceled(point); } } @@ -326,27 +352,27 @@ void QQuickTapHandler::updateTimeHeld() } /*! - \qmlproperty int TapHandler::tapCount + \qmlproperty int QtQuick::TapHandler::tapCount \readonly The number of taps which have occurred within the time and space constraints to be considered a single gesture. For example, to detect - a double-tap, you can write: + a triple-tap, you can write: \qml Rectangle { width: 100; height: 30 - signal doubleTap + signal tripleTap TapHandler { acceptedButtons: Qt.AllButtons - onTapped: if (tapCount == 2) doubleTap() + onTapped: if (tapCount == 3) tripleTap() } } \endqml */ /*! - \qmlproperty real TapHandler::timeHeld + \qmlproperty real QtQuick::TapHandler::timeHeld \readonly The amount of time in seconds that a pressed point has been held, without @@ -360,4 +386,24 @@ void QQuickTapHandler::updateTimeHeld() handler's \l [QML] Item. */ +/*! + \qmlsignal TapHandler::singleTapped + \since 5.11 + + This signal is emitted when the \l target is tapped once. After an amount + of time greater than QStyleHints::mouseDoubleClickInterval, it can be + tapped again; but if the time until the next tap is less, \l tapCount + will increase. +*/ + +/*! + \qmlsignal TapHandler::doubleTapped + \since 5.11 + + This signal is emitted when the \l target is tapped twice within a short + span of time (QStyleHints::mouseDoubleClickInterval) and distance + (QPlatformTheme::MouseDoubleClickDistance or + QPlatformTheme::TouchDoubleTapDistance). This signal always occurs + after singleTapped, tapped and tapCountChanged. +*/ QT_END_NAMESPACE diff --git a/src/quick/handlers/qquicktaphandler_p.h b/src/quick/handlers/qquicktaphandler_p.h index 6504ec87f0..b7c1895926 100644 --- a/src/quick/handlers/qquicktaphandler_p.h +++ b/src/quick/handlers/qquicktaphandler_p.h @@ -75,7 +75,7 @@ public: }; Q_ENUM(GesturePolicy) - explicit QQuickTapHandler(QObject *parent = 0); + explicit QQuickTapHandler(QObject *parent = nullptr); ~QQuickTapHandler(); bool isPressed() const { return m_pressed; } @@ -96,6 +96,8 @@ Q_SIGNALS: void longPressThresholdChanged(); void gesturePolicyChanged(); void tapped(); + void singleTapped(); + void doubleTapped(); void longPressed(); protected: diff --git a/src/quick/items/context2d/qquickcanvascontext_p.h b/src/quick/items/context2d/qquickcanvascontext_p.h index 0746b7dcd3..95100d2912 100644 --- a/src/quick/items/context2d/qquickcanvascontext_p.h +++ b/src/quick/items/context2d/qquickcanvascontext_p.h @@ -69,7 +69,7 @@ class QQuickCanvasContext : public QObject Q_OBJECT public: - QQuickCanvasContext(QObject *parent = 0); + QQuickCanvasContext(QObject *parent = nullptr); ~QQuickCanvasContext(); virtual QStringList contextNames() const = 0; diff --git a/src/quick/items/context2d/qquickcanvasitem.cpp b/src/quick/items/context2d/qquickcanvasitem.cpp index 57936d8cec..59917ce531 100644 --- a/src/quick/items/context2d/qquickcanvasitem.cpp +++ b/src/quick/items/context2d/qquickcanvasitem.cpp @@ -71,7 +71,7 @@ public: }; QQuickCanvasPixmap::QQuickCanvasPixmap(const QImage& image) - : m_pixmap(0) + : m_pixmap(nullptr) , m_image(image) { @@ -123,7 +123,7 @@ QHash<QQmlEngine *,QQuickContext2DRenderThread*> QQuickContext2DRenderThread::re QMutex QQuickContext2DRenderThread::renderThreadsMutex; QQuickContext2DRenderThread::QQuickContext2DRenderThread(QQmlEngine *eng) - : QThread(eng), m_engine(eng), m_eventLoopQuitHack(0) + : QThread(eng), m_engine(eng), m_eventLoopQuitHack(nullptr) { Q_ASSERT(eng); m_eventLoopQuitHack = new QObject; @@ -144,7 +144,7 @@ QQuickContext2DRenderThread::~QQuickContext2DRenderThread() QQuickContext2DRenderThread *QQuickContext2DRenderThread::instance(QQmlEngine *engine) { - QQuickContext2DRenderThread *thread = 0; + QQuickContext2DRenderThread *thread = nullptr; renderThreadsMutex.lock(); if (renderThreads.contains(engine)) thread = renderThreads.value(engine); @@ -183,7 +183,7 @@ public: QQuickCanvasItemPrivate::QQuickCanvasItemPrivate() : QQuickItemPrivate() - , context(0) + , context(nullptr) , canvasSize(1, 1) , tileSize(1, 1) , hasCanvasSize(false) @@ -192,9 +192,9 @@ QQuickCanvasItemPrivate::QQuickCanvasItemPrivate() , available(false) , renderTarget(QQuickCanvasItem::Image) , renderStrategy(QQuickCanvasItem::Immediate) - , textureProvider(0) - , node(0) - , nodeTexture(0) + , textureProvider(nullptr) + , node(nullptr) + , nodeTexture(nullptr) { implicitAntialiasing = true; } @@ -634,16 +634,16 @@ void QQuickCanvasItem::releaseResources() if (d->context) { delete d->context; - d->context = 0; + d->context = nullptr; } - d->node = 0; // managed by the scene graph, just reset the pointer + d->node = nullptr; // managed by the scene graph, just reset the pointer if (d->textureProvider) { QQuickWindowQObjectCleanupJob::schedule(window(), d->textureProvider); - d->textureProvider = 0; + d->textureProvider = nullptr; } if (d->nodeTexture) { QQuickWindowQObjectCleanupJob::schedule(window(), d->nodeTexture); - d->nodeTexture = 0; + d->nodeTexture = nullptr; } } @@ -663,12 +663,12 @@ void QQuickCanvasItem::invalidateSceneGraph() Q_D(QQuickCanvasItem); if (d->context) d->context->deleteLater(); - d->context = 0; - d->node = 0; // managed by the scene graph, just reset the pointer + d->context = nullptr; + d->node = nullptr; // managed by the scene graph, just reset the pointer delete d->textureProvider; - d->textureProvider = 0; + d->textureProvider = nullptr; delete d->nodeTexture; - d->nodeTexture = 0; + d->nodeTexture = nullptr; } void QQuickCanvasItem::schedulePolish() @@ -698,14 +698,14 @@ void QQuickCanvasItem::itemChange(QQuickItem::ItemChange change, const QQuickIte return; } - if (value.window== 0) + if (value.window== nullptr) return; d->window = value.window; QSGRenderContext *context = QQuickWindowPrivate::get(d->window)->context; // Rendering to FramebufferObject needs a valid OpenGL context. - if (context != 0 && (d->renderTarget != FramebufferObject || context->isValid())) { + if (context != nullptr && (d->renderTarget != FramebufferObject || context->isValid())) { // Defer the call. In some (arguably incorrect) cases we get here due // to ItemSceneChange with the user-supplied property values not yet // set. Work this around by a deferred invoke. (QTBUG-49692) @@ -727,7 +727,7 @@ void QQuickCanvasItem::updatePolish() QMap<int, QV4::PersistentValue> animationCallbacks = d->animationCallbacks; d->animationCallbacks.clear(); - QV4::ExecutionEngine *v4 = QQmlEnginePrivate::getV4Engine(qmlEngine(this)); + QV4::ExecutionEngine *v4 = qmlEngine(this)->handle(); QV4::Scope scope(v4); QV4::ScopedFunctionObject function(scope); QV4::JSCallData jsCall(scope, 1); @@ -763,11 +763,11 @@ QSGNode *QQuickCanvasItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData if (!d->context || d->canvasWindow.size().isEmpty()) { if (d->textureProvider) { - d->textureProvider->tex = 0; + d->textureProvider->tex = nullptr; d->textureProvider->fireTextureChanged(); } delete oldNode; - return 0; + return nullptr; } QSGInternalImageNode *node = static_cast<QSGInternalImageNode *>(oldNode); @@ -792,13 +792,13 @@ QSGNode *QQuickCanvasItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData QSGTexture *texture = factory->textureForNextFrame(d->nodeTexture, window()); if (!texture) { delete node; - d->node = 0; - d->nodeTexture = 0; + d->node = nullptr; + d->nodeTexture = nullptr; if (d->textureProvider) { - d->textureProvider->tex = 0; + d->textureProvider->tex = nullptr; d->textureProvider->fireTextureChanged(); } - return 0; + return nullptr; } d->nodeTexture = texture; @@ -833,7 +833,7 @@ QSGTextureProvider *QQuickCanvasItem::textureProvider() const if (!w || !w->isSceneGraphInitialized() || QThread::currentThread() != QQuickWindowPrivate::get(w)->context->thread()) { qWarning("QQuickCanvasItem::textureProvider: can only be queried on the rendering thread of an exposed window"); - return 0; + return nullptr; } #endif if (!d->textureProvider) @@ -879,7 +879,7 @@ void QQuickCanvasItem::getContext(QQmlV4Function *args) QString contextId = str->toQString(); - if (d->context != 0) { + if (d->context != nullptr) { if (d->context->contextNames().contains(contextId, Qt::CaseInsensitive)) { args->setReturnValue(d->context->v4value()); return; @@ -1210,7 +1210,7 @@ void QQuickCanvasItem::initializeContext(QQuickCanvasContext *context, const QVa d->context = context; d->context->init(this, args); - d->context->setV4Engine(QQmlEnginePrivate::get(qmlEngine(this))->v4engine()); + d->context->setV4Engine(qmlEngine(this)->handle()); connect(d->context, SIGNAL(textureChanged()), SLOT(update())); connect(d->context, SIGNAL(textureChanged()), SIGNAL(painted())); emit contextChanged(); diff --git a/src/quick/items/context2d/qquickcanvasitem_p.h b/src/quick/items/context2d/qquickcanvasitem_p.h index 59de847680..7dc981a6eb 100644 --- a/src/quick/items/context2d/qquickcanvasitem_p.h +++ b/src/quick/items/context2d/qquickcanvasitem_p.h @@ -114,7 +114,7 @@ public: }; Q_ENUM(RenderStrategy) - QQuickCanvasItem(QQuickItem *parent = 0); + QQuickCanvasItem(QQuickItem *parent = nullptr); ~QQuickCanvasItem(); bool isAvailable() const; diff --git a/src/quick/items/context2d/qquickcontext2d.cpp b/src/quick/items/context2d/qquickcontext2d.cpp index 49b2bf5838..af8048f2e4 100644 --- a/src/quick/items/context2d/qquickcontext2d.cpp +++ b/src/quick/items/context2d/qquickcontext2d.cpp @@ -304,7 +304,7 @@ static QStringList qExtractFontFamiliesFromString(const QStringRef &fontFamilies return extractedFamilies; } -/*! +/* Tries to set a family on \a font using the families provided in \a fontFamilyTokens. The list is ordered by preference, with the first family having the highest preference. @@ -364,7 +364,7 @@ if (!(usedTokens & token)) { \ return currentFont; \ } -/*! +/* Parses a font string based on the CSS shorthand font property. See: http://www.w3.org/TR/css3-fonts/#font-prop @@ -544,46 +544,46 @@ struct QQuickJSContext2D : public QV4::Object { V4_OBJECT2(QQuickJSContext2D, QV4::Object) - static QV4::ReturnedValue method_get_globalAlpha(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_set_globalAlpha(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_get_globalCompositeOperation(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_set_globalCompositeOperation(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_get_fillStyle(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_set_fillStyle(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_get_fillRule(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_set_fillRule(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_get_strokeStyle(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_set_strokeStyle(const QV4::BuiltinFunction *b, QV4::CallData *callData); - - static QV4::ReturnedValue method_get_lineCap(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_set_lineCap(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_get_lineJoin(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_set_lineJoin(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_get_lineWidth(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_set_lineWidth(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_get_miterLimit(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_set_miterLimit(const QV4::BuiltinFunction *b, QV4::CallData *callData); - - static QV4::ReturnedValue method_get_shadowBlur(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_set_shadowBlur(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_get_shadowColor(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_set_shadowColor(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_get_shadowOffsetX(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_set_shadowOffsetX(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_get_shadowOffsetY(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_set_shadowOffsetY(const QV4::BuiltinFunction *b, QV4::CallData *callData); + static QV4::ReturnedValue method_get_globalAlpha(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_set_globalAlpha(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_get_globalCompositeOperation(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_set_globalCompositeOperation(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_get_fillStyle(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_set_fillStyle(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_get_fillRule(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_set_fillRule(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_get_strokeStyle(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_set_strokeStyle(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + + static QV4::ReturnedValue method_get_lineCap(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_set_lineCap(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_get_lineJoin(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_set_lineJoin(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_get_lineWidth(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_set_lineWidth(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_get_miterLimit(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_set_miterLimit(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + + static QV4::ReturnedValue method_get_shadowBlur(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_set_shadowBlur(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_get_shadowColor(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_set_shadowColor(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_get_shadowOffsetX(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_set_shadowOffsetX(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_get_shadowOffsetY(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_set_shadowOffsetY(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); // should these two be on the proto? #if QT_CONFIG(quick_path) - static QV4::ReturnedValue method_get_path(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_set_path(const QV4::BuiltinFunction *b, QV4::CallData *callData); + static QV4::ReturnedValue method_get_path(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_set_path(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); #endif - static QV4::ReturnedValue method_get_font(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_set_font(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_get_textAlign(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_set_textAlign(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_get_textBaseline(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_set_textBaseline(const QV4::BuiltinFunction *b, QV4::CallData *callData); + static QV4::ReturnedValue method_get_font(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_set_font(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_get_textAlign(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_set_textAlign(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_get_textBaseline(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_set_textBaseline(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); }; DEFINE_OBJECT_VTABLE(QQuickJSContext2D); @@ -641,55 +641,55 @@ public: o->defineDefaultProperty(QStringLiteral("createLinearGradient"), method_createLinearGradient, 0); o->defineDefaultProperty(QStringLiteral("strokeRect"), method_strokeRect, 0); o->defineDefaultProperty(QStringLiteral("closePath"), method_closePath, 0); - o->defineAccessorProperty(QStringLiteral("canvas"), QQuickJSContext2DPrototype::method_get_canvas, 0); + o->defineAccessorProperty(QStringLiteral("canvas"), QQuickJSContext2DPrototype::method_get_canvas, nullptr); return o->d(); } - static QV4::ReturnedValue method_get_canvas(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_restore(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_reset(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_save(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_rotate(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_scale(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_translate(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_setTransform(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_transform(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_resetTransform(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_shear(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_createLinearGradient(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_createRadialGradient(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_createConicalGradient(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_createPattern(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_clearRect(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_fillRect(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_strokeRect(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_arc(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_arcTo(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_beginPath(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_bezierCurveTo(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_clip(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_closePath(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_fill(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_lineTo(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_moveTo(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_quadraticCurveTo(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_rect(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_roundedRect(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_ellipse(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_text(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_stroke(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_isPointInPath(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_drawFocusRing(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_setCaretSelectionRect(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_caretBlinkRate(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_fillText(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_strokeText(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_measureText(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_drawImage(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_createImageData(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_getImageData(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_putImageData(const QV4::BuiltinFunction *b, QV4::CallData *callData); + static QV4::ReturnedValue method_get_canvas(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_restore(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_reset(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_save(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_rotate(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_scale(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_translate(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_setTransform(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_transform(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_resetTransform(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_shear(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_createLinearGradient(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_createRadialGradient(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_createConicalGradient(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_createPattern(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_clearRect(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_fillRect(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_strokeRect(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_arc(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_arcTo(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_beginPath(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_bezierCurveTo(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_clip(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_closePath(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_fill(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_lineTo(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_moveTo(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_quadraticCurveTo(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_rect(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_roundedRect(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_ellipse(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_text(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_stroke(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_isPointInPath(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_drawFocusRing(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_setCaretSelectionRect(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_caretBlinkRate(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_fillText(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_strokeText(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_measureText(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_drawImage(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_createImageData(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_getImageData(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_putImageData(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); }; @@ -701,7 +701,7 @@ struct QQuickContext2DStyle : public QV4::Object V4_OBJECT2(QQuickContext2DStyle, QV4::Object) V4_NEEDS_DESTROY - static QV4::ReturnedValue gradient_proto_addColorStop(const QV4::BuiltinFunction *b, QV4::CallData *callData); + static QV4::ReturnedValue gradient_proto_addColorStop(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); }; @@ -911,7 +911,7 @@ struct QQuickJSContext2DPixelData : public QV4::Object static QV4::ReturnedValue getIndexed(const QV4::Managed *m, uint index, bool *hasProperty); static bool putIndexed(QV4::Managed *m, uint index, const QV4::Value &value); - static QV4::ReturnedValue proto_get_length(const QV4::BuiltinFunction *b, QV4::CallData *callData); + static QV4::ReturnedValue proto_get_length(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); }; void QV4::Heap::QQuickJSContext2DPixelData::init() @@ -929,9 +929,9 @@ struct QQuickJSContext2DImageData : public QV4::Object { V4_OBJECT2(QQuickJSContext2DImageData, QV4::Object) - static QV4::ReturnedValue method_get_width(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_get_height(const QV4::BuiltinFunction *b, QV4::CallData *callData); - static QV4::ReturnedValue method_get_data(const QV4::BuiltinFunction *b, QV4::CallData *callData); + static QV4::ReturnedValue method_get_width(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_get_height(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); + static QV4::ReturnedValue method_get_data(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc); }; @@ -943,9 +943,9 @@ void QV4::Heap::QQuickJSContext2DImageData::init() QV4::Scope scope(internalClass->engine); QV4::ScopedObject o(scope, this); - o->defineAccessorProperty(QStringLiteral("width"), ::QQuickJSContext2DImageData::method_get_width, 0); - o->defineAccessorProperty(QStringLiteral("height"), ::QQuickJSContext2DImageData::method_get_height, 0); - o->defineAccessorProperty(QStringLiteral("data"), ::QQuickJSContext2DImageData::method_get_data, 0); + o->defineAccessorProperty(QStringLiteral("width"), ::QQuickJSContext2DImageData::method_get_width, nullptr); + o->defineAccessorProperty(QStringLiteral("height"), ::QQuickJSContext2DImageData::method_get_height, nullptr); + o->defineAccessorProperty(QStringLiteral("data"), ::QQuickJSContext2DImageData::method_get_data, nullptr); } DEFINE_OBJECT_VTABLE(QQuickJSContext2DImageData); @@ -979,10 +979,10 @@ static QV4::ReturnedValue qt_create_image_data(qreal w, qreal h, QV4::ExecutionE This property is read only. */ -QV4::ReturnedValue QQuickJSContext2DPrototype::method_get_canvas(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2DPrototype::method_get_canvas(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>()); + QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>()); CHECK_CONTEXT(r) RETURN_RESULT(QV4::QObjectWrapper::wrap(scope.engine, r->d()->context->canvas())); @@ -994,29 +994,29 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_get_canvas(const QV4::Buil \sa save() */ -QV4::ReturnedValue QQuickJSContext2DPrototype::method_restore(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2DPrototype::method_restore(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>()); + QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>()); CHECK_CONTEXT(r) r->d()->context->popState(); - RETURN_RESULT(callData->thisObject.asReturnedValue()); + RETURN_RESULT(thisObject->asReturnedValue()); } /*! \qmlmethod object QtQuick::Context2D::reset() Resets the context state and properties to the default values. */ -QV4::ReturnedValue QQuickJSContext2DPrototype::method_reset(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2DPrototype::method_reset(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>()); + QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>()); CHECK_CONTEXT(r) r->d()->context->reset(); - RETURN_RESULT(callData->thisObject.asReturnedValue()); + RETURN_RESULT(thisObject->asReturnedValue()); } /*! @@ -1049,15 +1049,15 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_reset(const QV4::BuiltinFu The current path is NOT part of the drawing state. The path can be reset by invoking the beginPath() method. */ -QV4::ReturnedValue QQuickJSContext2DPrototype::method_save(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2DPrototype::method_save(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>()); + QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>()); CHECK_CONTEXT(r) r->d()->context->pushState(); - RETURN_RESULT(callData->thisObject); + RETURN_RESULT(*thisObject); } // transformations @@ -1078,15 +1078,15 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_save(const QV4::BuiltinFun where the \a angle of rotation is in radians. */ -QV4::ReturnedValue QQuickJSContext2DPrototype::method_rotate(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2DPrototype::method_rotate(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>()); + QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>()); CHECK_CONTEXT(r) - if (callData->argc() >= 1) - r->d()->context->rotate(callData->args[0].toNumber()); - RETURN_RESULT(callData->thisObject); + if (argc >= 1) + r->d()->context->rotate(argv[0].toNumber()); + RETURN_RESULT(*thisObject); } /*! @@ -1106,16 +1106,16 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_rotate(const QV4::BuiltinF \image qml-item-canvas-scale.png */ -QV4::ReturnedValue QQuickJSContext2DPrototype::method_scale(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2DPrototype::method_scale(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>()); + QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>()); CHECK_CONTEXT(r) - if (callData->argc() >= 2) - r->d()->context->scale(callData->args[0].toNumber(), callData->args[1].toNumber()); - RETURN_RESULT(callData->thisObject); + if (argc >= 2) + r->d()->context->scale(argv[0].toNumber(), argv[1].toNumber()); + RETURN_RESULT(*thisObject); } @@ -1153,22 +1153,22 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_scale(const QV4::BuiltinFu \sa transform() */ -QV4::ReturnedValue QQuickJSContext2DPrototype::method_setTransform(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2DPrototype::method_setTransform(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>()); + QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>()); CHECK_CONTEXT(r) - if (callData->argc() >= 6) - r->d()->context->setTransform( callData->args[0].toNumber() - , callData->args[1].toNumber() - , callData->args[2].toNumber() - , callData->args[3].toNumber() - , callData->args[4].toNumber() - , callData->args[5].toNumber()); + if (argc >= 6) + r->d()->context->setTransform( argv[0].toNumber() + , argv[1].toNumber() + , argv[2].toNumber() + , argv[3].toNumber() + , argv[4].toNumber() + , argv[5].toNumber()); - RETURN_RESULT(callData->thisObject); + RETURN_RESULT(*thisObject); } @@ -1183,21 +1183,21 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_setTransform(const QV4::Bu \sa setTransform() */ -QV4::ReturnedValue QQuickJSContext2DPrototype::method_transform(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2DPrototype::method_transform(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>()); + QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>()); CHECK_CONTEXT(r) - if (callData->argc() >= 6) - r->d()->context->transform( callData->args[0].toNumber() - , callData->args[1].toNumber() - , callData->args[2].toNumber() - , callData->args[3].toNumber() - , callData->args[4].toNumber() - , callData->args[5].toNumber()); + if (argc >= 6) + r->d()->context->transform( argv[0].toNumber() + , argv[1].toNumber() + , argv[2].toNumber() + , argv[3].toNumber() + , argv[4].toNumber() + , argv[5].toNumber()); - RETURN_RESULT(callData->thisObject); + RETURN_RESULT(*thisObject); } @@ -1210,15 +1210,15 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_transform(const QV4::Built Translating the origin enables you to draw patterns of different objects on the canvas without having to measure the coordinates manually for each shape. */ -QV4::ReturnedValue QQuickJSContext2DPrototype::method_translate(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2DPrototype::method_translate(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>()); + QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>()); CHECK_CONTEXT(r) - if (callData->argc() >= 2) - r->d()->context->translate(callData->args[0].toNumber(), callData->args[1].toNumber()); - RETURN_RESULT(callData->thisObject); + if (argc >= 2) + r->d()->context->translate(argv[0].toNumber(), argv[1].toNumber()); + RETURN_RESULT(*thisObject); } @@ -1231,15 +1231,15 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_translate(const QV4::Built \sa transform(), setTransform(), reset() */ -QV4::ReturnedValue QQuickJSContext2DPrototype::method_resetTransform(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2DPrototype::method_resetTransform(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>()); + QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>()); CHECK_CONTEXT(r) r->d()->context->setTransform(1, 0, 0, 1, 0, 0); - RETURN_RESULT(callData->thisObject); + RETURN_RESULT(*thisObject); } @@ -1250,16 +1250,16 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_resetTransform(const QV4:: Shears the transformation matrix by \a sh in the horizontal direction and \a sv in the vertical direction. */ -QV4::ReturnedValue QQuickJSContext2DPrototype::method_shear(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2DPrototype::method_shear(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>()); + QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>()); CHECK_CONTEXT(r) - if (callData->argc() >= 2) - r->d()->context->shear(callData->args[0].toNumber(), callData->args[1].toNumber()); + if (argc >= 2) + r->d()->context->shear(argv[0].toNumber(), argv[1].toNumber()); - RETURN_RESULT(callData->thisObject); + RETURN_RESULT(*thisObject); } // compositing @@ -1271,22 +1271,22 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_shear(const QV4::BuiltinFu The value must be in the range from \c 0.0 (fully transparent) to \c 1.0 (fully opaque). The default value is \c 1.0. */ -QV4::ReturnedValue QQuickJSContext2D::method_get_globalAlpha(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2D::method_get_globalAlpha(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>()); + QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>()); CHECK_CONTEXT(r) RETURN_RESULT(QV4::Encode(r->d()->context->state.globalAlpha)); } -QV4::ReturnedValue QQuickJSContext2D::method_set_globalAlpha(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2D::method_set_globalAlpha(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>()); + QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>()); CHECK_CONTEXT_SETTER(r) - double globalAlpha = callData->argc() ? callData->args[0].toNumber() : qt_qnan(); + double globalAlpha = argc ? argv[0].toNumber() : qt_qnan(); if (!qt_is_finite(globalAlpha)) @@ -1325,25 +1325,25 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_globalAlpha(const QV4::BuiltinF extension composition modes are provided as "vendorName-operationName" syntax, for example: QPainter::CompositionMode_Exclusion is provided as "qt-exclusion". */ -QV4::ReturnedValue QQuickJSContext2D::method_get_globalCompositeOperation(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2D::method_get_globalCompositeOperation(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>()); + QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>()); CHECK_CONTEXT(r) RETURN_RESULT(scope.engine->newString(qt_composite_mode_to_string(r->d()->context->state.globalCompositeOperation))); } -QV4::ReturnedValue QQuickJSContext2D::method_set_globalCompositeOperation(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2D::method_set_globalCompositeOperation(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>()); + QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>()); CHECK_CONTEXT_SETTER(r) - if (!callData->argc()) + if (!argc) THROW_TYPE_ERROR(); - QString mode = callData->args[0].toQString(); + QString mode = argv[0].toQString(); QPainter::CompositionMode cm = qt_composite_mode_from_string(mode); if (cm == QPainter::CompositionMode_SourceOver && mode != QLatin1String("source-over")) RETURN_UNDEFINED(); @@ -1379,10 +1379,10 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_globalCompositeOperation(const \sa createPattern() \sa strokeStyle */ -QV4::ReturnedValue QQuickJSContext2D::method_get_fillStyle(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2D::method_get_fillStyle(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>()); + QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>()); CHECK_CONTEXT(r) QColor color = r->d()->context->state.fillStyle.color(); @@ -1400,13 +1400,13 @@ QV4::ReturnedValue QQuickJSContext2D::method_get_fillStyle(const QV4::BuiltinFun RETURN_RESULT(r->d()->context->m_fillStyle.value()); } -QV4::ReturnedValue QQuickJSContext2D::method_set_fillStyle(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2D::method_set_fillStyle(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>()); + QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>()); CHECK_CONTEXT_SETTER(r) - QV4::ScopedValue value(scope, callData->argument(0)); + QV4::ScopedValue value(scope, argc ? argv[0] : QV4::Primitive::undefinedValue()); if (value->as<Object>()) { QColor color = scope.engine->toVariant(value, qMetaTypeId<QColor>()).value<QColor>(); @@ -1446,22 +1446,22 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_fillStyle(const QV4::BuiltinFun \sa fillStyle */ -QV4::ReturnedValue QQuickJSContext2D::method_get_fillRule(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2D::method_get_fillRule(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>()); + QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>()); CHECK_CONTEXT(r) RETURN_RESULT(scope.engine->fromVariant(r->d()->context->state.fillRule)); } -QV4::ReturnedValue QQuickJSContext2D::method_set_fillRule(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2D::method_set_fillRule(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>()); + QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>()); CHECK_CONTEXT_SETTER(r) - QV4::ScopedValue value(scope, callData->argument(0)); + QV4::ScopedValue value(scope, argc ? argv[0] : QV4::Primitive::undefinedValue()); if ((value->isString() && value->toQString() == QLatin1String("WindingFill")) || (value->isInt32() && value->integerValue() == Qt::WindingFill)) { @@ -1488,10 +1488,10 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_fillRule(const QV4::BuiltinFunc \sa createPattern() \sa fillStyle */ -QV4::ReturnedValue QQuickJSContext2D::method_get_strokeStyle(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2D::method_get_strokeStyle(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>()); + QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>()); CHECK_CONTEXT(r) QColor color = r->d()->context->state.strokeStyle.color(); @@ -1509,13 +1509,13 @@ QV4::ReturnedValue QQuickJSContext2D::method_get_strokeStyle(const QV4::BuiltinF RETURN_RESULT(r->d()->context->m_strokeStyle.value()); } -QV4::ReturnedValue QQuickJSContext2D::method_set_strokeStyle(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2D::method_set_strokeStyle(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>()); + QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>()); CHECK_CONTEXT_SETTER(r) - QV4::ScopedValue value(scope, callData->argument(0)); + QV4::ScopedValue value(scope, argc ? argv[0] : QV4::Primitive::undefinedValue()); if (value->as<Object>()) { QColor color = scope.engine->toVariant(value, qMetaTypeId<QColor>()).value<QColor>(); @@ -1562,17 +1562,17 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_strokeStyle(const QV4::BuiltinF \sa strokeStyle */ -QV4::ReturnedValue QQuickJSContext2DPrototype::method_createLinearGradient(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2DPrototype::method_createLinearGradient(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>()); + QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>()); CHECK_CONTEXT(r) - if (callData->argc() >= 4) { - qreal x0 = callData->args[0].toNumber(); - qreal y0 = callData->args[1].toNumber(); - qreal x1 = callData->args[2].toNumber(); - qreal y1 = callData->args[3].toNumber(); + if (argc >= 4) { + qreal x0 = argv[0].toNumber(); + qreal y0 = argv[1].toNumber(); + qreal x1 = argv[2].toNumber(); + qreal y1 = argv[3].toNumber(); if (!qt_is_finite(x0) || !qt_is_finite(y0) @@ -1589,7 +1589,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createLinearGradient(const RETURN_RESULT(*gradient); } - RETURN_RESULT(callData->thisObject); + RETURN_RESULT(*thisObject); } @@ -1606,19 +1606,19 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createLinearGradient(const \sa strokeStyle */ -QV4::ReturnedValue QQuickJSContext2DPrototype::method_createRadialGradient(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2DPrototype::method_createRadialGradient(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>()); + QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>()); CHECK_CONTEXT(r) - if (callData->argc() >= 6) { - qreal x0 = callData->args[0].toNumber(); - qreal y0 = callData->args[1].toNumber(); - qreal r0 = callData->args[2].toNumber(); - qreal x1 = callData->args[3].toNumber(); - qreal y1 = callData->args[4].toNumber(); - qreal r1 = callData->args[5].toNumber(); + if (argc >= 6) { + qreal x0 = argv[0].toNumber(); + qreal y0 = argv[1].toNumber(); + qreal r0 = argv[2].toNumber(); + qreal x1 = argv[3].toNumber(); + qreal y1 = argv[4].toNumber(); + qreal r1 = argv[5].toNumber(); if (!qt_is_finite(x0) || !qt_is_finite(y0) @@ -1641,7 +1641,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createRadialGradient(const RETURN_RESULT(*gradient); } - RETURN_RESULT(callData->thisObject); + RETURN_RESULT(*thisObject); } @@ -1658,16 +1658,16 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createRadialGradient(const \sa strokeStyle */ -QV4::ReturnedValue QQuickJSContext2DPrototype::method_createConicalGradient(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2DPrototype::method_createConicalGradient(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>()); + QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>()); CHECK_CONTEXT(r) - if (callData->argc() >= 3) { - qreal x = callData->args[0].toNumber(); - qreal y = callData->args[1].toNumber(); - qreal angle = qRadiansToDegrees(callData->args[2].toNumber()); + if (argc >= 3) { + qreal x = argv[0].toNumber(); + qreal y = argv[1].toNumber(); + qreal angle = qRadiansToDegrees(argv[2].toNumber()); if (!qt_is_finite(x) || !qt_is_finite(y)) { THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "createConicalGradient(): Incorrect arguments"); } @@ -1685,7 +1685,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createConicalGradient(cons RETURN_RESULT(*gradient); } - RETURN_RESULT(callData->thisObject); + RETURN_RESULT(*thisObject); } /*! @@ -1731,18 +1731,18 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createConicalGradient(cons \sa strokeStyle \sa fillStyle */ -QV4::ReturnedValue QQuickJSContext2DPrototype::method_createPattern(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2DPrototype::method_createPattern(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject); + QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject); CHECK_CONTEXT(r) - if (callData->argc() >= 2) { + if (argc >= 2) { QV4::Scoped<QQuickContext2DStyle> pattern(scope, scope.engine->memoryManager->allocObject<QQuickContext2DStyle>()); - QColor color = scope.engine->toVariant(callData->args[0], qMetaTypeId<QColor>()).value<QColor>(); + QColor color = scope.engine->toVariant(argv[0], qMetaTypeId<QColor>()).value<QColor>(); if (color.isValid()) { - int patternMode = callData->args[1].toInt32(); + int patternMode = argv[1].toInt32(); Qt::BrushStyle style = Qt::SolidPattern; if (patternMode >= 0 && patternMode < Qt::LinearGradientPattern) { style = static_cast<Qt::BrushStyle>(patternMode); @@ -1751,20 +1751,20 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createPattern(const QV4::B } else { QImage patternTexture; - if (const QV4::Object *o = callData->args[0].as<Object>()) { + if (const QV4::Object *o = argv[0].as<Object>()) { QV4::ScopedString s(scope, scope.engine->newString(QStringLiteral("data"))); QV4::Scoped<QQuickJSContext2DPixelData> pixelData(scope, o->get(s)); if (!!pixelData) { patternTexture = *pixelData->d()->image; } } else { - patternTexture = r->d()->context->createPixmap(QUrl(callData->args[0].toQStringNoThrow()))->image(); + patternTexture = r->d()->context->createPixmap(QUrl(argv[0].toQStringNoThrow()))->image(); } if (!patternTexture.isNull()) { pattern->d()->brush->setTextureImage(patternTexture); - QString repetition = callData->args[1].toQStringNoThrow(); + QString repetition = argv[1].toQStringNoThrow(); if (repetition == QLatin1String("repeat") || repetition.isEmpty()) { pattern->d()->patternRepeatX = true; pattern->d()->patternRepeatY = true; @@ -1802,10 +1802,10 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createPattern(const QV4::B \endlist Other values are ignored. */ -QV4::ReturnedValue QQuickJSContext2D::method_get_lineCap(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2D::method_get_lineCap(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject); + QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject); CHECK_CONTEXT(r) switch (r->d()->context->state.lineCap) { @@ -1820,14 +1820,16 @@ QV4::ReturnedValue QQuickJSContext2D::method_get_lineCap(const QV4::BuiltinFunct RETURN_RESULT(scope.engine->newString(QStringLiteral("butt"))); } -QV4::ReturnedValue QQuickJSContext2D::method_set_lineCap(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2D::method_set_lineCap(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { + if (!argc) + return QV4::Encode::undefined(); QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject); + QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject); CHECK_CONTEXT_SETTER(r) - QString lineCap = callData->args[0].toQString(); + QString lineCap = argv[0].toQString(); Qt::PenCapStyle cap; if (lineCap == QLatin1String("round")) cap = Qt::RoundCap; @@ -1859,10 +1861,10 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_lineCap(const QV4::BuiltinFunct \endlist Other values are ignored. */ -QV4::ReturnedValue QQuickJSContext2D::method_get_lineJoin(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2D::method_get_lineJoin(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject); + QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject); CHECK_CONTEXT(r) switch (r->d()->context->state.lineJoin) { @@ -1877,16 +1879,16 @@ QV4::ReturnedValue QQuickJSContext2D::method_get_lineJoin(const QV4::BuiltinFunc RETURN_RESULT(scope.engine->newString(QStringLiteral("miter"))); } -QV4::ReturnedValue QQuickJSContext2D::method_set_lineJoin(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2D::method_set_lineJoin(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject); + QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject); CHECK_CONTEXT_SETTER(r) - if (!callData->argc()) + if (!argc) THROW_TYPE_ERROR(); - QString lineJoin = callData->args[0].toQString(); + QString lineJoin = argv[0].toQString(); Qt::PenJoinStyle join; if (lineJoin == QLatin1String("round")) join = Qt::RoundJoin; @@ -1908,22 +1910,22 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_lineJoin(const QV4::BuiltinFunc \qmlproperty real QtQuick::Context2D::lineWidth Holds the current line width. Values that are not finite values greater than zero are ignored. */ -QV4::ReturnedValue QQuickJSContext2D::method_get_lineWidth(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2D::method_get_lineWidth(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject); + QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject); CHECK_CONTEXT(r) RETURN_RESULT(QV4::Encode(r->d()->context->state.lineWidth)); } -QV4::ReturnedValue QQuickJSContext2D::method_set_lineWidth(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2D::method_set_lineWidth(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject); + QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject); CHECK_CONTEXT_SETTER(r) - qreal w = callData->argc() ? callData->args[0].toNumber() : -1; + qreal w = argc ? argv[0].toNumber() : -1; if (w > 0 && qt_is_finite(w) && w != r->d()->context->state.lineWidth) { r->d()->context->state.lineWidth = w; @@ -1937,22 +1939,22 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_lineWidth(const QV4::BuiltinFun Holds the current miter limit ratio. The default miter limit value is 10.0. */ -QV4::ReturnedValue QQuickJSContext2D::method_get_miterLimit(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2D::method_get_miterLimit(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject); + QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject); CHECK_CONTEXT(r) RETURN_RESULT(QV4::Encode(r->d()->context->state.miterLimit)); } -QV4::ReturnedValue QQuickJSContext2D::method_set_miterLimit(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2D::method_set_miterLimit(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject); + QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject); CHECK_CONTEXT_SETTER(r) - qreal ml = callData->argc() ? callData->args[0].toNumber() : -1; + qreal ml = argc ? argv[0].toNumber() : -1; if (ml > 0 && qt_is_finite(ml) && ml != r->d()->context->state.miterLimit) { r->d()->context->state.miterLimit = ml; @@ -1966,22 +1968,22 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_miterLimit(const QV4::BuiltinFu \qmlproperty real QtQuick::Context2D::shadowBlur Holds the current level of blur applied to shadows */ -QV4::ReturnedValue QQuickJSContext2D::method_get_shadowBlur(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2D::method_get_shadowBlur(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject); + QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject); CHECK_CONTEXT(r) RETURN_RESULT(QV4::Encode(r->d()->context->state.shadowBlur)); } -QV4::ReturnedValue QQuickJSContext2D::method_set_shadowBlur(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2D::method_set_shadowBlur(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject); + QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject); CHECK_CONTEXT_SETTER(r) - qreal blur = callData->argc() ? callData->args[0].toNumber() : -1; + qreal blur = argc ? argv[0].toNumber() : -1; if (blur > 0 && qt_is_finite(blur) && blur != r->d()->context->state.shadowBlur) { r->d()->context->state.shadowBlur = blur; @@ -1994,24 +1996,24 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_shadowBlur(const QV4::BuiltinFu \qmlproperty string QtQuick::Context2D::shadowColor Holds the current shadow color. */ -QV4::ReturnedValue QQuickJSContext2D::method_get_shadowColor(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2D::method_get_shadowColor(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject); + QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject); CHECK_CONTEXT(r) RETURN_RESULT(scope.engine->newString(r->d()->context->state.shadowColor.name())); } -QV4::ReturnedValue QQuickJSContext2D::method_set_shadowColor(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2D::method_set_shadowColor(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject); + QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject); CHECK_CONTEXT_SETTER(r) QColor color; - if (callData->argc()) - color = qt_color_from_string(callData->args[0]); + if (argc) + color = qt_color_from_string(argv[0]); if (color.isValid() && color != r->d()->context->state.shadowColor) { r->d()->context->state.shadowColor = color; @@ -2027,22 +2029,22 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_shadowColor(const QV4::BuiltinF \sa shadowOffsetY */ -QV4::ReturnedValue QQuickJSContext2D::method_get_shadowOffsetX(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2D::method_get_shadowOffsetX(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject); + QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject); CHECK_CONTEXT(r) RETURN_RESULT(QV4::Encode(r->d()->context->state.shadowOffsetX)); } -QV4::ReturnedValue QQuickJSContext2D::method_set_shadowOffsetX(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2D::method_set_shadowOffsetX(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject); + QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject); CHECK_CONTEXT_SETTER(r) - qreal offsetX = callData->argc() ? callData->args[0].toNumber() : qt_qnan(); + qreal offsetX = argc ? argv[0].toNumber() : qt_qnan(); if (qt_is_finite(offsetX) && offsetX != r->d()->context->state.shadowOffsetX) { r->d()->context->state.shadowOffsetX = offsetX; r->d()->context->buffer()->setShadowOffsetX(offsetX); @@ -2055,22 +2057,22 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_shadowOffsetX(const QV4::Builti \sa shadowOffsetX */ -QV4::ReturnedValue QQuickJSContext2D::method_get_shadowOffsetY(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2D::method_get_shadowOffsetY(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject); + QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject); CHECK_CONTEXT(r) RETURN_RESULT(QV4::Encode(r->d()->context->state.shadowOffsetY)); } -QV4::ReturnedValue QQuickJSContext2D::method_set_shadowOffsetY(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2D::method_set_shadowOffsetY(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject); + QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject); CHECK_CONTEXT_SETTER(r) - qreal offsetY = callData->argc() ? callData->args[0].toNumber() : qt_qnan(); + qreal offsetY = argc ? argv[0].toNumber() : qt_qnan(); if (qt_is_finite(offsetY) && offsetY != r->d()->context->state.shadowOffsetY) { r->d()->context->state.shadowOffsetY = offsetY; r->d()->context->buffer()->setShadowOffsetY(offsetY); @@ -2079,22 +2081,22 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_shadowOffsetY(const QV4::Builti } #if QT_CONFIG(quick_path) -QV4::ReturnedValue QQuickJSContext2D::method_get_path(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2D::method_get_path(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject); + QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject); CHECK_CONTEXT(r) RETURN_RESULT(r->d()->context->m_v4path.value()); } -QV4::ReturnedValue QQuickJSContext2D::method_set_path(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2D::method_set_path(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject); + QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject); CHECK_CONTEXT_SETTER(r) - QV4::ScopedValue value(scope, callData->argument(0)); + QV4::ScopedValue value(scope, argc ? argv[0] : QV4::Primitive::undefinedValue()); r->d()->context->beginPath(); QV4::Scoped<QV4::QObjectWrapper> qobjectWrapper(scope, value); if (!!qobjectWrapper) { @@ -2114,20 +2116,20 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_path(const QV4::BuiltinFunction \qmlmethod object QtQuick::Context2D::clearRect(real x, real y, real w, real h) Clears all pixels on the canvas in the given rectangle to transparent black. */ -QV4::ReturnedValue QQuickJSContext2DPrototype::method_clearRect(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2DPrototype::method_clearRect(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject); + QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject); CHECK_CONTEXT(r) - if (callData->argc() >= 4) - r->d()->context->clearRect(callData->args[0].toNumber(), - callData->args[1].toNumber(), - callData->args[2].toNumber(), - callData->args[3].toNumber()); + if (argc >= 4) + r->d()->context->clearRect(argv[0].toNumber(), + argv[1].toNumber(), + argv[2].toNumber(), + argv[3].toNumber()); - RETURN_RESULT(callData->thisObject); + RETURN_RESULT(*thisObject); } /*! @@ -2136,15 +2138,15 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_clearRect(const QV4::Built \sa fillStyle */ -QV4::ReturnedValue QQuickJSContext2DPrototype::method_fillRect(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2DPrototype::method_fillRect(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject); + QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject); CHECK_CONTEXT(r) - if (callData->argc() >= 4) - r->d()->context->fillRect(callData->args[0].toNumber(), callData->args[1].toNumber(), callData->args[2].toNumber(), callData->args[3].toNumber()); - RETURN_RESULT(callData->thisObject); + if (argc >= 4) + r->d()->context->fillRect(argv[0].toNumber(), argv[1].toNumber(), argv[2].toNumber(), argv[3].toNumber()); + RETURN_RESULT(*thisObject); } @@ -2158,16 +2160,16 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_fillRect(const QV4::Builti \sa lineJoin \sa miterLimit */ -QV4::ReturnedValue QQuickJSContext2DPrototype::method_strokeRect(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2DPrototype::method_strokeRect(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject); + QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject); CHECK_CONTEXT(r) - if (callData->argc() >= 4) - r->d()->context->strokeRect(callData->args[0].toNumber(), callData->args[1].toNumber(), callData->args[2].toNumber(), callData->args[3].toNumber()); + if (argc >= 4) + r->d()->context->strokeRect(argv[0].toNumber(), argv[1].toNumber(), argv[2].toNumber(), argv[3].toNumber()); - RETURN_RESULT(callData->thisObject); + RETURN_RESULT(*thisObject); } @@ -2192,32 +2194,32 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_strokeRect(const QV4::Buil \sa arcTo, {http://www.w3.org/TR/2dcontext/#dom-context-2d-arc}{W3C's 2D Context Standard for arc()} */ -QV4::ReturnedValue QQuickJSContext2DPrototype::method_arc(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2DPrototype::method_arc(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject); + QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject); CHECK_CONTEXT(r) - if (callData->argc() >= 5) { + if (argc >= 5) { bool antiClockwise = false; - if (callData->argc() == 6) - antiClockwise = callData->args[5].toBoolean(); + if (argc == 6) + antiClockwise = argv[5].toBoolean(); - qreal radius = callData->args[2].toNumber(); + qreal radius = argv[2].toNumber(); if (qt_is_finite(radius) && radius < 0) THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR, "Incorrect argument radius"); - r->d()->context->arc(callData->args[0].toNumber(), - callData->args[1].toNumber(), + r->d()->context->arc(argv[0].toNumber(), + argv[1].toNumber(), radius, - callData->args[3].toNumber(), - callData->args[4].toNumber(), + argv[3].toNumber(), + argv[4].toNumber(), antiClockwise); } - RETURN_RESULT(callData->thisObject); + RETURN_RESULT(*thisObject); } @@ -2244,26 +2246,26 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_arc(const QV4::BuiltinFunc \sa arc, {http://www.w3.org/TR/2dcontext/#dom-context-2d-arcto}{W3C's 2D Context Standard for arcTo()} */ -QV4::ReturnedValue QQuickJSContext2DPrototype::method_arcTo(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2DPrototype::method_arcTo(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject); + QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject); CHECK_CONTEXT(r) - if (callData->argc() >= 5) { - qreal radius = callData->args[4].toNumber(); + if (argc >= 5) { + qreal radius = argv[4].toNumber(); if (qt_is_finite(radius) && radius < 0) THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR, "Incorrect argument radius"); - r->d()->context->arcTo(callData->args[0].toNumber(), - callData->args[1].toNumber(), - callData->args[2].toNumber(), - callData->args[3].toNumber(), + r->d()->context->arcTo(argv[0].toNumber(), + argv[1].toNumber(), + argv[2].toNumber(), + argv[3].toNumber(), radius); } - RETURN_RESULT(callData->thisObject); + RETURN_RESULT(*thisObject); } @@ -2272,15 +2274,15 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_arcTo(const QV4::BuiltinFu Resets the current path to a new path. */ -QV4::ReturnedValue QQuickJSContext2DPrototype::method_beginPath(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2DPrototype::method_beginPath(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject); + QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject); CHECK_CONTEXT(r) r->d()->context->beginPath(); - RETURN_RESULT(callData->thisObject); + RETURN_RESULT(*thisObject); } @@ -2303,26 +2305,26 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_beginPath(const QV4::Built \sa {http://www.w3.org/TR/2dcontext/#dom-context-2d-beziercurveto}{W3C 2d context standard for bezierCurveTo} \sa {http://www.openrise.com/lab/FlowerPower/}{The beautiful flower demo by using bezierCurveTo} */ -QV4::ReturnedValue QQuickJSContext2DPrototype::method_bezierCurveTo(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2DPrototype::method_bezierCurveTo(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject); + QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject); CHECK_CONTEXT(r) - if (callData->argc() >= 6) { - qreal cp1x = callData->args[0].toNumber(); - qreal cp1y = callData->args[1].toNumber(); - qreal cp2x = callData->args[2].toNumber(); - qreal cp2y = callData->args[3].toNumber(); - qreal x = callData->args[4].toNumber(); - qreal y = callData->args[5].toNumber(); + if (argc >= 6) { + qreal cp1x = argv[0].toNumber(); + qreal cp1y = argv[1].toNumber(); + qreal cp2x = argv[2].toNumber(); + qreal cp2y = argv[3].toNumber(); + qreal x = argv[4].toNumber(); + qreal y = argv[5].toNumber(); if (!qt_is_finite(cp1x) || !qt_is_finite(cp1y) || !qt_is_finite(cp2x) || !qt_is_finite(cp2y) || !qt_is_finite(x) || !qt_is_finite(y)) RETURN_UNDEFINED(); r->d()->context->bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y); } - RETURN_RESULT(callData->thisObject); + RETURN_RESULT(*thisObject); } /*! @@ -2349,14 +2351,14 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_bezierCurveTo(const QV4::B \sa fill() \sa {http://www.w3.org/TR/2dcontext/#dom-context-2d-clip}{W3C 2d context standard for clip} */ -QV4::ReturnedValue QQuickJSContext2DPrototype::method_clip(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2DPrototype::method_clip(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject); + QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject); CHECK_CONTEXT(r) r->d()->context->clip(); - RETURN_RESULT(callData->thisObject); + RETURN_RESULT(*thisObject); } /*! @@ -2366,15 +2368,15 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_clip(const QV4::BuiltinFun \sa {http://www.w3.org/TR/2dcontext/#dom-context-2d-closepath}{W3C 2d context standard for closePath} */ -QV4::ReturnedValue QQuickJSContext2DPrototype::method_closePath(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2DPrototype::method_closePath(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject); + QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject); CHECK_CONTEXT(r) r->d()->context->closePath(); - RETURN_RESULT(callData->thisObject); + RETURN_RESULT(*thisObject); } /*! @@ -2386,13 +2388,13 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_closePath(const QV4::Built \sa fillStyle */ -QV4::ReturnedValue QQuickJSContext2DPrototype::method_fill(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2DPrototype::method_fill(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject); + QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject); CHECK_CONTEXT(r); r->d()->context->fill(); - RETURN_RESULT(callData->thisObject); + RETURN_RESULT(*thisObject); } /*! @@ -2400,15 +2402,15 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_fill(const QV4::BuiltinFun Draws a line from the current position to the point (x, y). */ -QV4::ReturnedValue QQuickJSContext2DPrototype::method_lineTo(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2DPrototype::method_lineTo(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject); + QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject); CHECK_CONTEXT(r) - if (callData->argc() >= 2) { - qreal x = callData->args[0].toNumber(); - qreal y = callData->args[1].toNumber(); + if (argc >= 2) { + qreal x = argv[0].toNumber(); + qreal y = argv[1].toNumber(); if (!qt_is_finite(x) || !qt_is_finite(y)) RETURN_UNDEFINED(); @@ -2416,7 +2418,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_lineTo(const QV4::BuiltinF r->d()->context->lineTo(x, y); } - RETURN_RESULT(callData->thisObject); + RETURN_RESULT(*thisObject); } /*! @@ -2424,22 +2426,22 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_lineTo(const QV4::BuiltinF Creates a new subpath with the given point. */ -QV4::ReturnedValue QQuickJSContext2DPrototype::method_moveTo(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2DPrototype::method_moveTo(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject); + QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject); CHECK_CONTEXT(r) - if (callData->argc() >= 2) { - qreal x = callData->args[0].toNumber(); - qreal y = callData->args[1].toNumber(); + if (argc >= 2) { + qreal x = argv[0].toNumber(); + qreal y = argv[1].toNumber(); if (!qt_is_finite(x) || !qt_is_finite(y)) RETURN_UNDEFINED(); r->d()->context->moveTo(x, y); } - RETURN_RESULT(callData->thisObject); + RETURN_RESULT(*thisObject); } /*! @@ -2449,17 +2451,17 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_moveTo(const QV4::BuiltinF See \l{http://www.w3.org/TR/2dcontext/#dom-context-2d-quadraticcurveto}{W3C 2d context standard for quadraticCurveTo} */ -QV4::ReturnedValue QQuickJSContext2DPrototype::method_quadraticCurveTo(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2DPrototype::method_quadraticCurveTo(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject); + QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject); CHECK_CONTEXT(r) - if (callData->argc() >= 4) { - qreal cpx = callData->args[0].toNumber(); - qreal cpy = callData->args[1].toNumber(); - qreal x = callData->args[2].toNumber(); - qreal y = callData->args[3].toNumber(); + if (argc >= 4) { + qreal cpx = argv[0].toNumber(); + qreal cpy = argv[1].toNumber(); + qreal x = argv[2].toNumber(); + qreal y = argv[3].toNumber(); if (!qt_is_finite(cpx) || !qt_is_finite(cpy) || !qt_is_finite(x) || !qt_is_finite(y)) RETURN_UNDEFINED(); @@ -2467,7 +2469,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_quadraticCurveTo(const QV4 r->d()->context->quadraticCurveTo(cpx, cpy, x, y); } - RETURN_RESULT(callData->thisObject); + RETURN_RESULT(*thisObject); } /*! @@ -2475,15 +2477,15 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_quadraticCurveTo(const QV4 Adds a rectangle at position (\c x, \c y), with the given width \c w and height \c h, as a closed subpath. */ -QV4::ReturnedValue QQuickJSContext2DPrototype::method_rect(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2DPrototype::method_rect(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject); + QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject); CHECK_CONTEXT(r) - if (callData->argc() >= 4) - r->d()->context->rect(callData->args[0].toNumber(), callData->args[1].toNumber(), callData->args[2].toNumber(), callData->args[3].toNumber()); - RETURN_RESULT(callData->thisObject); + if (argc >= 4) + r->d()->context->rect(argv[0].toNumber(), argv[1].toNumber(), argv[2].toNumber(), argv[3].toNumber()); + RETURN_RESULT(*thisObject); } @@ -2493,20 +2495,20 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_rect(const QV4::BuiltinFun Adds the given rectangle rect with rounded corners to the path. The \c xRadius and \c yRadius arguments specify the radius of the ellipses defining the corners of the rounded rectangle. */ -QV4::ReturnedValue QQuickJSContext2DPrototype::method_roundedRect(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2DPrototype::method_roundedRect(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject); + QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject); CHECK_CONTEXT(r) - if (callData->argc() >= 6) - r->d()->context->roundedRect(callData->args[0].toNumber() - , callData->args[1].toNumber() - , callData->args[2].toNumber() - , callData->args[3].toNumber() - , callData->args[4].toNumber() - , callData->args[5].toNumber()); - RETURN_RESULT(callData->thisObject); + if (argc >= 6) + r->d()->context->roundedRect(argv[0].toNumber() + , argv[1].toNumber() + , argv[2].toNumber() + , argv[3].toNumber() + , argv[4].toNumber() + , argv[5].toNumber()); + RETURN_RESULT(*thisObject); } @@ -2518,16 +2520,16 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_roundedRect(const QV4::Bui The ellipse is composed of a clockwise curve, starting and finishing at zero degrees (the 3 o'clock position). */ -QV4::ReturnedValue QQuickJSContext2DPrototype::method_ellipse(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2DPrototype::method_ellipse(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject); + QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject); CHECK_CONTEXT(r) - if (callData->argc() >= 4) - r->d()->context->ellipse(callData->args[0].toNumber(), callData->args[1].toNumber(), callData->args[2].toNumber(), callData->args[3].toNumber()); + if (argc >= 4) + r->d()->context->ellipse(argv[0].toNumber(), argv[1].toNumber(), argv[2].toNumber(), argv[3].toNumber()); - RETURN_RESULT(callData->thisObject); + RETURN_RESULT(*thisObject); } @@ -2537,22 +2539,22 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_ellipse(const QV4::Builtin Adds the given \c text to the path as a set of closed subpaths created from the current context font supplied. The subpaths are positioned so that the left end of the text's baseline lies at the point specified by (\c x, \c y). */ -QV4::ReturnedValue QQuickJSContext2DPrototype::method_text(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2DPrototype::method_text(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject); + QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject); CHECK_CONTEXT(r) - if (callData->argc() >= 3) { - qreal x = callData->args[1].toNumber(); - qreal y = callData->args[2].toNumber(); + if (argc >= 3) { + qreal x = argv[1].toNumber(); + qreal y = argv[2].toNumber(); if (!qt_is_finite(x) || !qt_is_finite(y)) RETURN_UNDEFINED(); - r->d()->context->text(callData->args[0].toQStringNoThrow(), x, y); + r->d()->context->text(argv[0].toQStringNoThrow(), x, y); } - RETURN_RESULT(callData->thisObject); + RETURN_RESULT(*thisObject); } /*! @@ -2564,14 +2566,14 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_text(const QV4::BuiltinFun \sa strokeStyle */ -QV4::ReturnedValue QQuickJSContext2DPrototype::method_stroke(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2DPrototype::method_stroke(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject); + QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject); CHECK_CONTEXT(r) r->d()->context->stroke(); - RETURN_RESULT(callData->thisObject); + RETURN_RESULT(*thisObject); } @@ -2582,31 +2584,31 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_stroke(const QV4::BuiltinF \sa {http://www.w3.org/TR/2dcontext/#dom-context-2d-ispointinpath}{W3C 2d context standard for isPointInPath} */ -QV4::ReturnedValue QQuickJSContext2DPrototype::method_isPointInPath(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2DPrototype::method_isPointInPath(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject); + QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject); CHECK_CONTEXT(r) bool pointInPath = false; - if (callData->argc() >= 2) - pointInPath = r->d()->context->isPointInPath(callData->args[0].toNumber(), callData->args[1].toNumber()); + if (argc >= 2) + pointInPath = r->d()->context->isPointInPath(argv[0].toNumber(), argv[1].toNumber()); RETURN_RESULT(QV4::Primitive::fromBoolean(pointInPath).asReturnedValue()); } -QV4::ReturnedValue QQuickJSContext2DPrototype::method_drawFocusRing(const QV4::BuiltinFunction *b, QV4::CallData *) +QV4::ReturnedValue QQuickJSContext2DPrototype::method_drawFocusRing(const QV4::FunctionObject *b, const QV4::Value *, const QV4::Value *, int) { QV4::Scope scope(b); THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "Context2D::drawFocusRing is not supported"); } -QV4::ReturnedValue QQuickJSContext2DPrototype::method_setCaretSelectionRect(const QV4::BuiltinFunction *b, QV4::CallData *) +QV4::ReturnedValue QQuickJSContext2DPrototype::method_setCaretSelectionRect(const QV4::FunctionObject *b, const QV4::Value *, const QV4::Value *, int) { QV4::Scope scope(b); THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "Context2D::setCaretSelectionRect is not supported"); } -QV4::ReturnedValue QQuickJSContext2DPrototype::method_caretBlinkRate(const QV4::BuiltinFunction *b, QV4::CallData *) +QV4::ReturnedValue QQuickJSContext2DPrototype::method_caretBlinkRate(const QV4::FunctionObject *b, const QV4::Value *, const QV4::Value *, int) { QV4::Scope scope(b); THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "Context2D::caretBlinkRate is not supported"); @@ -2635,22 +2637,22 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_caretBlinkRate(const QV4:: The default font value is "10px sans-serif". */ -QV4::ReturnedValue QQuickJSContext2D::method_get_font(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2D::method_get_font(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject); + QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject); CHECK_CONTEXT(r) RETURN_RESULT(scope.engine->newString(r->d()->context->state.font.toString())); } -QV4::ReturnedValue QQuickJSContext2D::method_set_font(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2D::method_set_font(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject); + QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject); CHECK_CONTEXT_SETTER(r) - QV4::ScopedString s(scope, callData->argument(0), QV4::ScopedString::Convert); + QV4::ScopedString s(scope, argc ? argv[0] : QV4::Primitive::undefinedValue(), QV4::ScopedString::Convert); if (scope.engine->hasException) RETURN_UNDEFINED(); QFont font = qt_font_from_string(s->toQString(), r->d()->context->state.font); @@ -2674,10 +2676,10 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_font(const QV4::BuiltinFunction \endlist Other values are ignored. The default value is "start". */ -QV4::ReturnedValue QQuickJSContext2D::method_get_textAlign(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2D::method_get_textAlign(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject); + QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject); CHECK_CONTEXT(r) switch (r->d()->context->state.textAlign) { @@ -2696,13 +2698,13 @@ QV4::ReturnedValue QQuickJSContext2D::method_get_textAlign(const QV4::BuiltinFun RETURN_RESULT(scope.engine->newString(QStringLiteral("start"))); } -QV4::ReturnedValue QQuickJSContext2D::method_set_textAlign(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2D::method_set_textAlign(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject); + QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject); CHECK_CONTEXT_SETTER(r) - QV4::ScopedString s(scope, callData->argument(0), QV4::ScopedString::Convert); + QV4::ScopedString s(scope, argc ? argv[0] : QV4::Primitive::undefinedValue(), QV4::ScopedString::Convert); if (scope.engine->hasException) RETURN_UNDEFINED(); QString textAlign = s->toQString(); @@ -2742,10 +2744,10 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_textAlign(const QV4::BuiltinFun \endlist Other values are ignored. The default value is "alphabetic". */ -QV4::ReturnedValue QQuickJSContext2D::method_get_textBaseline(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2D::method_get_textBaseline(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject); + QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject); CHECK_CONTEXT(r) switch (r->d()->context->state.textBaseline) { @@ -2764,12 +2766,12 @@ QV4::ReturnedValue QQuickJSContext2D::method_get_textBaseline(const QV4::Builtin RETURN_RESULT(scope.engine->newString(QStringLiteral("alphabetic"))); } -QV4::ReturnedValue QQuickJSContext2D::method_set_textBaseline(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2D::method_set_textBaseline(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject); + QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject); CHECK_CONTEXT_SETTER(r) - QV4::ScopedString s(scope, callData->argument(0), QV4::ScopedString::Convert); + QV4::ScopedString s(scope, argc ? argv[0] : QV4::Primitive::undefinedValue(), QV4::ScopedString::Convert); if (scope.engine->hasException) RETURN_UNDEFINED(); QString textBaseline = s->toQString(); @@ -2802,22 +2804,22 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_textBaseline(const QV4::Builtin \sa textBaseline \sa strokeText */ -QV4::ReturnedValue QQuickJSContext2DPrototype::method_fillText(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2DPrototype::method_fillText(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject); + QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject); CHECK_CONTEXT(r) - if (callData->argc() >= 3) { - qreal x = callData->args[1].toNumber(); - qreal y = callData->args[2].toNumber(); + if (argc >= 3) { + qreal x = argv[1].toNumber(); + qreal y = argv[2].toNumber(); if (!qt_is_finite(x) || !qt_is_finite(y)) RETURN_UNDEFINED(); - QPainterPath textPath = r->d()->context->createTextGlyphs(x, y, callData->args[0].toQStringNoThrow()); + QPainterPath textPath = r->d()->context->createTextGlyphs(x, y, argv[0].toQStringNoThrow()); r->d()->context->buffer()->fill(textPath); } - RETURN_RESULT(callData->thisObject); + RETURN_RESULT(*thisObject); } /*! \qmlmethod object QtQuick::Context2D::strokeText(text, x, y) @@ -2827,16 +2829,16 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_fillText(const QV4::Builti \sa textBaseline \sa fillText */ -QV4::ReturnedValue QQuickJSContext2DPrototype::method_strokeText(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2DPrototype::method_strokeText(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject); + QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject); CHECK_CONTEXT(r) - if (callData->argc() >= 3) - r->d()->context->drawText(callData->args[0].toQStringNoThrow(), callData->args[1].toNumber(), callData->args[2].toNumber(), false); + if (argc >= 3) + r->d()->context->drawText(argv[0].toQStringNoThrow(), argv[1].toNumber(), argv[2].toNumber(), false); - RETURN_RESULT(callData->thisObject); + RETURN_RESULT(*thisObject); } /*! @@ -2845,15 +2847,15 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_strokeText(const QV4::Buil Returns an object with a \c width property, whose value is equivalent to calling \l {QFontMetrics::width()} with the given \a text in the current font. */ -QV4::ReturnedValue QQuickJSContext2DPrototype::method_measureText(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2DPrototype::method_measureText(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject); + QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject); CHECK_CONTEXT(r) - if (callData->argc() >= 1) { + if (argc >= 1) { QFontMetrics fm(r->d()->context->state.font); - uint width = fm.width(callData->args[0].toQStringNoThrow()); + uint width = fm.width(argv[0].toQStringNoThrow()); QV4::ScopedObject tm(scope, scope.engine->newObject()); tm->put(QV4::ScopedString(scope, scope.engine->newIdentifier(QStringLiteral("width"))).getPointer(), QV4::ScopedValue(scope, QV4::Primitive::fromDouble(width))); @@ -2921,15 +2923,15 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_measureText(const QV4::Bui \sa {http://www.w3.org/TR/2dcontext/#dom-context-2d-drawimage}{W3C 2d context standard for drawImage} */ -QV4::ReturnedValue QQuickJSContext2DPrototype::method_drawImage(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2DPrototype::method_drawImage(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject); + QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject); CHECK_CONTEXT(r) qreal sx, sy, sw, sh, dx, dy, dw, dh; - if (!callData->argc()) + if (!argc) RETURN_UNDEFINED(); //FIXME:This function should be moved to QQuickContext2D::drawImage(...) @@ -2938,7 +2940,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_drawImage(const QV4::Built QQmlRefPointer<QQuickCanvasPixmap> pixmap; - QV4::ScopedValue arg(scope, callData->args[0]); + QV4::ScopedValue arg(scope, argv[0]); if (arg->isString()) { QUrl url(arg->toQString()); if (!url.isValid()) @@ -2981,27 +2983,27 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_drawImage(const QV4::Built if (pixmap.isNull() || !pixmap->isValid()) RETURN_UNDEFINED(); - if (callData->argc() >= 9) { - sx = callData->args[1].toNumber(); - sy = callData->args[2].toNumber(); - sw = callData->args[3].toNumber(); - sh = callData->args[4].toNumber(); - dx = callData->args[5].toNumber(); - dy = callData->args[6].toNumber(); - dw = callData->args[7].toNumber(); - dh = callData->args[8].toNumber(); - } else if (callData->argc() >= 5) { + if (argc >= 9) { + sx = argv[1].toNumber(); + sy = argv[2].toNumber(); + sw = argv[3].toNumber(); + sh = argv[4].toNumber(); + dx = argv[5].toNumber(); + dy = argv[6].toNumber(); + dw = argv[7].toNumber(); + dh = argv[8].toNumber(); + } else if (argc >= 5) { sx = 0; sy = 0; sw = pixmap->width(); sh = pixmap->height(); - dx = callData->args[1].toNumber(); - dy = callData->args[2].toNumber(); - dw = callData->args[3].toNumber(); - dh = callData->args[4].toNumber(); - } else if (callData->argc() >= 3) { - dx = callData->args[1].toNumber(); - dy = callData->args[2].toNumber(); + dx = argv[1].toNumber(); + dy = argv[2].toNumber(); + dw = argv[3].toNumber(); + dh = argv[4].toNumber(); + } else if (argc >= 3) { + dx = argv[1].toNumber(); + dy = argv[2].toNumber(); sx = 0; sy = 0; sw = pixmap->width(); @@ -3034,7 +3036,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_drawImage(const QV4::Built r->d()->context->buffer()->drawPixmap(pixmap, QRectF(sx, sy, sw, sh), QRectF(dx, dy, dw, dh)); - RETURN_RESULT(callData->thisObject); + RETURN_RESULT(*thisObject); } // pixel manipulation @@ -3061,10 +3063,10 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_drawImage(const QV4::Built \qmlproperty int QtQuick::CanvasImageData::width Holds the actual width dimension of the data in the ImageData object, in device pixels. */ -QV4::ReturnedValue QQuickJSContext2DImageData::method_get_width(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2DImageData::method_get_width(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, callData->thisObject); + QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, *thisObject); if (!imageData) THROW_TYPE_ERROR(); QV4::Scoped<QQuickJSContext2DPixelData> r(scope, imageData->d()->pixelData.as<QQuickJSContext2DPixelData>()); @@ -3076,10 +3078,10 @@ QV4::ReturnedValue QQuickJSContext2DImageData::method_get_width(const QV4::Built \qmlproperty int QtQuick::CanvasImageData::height Holds the actual height dimension of the data in the ImageData object, in device pixels. */ -QV4::ReturnedValue QQuickJSContext2DImageData::method_get_height(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2DImageData::method_get_height(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, callData->thisObject); + QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, *thisObject); if (!imageData) THROW_TYPE_ERROR(); QV4::Scoped<QQuickJSContext2DPixelData> r(scope, imageData->d()->pixelData.as<QQuickJSContext2DPixelData>()); @@ -3091,10 +3093,10 @@ QV4::ReturnedValue QQuickJSContext2DImageData::method_get_height(const QV4::Buil \qmlproperty object QtQuick::CanvasImageData::data Holds the one-dimensional array containing the data in RGBA order, as integers in the range 0 to 255. */ -QV4::ReturnedValue QQuickJSContext2DImageData::method_get_data(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2DImageData::method_get_data(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, callData->thisObject); + QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, *thisObject); if (!imageData) THROW_TYPE_ERROR(); RETURN_RESULT(imageData->d()->pixelData); @@ -3118,10 +3120,10 @@ QV4::ReturnedValue QQuickJSContext2DImageData::method_get_data(const QV4::Builti The length attribute of a CanvasPixelArray object must return this h×w×4 number value. This property is read only. */ -QV4::ReturnedValue QQuickJSContext2DPixelData::proto_get_length(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2DPixelData::proto_get_length(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2DPixelData> r(scope, callData->thisObject.as<QQuickJSContext2DPixelData>()); + QV4::Scoped<QQuickJSContext2DPixelData> r(scope, thisObject->as<QQuickJSContext2DPixelData>()); if (!r || r->d()->image->isNull()) RETURN_UNDEFINED(); @@ -3217,14 +3219,14 @@ bool QQuickJSContext2DPixelData::putIndexed(QV4::Managed *m, uint index, const Q \sa Canvas::loadImage(), QtQuick::Canvas::unloadImage(), QtQuick::Canvas::isImageLoaded */ -QV4::ReturnedValue QQuickJSContext2DPrototype::method_createImageData(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2DPrototype::method_createImageData(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>()); + QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>()); CHECK_CONTEXT(r) - if (callData->argc() == 1) { - QV4::ScopedValue arg0(scope, callData->args[0]); + if (argc == 1) { + QV4::ScopedValue arg0(scope, argv[0]); QV4::Scoped<QQuickJSContext2DImageData> imgData(scope, arg0); if (!!imgData) { QV4::Scoped<QQuickJSContext2DPixelData> pa(scope, imgData->d()->pixelData.as<QQuickJSContext2DPixelData>()); @@ -3237,9 +3239,9 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createImageData(const QV4: QImage image = r->d()->context->createPixmap(QUrl(arg0->toQStringNoThrow()))->image(); RETURN_RESULT(qt_create_image_data(image.width(), image.height(), scope.engine, image)); } - } else if (callData->argc() == 2) { - qreal w = callData->args[0].toNumber(); - qreal h = callData->args[1].toNumber(); + } else if (argc == 2) { + qreal w = argv[0].toNumber(); + qreal h = argv[1].toNumber(); if (!qt_is_finite(w) || !qt_is_finite(h)) THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "createImageData(): invalid arguments"); @@ -3256,17 +3258,17 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createImageData(const QV4: \qmlmethod CanvasImageData QtQuick::Context2D::getImageData(real sx, real sy, real sw, real sh) Returns an CanvasImageData object containing the image data for the given rectangle of the canvas. */ -QV4::ReturnedValue QQuickJSContext2DPrototype::method_getImageData(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2DPrototype::method_getImageData(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>()); + QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>()); CHECK_CONTEXT(r) - if (callData->argc() >= 4) { - qreal x = callData->args[0].toNumber(); - qreal y = callData->args[1].toNumber(); - qreal w = callData->args[2].toNumber(); - qreal h = callData->args[3].toNumber(); + if (argc >= 4) { + qreal x = argv[0].toNumber(); + qreal y = argv[1].toNumber(); + qreal w = argv[2].toNumber(); + qreal h = argv[3].toNumber(); if (!qt_is_finite(x) || !qt_is_finite(y) || !qt_is_finite(w) || !qt_is_finite(h)) THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "getImageData(): Invalid arguments"); @@ -3283,20 +3285,20 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_getImageData(const QV4::Bu \qmlmethod object QtQuick::Context2D::putImageData(CanvasImageData imageData, real dx, real dy, real dirtyX, real dirtyY, real dirtyWidth, real dirtyHeight) Paints the data from the given ImageData object onto the canvas. If a dirty rectangle (\a dirtyX, \a dirtyY, \a dirtyWidth, \a dirtyHeight) is provided, only the pixels from that rectangle are painted. */ -QV4::ReturnedValue QQuickJSContext2DPrototype::method_putImageData(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickJSContext2DPrototype::method_putImageData(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { QV4::Scope scope(b); - QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>()); + QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>()); CHECK_CONTEXT(r) - if (callData->argc() < 7) + if (argc < 7) RETURN_UNDEFINED(); - QV4::ScopedValue arg0(scope, callData->args[0]); + QV4::ScopedValue arg0(scope, argv[0]); if (!arg0->isObject()) THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR, "Context2D::putImageData, the image data type mismatch"); - qreal dx = callData->args[1].toNumber(); - qreal dy = callData->args[2].toNumber(); + qreal dx = argv[1].toNumber(); + qreal dy = argv[2].toNumber(); qreal w, h, dirtyX, dirtyY, dirtyWidth, dirtyHeight; if (!qt_is_finite(dx) || !qt_is_finite(dy)) @@ -3311,11 +3313,11 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_putImageData(const QV4::Bu w = pixelArray->d()->image->width(); h = pixelArray->d()->image->height(); - if (callData->argc() == 7) { - dirtyX = callData->args[3].toNumber(); - dirtyY = callData->args[4].toNumber(); - dirtyWidth = callData->args[5].toNumber(); - dirtyHeight = callData->args[6].toNumber(); + if (argc == 7) { + dirtyX = argv[3].toNumber(); + dirtyY = argv[4].toNumber(); + dirtyWidth = argv[5].toNumber(); + dirtyHeight = argv[6].toNumber(); if (!qt_is_finite(dirtyX) || !qt_is_finite(dirtyY) || !qt_is_finite(dirtyWidth) || !qt_is_finite(dirtyHeight)) THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "putImageData() : Invalid arguments"); @@ -3362,7 +3364,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_putImageData(const QV4::Bu r->d()->context->buffer()->drawImage(image, QRectF(dirtyX, dirtyY, dirtyWidth, dirtyHeight), QRectF(dx, dy, dirtyWidth, dirtyHeight)); } - RETURN_RESULT(callData->thisObject); + RETURN_RESULT(*thisObject); } /*! @@ -3385,25 +3387,25 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_putImageData(const QV4::Bu gradient.addColorStop(0.7, 'rgba(0, 255, 255, 1'); \endcode */ -QV4::ReturnedValue QQuickContext2DStyle::gradient_proto_addColorStop(const QV4::BuiltinFunction *b, QV4::CallData *callData) +QV4::ReturnedValue QQuickContext2DStyle::gradient_proto_addColorStop(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { QV4::Scope scope(b); - QV4::Scoped<QQuickContext2DStyle> style(scope, callData->thisObject.as<QQuickContext2DStyle>()); + QV4::Scoped<QQuickContext2DStyle> style(scope, thisObject->as<QQuickContext2DStyle>()); if (!style) THROW_GENERIC_ERROR("Not a CanvasGradient object"); - if (callData->argc() == 2) { + if (argc == 2) { if (!style->d()->brush->gradient()) THROW_GENERIC_ERROR("Not a valid CanvasGradient object, can't get the gradient information"); QGradient gradient = *(style->d()->brush->gradient()); - qreal pos = callData->args[0].toNumber(); + qreal pos = argv[0].toNumber(); QColor color; - if (callData->args[1].as<Object>()) { - color = scope.engine->toVariant(callData->args[1], qMetaTypeId<QColor>()).value<QColor>(); + if (argv[1].as<Object>()) { + color = scope.engine->toVariant(argv[1], qMetaTypeId<QColor>()).value<QColor>(); } else { - color = qt_color_from_string(callData->args[1]); + color = qt_color_from_string(argv[1]); } if (pos < 0.0 || pos > 1.0 || !qt_is_finite(pos)) { THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR, "CanvasGradient: parameter offset out of range"); @@ -3417,7 +3419,7 @@ QV4::ReturnedValue QQuickContext2DStyle::gradient_proto_addColorStop(const QV4:: *style->d()->brush = gradient; } - return callData->thisObject.asReturnedValue(); + return thisObject->asReturnedValue(); } void QQuickContext2D::scale(qreal x, qreal y) @@ -4049,10 +4051,10 @@ QMutex QQuickContext2D::mutex; QQuickContext2D::QQuickContext2D(QObject *parent) : QQuickCanvasContext(parent) , m_buffer(new QQuickContext2DCommandBuffer) - , m_v4engine(0) - , m_surface(0) - , m_glContext(0) - , m_thread(0) + , m_v4engine(nullptr) + , m_surface(nullptr) + , m_glContext(nullptr) + , m_thread(nullptr) , m_grabbed(false) { } @@ -4060,7 +4062,7 @@ QQuickContext2D::QQuickContext2D(QObject *parent) QQuickContext2D::~QQuickContext2D() { mutex.lock(); - m_texture->setItem(0); + m_texture->setItem(nullptr); delete m_buffer; if (m_renderTarget == QQuickCanvasItem::FramebufferObject) { @@ -4240,7 +4242,7 @@ QImage QQuickContext2D::toImage(const QRectF& bounds) } else { #if QT_CONFIG(opengl) QQuickWindow *window = m_canvas->window(); - QOpenGLContext *ctx = window ? window->openglContext() : 0; + QOpenGLContext *ctx = window ? window->openglContext() : nullptr; if (ctx && ctx->isValid()) { if (ctx == QOpenGLContext::currentContext()) { flush(); @@ -4308,7 +4310,7 @@ QQuickContext2DEngineData::QQuickContext2DEngineData(QV4::ExecutionEngine *v4) gradientProto = proto; proto = scope.engine->newObject(); - proto->defineAccessorProperty(scope.engine->id_length(), QQuickJSContext2DPixelData::proto_get_length, 0); + proto->defineAccessorProperty(scope.engine->id_length(), QQuickJSContext2DPixelData::proto_get_length, nullptr); pixelArrayProto = proto; } @@ -4392,7 +4394,7 @@ void QQuickContext2D::setV4Engine(QV4::ExecutionEngine *engine) if (m_v4engine != engine) { m_v4engine = engine; - if (m_v4engine == 0) + if (m_v4engine == nullptr) return; QQuickContext2DEngineData *ed = engineData(engine); diff --git a/src/quick/items/context2d/qquickcontext2d_p.h b/src/quick/items/context2d/qquickcontext2d_p.h index 334bf08329..4cc07027b1 100644 --- a/src/quick/items/context2d/qquickcontext2d_p.h +++ b/src/quick/items/context2d/qquickcontext2d_p.h @@ -181,7 +181,7 @@ public: QQuickContext2D::TextBaseLineType textBaseline; }; - QQuickContext2D(QObject *parent = 0); + QQuickContext2D(QObject *parent = nullptr); ~QQuickContext2D(); QStringList contextNames() const override; @@ -199,7 +199,7 @@ public: QQuickCanvasItem* canvas() const { return m_canvas; } QQuickContext2DCommandBuffer* buffer() const { return m_buffer; } - bool bufferValid() const { return m_buffer != 0; } + bool bufferValid() const { return m_buffer != nullptr; } void popState(); void pushState(); void reset(); diff --git a/src/quick/items/context2d/qquickcontext2dtexture.cpp b/src/quick/items/context2d/qquickcontext2dtexture.cpp index a8bf14ba9f..69ff3b3852 100644 --- a/src/quick/items/context2d/qquickcontext2dtexture.cpp +++ b/src/quick/items/context2d/qquickcontext2dtexture.cpp @@ -93,12 +93,12 @@ struct GLAcquireContext { }; #endif QQuickContext2DTexture::QQuickContext2DTexture() - : m_context(0) + : m_context(nullptr) #if QT_CONFIG(opengl) - , m_gl(0) + , m_gl(nullptr) #endif - , m_surface(0) - , m_item(0) + , m_surface(nullptr) + , m_item(nullptr) , m_canvasDevicePixelRatio(1) , m_canvasWindowChanged(false) , m_dirtyTexture(false) @@ -159,7 +159,7 @@ void QQuickContext2DTexture::setItem(QQuickCanvasItem* item) m_context = (QQuickContext2D*) item->rawContext(); // FIXME m_state = m_context->state; } else { - m_context = 0; + m_context = nullptr; } } @@ -257,7 +257,7 @@ void QQuickContext2DTexture::paintWithoutTiles(QQuickContext2DCommandBuffer *ccb bool QQuickContext2DTexture::canvasDestroyed() { - return m_item == 0; + return m_item == nullptr; } void QQuickContext2DTexture::paint(QQuickContext2DCommandBuffer *ccb) @@ -349,7 +349,7 @@ QRect QQuickContext2DTexture::createTiles(const QRect& window) int ht = xx + h1; int vt = yy + v1; - QQuickContext2DTile* tile = 0; + QQuickContext2DTile* tile = nullptr; QPoint pos(ht * tw, vt * th); QRect rect(pos, m_tileSize); @@ -420,9 +420,9 @@ static inline QSize npotAdjustedSize(const QSize &size) QQuickContext2DFBOTexture::QQuickContext2DFBOTexture() : QQuickContext2DTexture() - , m_fbo(0) - , m_multisampledFbo(0) - , m_paint_device(0) + , m_fbo(nullptr) + , m_multisampledFbo(nullptr) + , m_paint_device(nullptr) { m_displayTextures[0] = 0; m_displayTextures[1] = 0; @@ -567,15 +567,15 @@ QPaintDevice* QQuickContext2DFBOTexture::beginPainting() delete m_fbo; delete m_multisampledFbo; delete m_paint_device; - m_fbo = 0; - m_multisampledFbo = 0; - m_paint_device = 0; - return 0; + m_fbo = nullptr; + m_multisampledFbo = nullptr; + m_paint_device = nullptr; + return nullptr; } else if (!m_fbo || m_canvasWindowChanged) { delete m_fbo; delete m_multisampledFbo; delete m_paint_device; - m_paint_device = 0; + m_paint_device = nullptr; m_fboSize = npotAdjustedSize(m_canvasWindow.size() * m_canvasDevicePixelRatio); m_canvasWindowChanged = false; @@ -722,7 +722,7 @@ QPaintDevice* QQuickContext2DImageTexture::beginPainting() QQuickContext2DTexture::beginPainting(); if (m_canvasWindow.size().isEmpty()) - return 0; + return nullptr; if (m_canvasWindowChanged) { diff --git a/src/quick/items/context2d/qquickcontext2dtexture_p.h b/src/quick/items/context2d/qquickcontext2dtexture_p.h index 0e1fbd5d34..9c4870f328 100644 --- a/src/quick/items/context2d/qquickcontext2dtexture_p.h +++ b/src/quick/items/context2d/qquickcontext2dtexture_p.h @@ -146,7 +146,7 @@ protected: virtual QVector2D scaleFactor() const { return QVector2D(1, 1); } void paintWithoutTiles(QQuickContext2DCommandBuffer *ccb); - virtual QPaintDevice* beginPainting() {m_painting = true; return 0; } + virtual QPaintDevice* beginPainting() {m_painting = true; return nullptr; } virtual void endPainting() {m_painting = false;} virtual QQuickContext2DTile* createTile() const = 0; virtual void compositeTile(QQuickContext2DTile* tile) = 0; diff --git a/src/quick/items/context2d/qquickcontext2dtile.cpp b/src/quick/items/context2d/qquickcontext2dtile.cpp index d31fee7f91..0ee3de6bcc 100644 --- a/src/quick/items/context2d/qquickcontext2dtile.cpp +++ b/src/quick/items/context2d/qquickcontext2dtile.cpp @@ -49,7 +49,7 @@ QT_BEGIN_NAMESPACE QQuickContext2DTile::QQuickContext2DTile() : m_dirty(true) , m_rect(QRect(0, 0, 1, 1)) - , m_device(0) + , m_device(nullptr) { } @@ -95,12 +95,12 @@ QPainter* QQuickContext2DTile::createPainter(bool smooth, bool antialiasing) return &m_painter; } - return 0; + return nullptr; } #if QT_CONFIG(opengl) QQuickContext2DFBOTile::QQuickContext2DFBOTile() : QQuickContext2DTile() - , m_fbo(0) + , m_fbo(nullptr) { } diff --git a/src/quick/items/items.pri b/src/quick/items/items.pri index 0f8061b5ef..1acb3b5265 100644 --- a/src/quick/items/items.pri +++ b/src/quick/items/items.pri @@ -41,8 +41,6 @@ HEADERS += \ $$PWD/qquickflickable_p.h \ $$PWD/qquickflickable_p_p.h \ $$PWD/qquickflickablebehavior_p.h \ - $$PWD/qquickrepeater_p.h \ - $$PWD/qquickrepeater_p_p.h \ $$PWD/qquickloader_p.h \ $$PWD/qquickloader_p_p.h \ $$PWD/qquicktranslate_p.h \ @@ -89,7 +87,6 @@ SOURCES += \ $$PWD/qquickmousearea.cpp \ $$PWD/qquickpincharea.cpp \ $$PWD/qquickflickable.cpp \ - $$PWD/qquickrepeater.cpp \ $$PWD/qquickloader.cpp \ $$PWD/qquicktranslate.cpp \ $$PWD/qquickclipnode.cpp \ @@ -168,6 +165,15 @@ qtConfig(quick-flipable) { $$PWD/qquickflipable.cpp } +qtConfig(quick-repeater) { + HEADERS += \ + $$PWD/qquickrepeater_p.h \ + $$PWD/qquickrepeater_p_p.h + + SOURCES += \ + $$PWD/qquickrepeater.cpp +} + qtConfig(quick-shadereffect) { HEADERS += \ $$PWD/qquickshadereffectsource_p.h \ diff --git a/src/quick/items/qquickaccessibleattached.cpp b/src/quick/items/qquickaccessibleattached.cpp index c559ee8887..252d6538e2 100644 --- a/src/quick/items/qquickaccessibleattached.cpp +++ b/src/quick/items/qquickaccessibleattached.cpp @@ -410,7 +410,7 @@ void QQuickAccessibleAttached::setIgnored(bool ignored) bool QQuickAccessibleAttached::doAction(const QString &actionName) { - QMetaMethod *sig = 0; + QMetaMethod *sig = nullptr; if (actionName == QAccessibleActionInterface::pressAction()) sig = &sigPress; else if (actionName == QAccessibleActionInterface::toggleAction()) diff --git a/src/quick/items/qquickanchors.cpp b/src/quick/items/qquickanchors.cpp index 45b405bd82..8ee4229013 100644 --- a/src/quick/items/qquickanchors.cpp +++ b/src/quick/items/qquickanchors.cpp @@ -252,35 +252,35 @@ void QQuickAnchorsPrivate::clearItem(QQuickItem *item) if (!item) return; if (fill == item) - fill = 0; + fill = nullptr; if (centerIn == item) - centerIn = 0; + centerIn = nullptr; if (leftAnchorItem == item) { - leftAnchorItem = 0; + leftAnchorItem = nullptr; usedAnchors &= ~QQuickAnchors::LeftAnchor; } if (rightAnchorItem == item) { - rightAnchorItem = 0; + rightAnchorItem = nullptr; usedAnchors &= ~QQuickAnchors::RightAnchor; } if (topAnchorItem == item) { - topAnchorItem = 0; + topAnchorItem = nullptr; usedAnchors &= ~QQuickAnchors::TopAnchor; } if (bottomAnchorItem == item) { - bottomAnchorItem = 0; + bottomAnchorItem = nullptr; usedAnchors &= ~QQuickAnchors::BottomAnchor; } if (vCenterAnchorItem == item) { - vCenterAnchorItem = 0; + vCenterAnchorItem = nullptr; usedAnchors &= ~QQuickAnchors::VCenterAnchor; } if (hCenterAnchorItem == item) { - hCenterAnchorItem = 0; + hCenterAnchorItem = nullptr; usedAnchors &= ~QQuickAnchors::HCenterAnchor; } if (baselineAnchorItem == item) { - baselineAnchorItem = 0; + baselineAnchorItem = nullptr; usedAnchors &= ~QQuickAnchors::BaselineAnchor; } } @@ -462,7 +462,7 @@ void QQuickAnchorsPrivate::updateOnComplete() std::sort(dependencies, dependencies + 9); - QQuickItem *lastDependency = 0; + QQuickItem *lastDependency = nullptr; for (int i = 0; i < 9; ++i) { QQuickItem *dependency = dependencies[i]; if (lastDependency != dependency) { @@ -542,7 +542,7 @@ void QQuickAnchors::setFill(QQuickItem *f) void QQuickAnchors::resetFill() { - setFill(0); + setFill(nullptr); } QQuickItem *QQuickAnchors::centerIn() const @@ -578,7 +578,7 @@ void QQuickAnchors::setCenterIn(QQuickItem* c) void QQuickAnchors::resetCenterIn() { - setCenterIn(0); + setCenterIn(nullptr); } bool QQuickAnchorsPrivate::calcStretch(QQuickItem *edge1Item, @@ -1324,6 +1324,19 @@ QQuickAnchors::Anchors QQuickAnchors::usedAnchors() const return static_cast<QQuickAnchors::Anchors>(d->usedAnchors); } +Qt::Orientations QQuickAnchors::activeDirections() const +{ + Q_D(const QQuickAnchors); + if (d->fill || d->centerIn) + return Qt::Horizontal | Qt::Vertical; + Qt::Orientations o; + if (d->usedAnchors & QQuickAnchors::Horizontal_Mask) + o |= Qt::Horizontal; + if (d->usedAnchors & QQuickAnchors::Vertical_Mask) + o |= Qt::Vertical; + return o; +} + bool QQuickAnchorsPrivate::checkHValid() const { if (usedAnchors & QQuickAnchors::LeftAnchor && diff --git a/src/quick/items/qquickanchors_p.h b/src/quick/items/qquickanchors_p.h index f00b8b5ba7..931b963534 100644 --- a/src/quick/items/qquickanchors_p.h +++ b/src/quick/items/qquickanchors_p.h @@ -86,8 +86,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickAnchors : public QObject Q_PROPERTY(bool alignWhenCentered READ alignWhenCentered WRITE setAlignWhenCentered NOTIFY centerAlignedChanged) public: - QQuickAnchors(QQuickItem *item, QObject *parent=0); - virtual ~QQuickAnchors(); + QQuickAnchors(QQuickItem *item, QObject *parent=nullptr); + ~QQuickAnchors() override; enum Anchor #if defined(Q_CC_CLANG) || !defined(Q_CC_GNU) // meaning: clang and msvc, but NOT gcc proper (because, you know, Q_CC_CLANG implies Q_CC_GNU) @@ -174,6 +174,7 @@ public: void resetCenterIn(); Anchors usedAnchors() const; + Qt::Orientations activeDirections() const; bool mirrored(); diff --git a/src/quick/items/qquickanchors_p_p.h b/src/quick/items/qquickanchors_p_p.h index ae6ca02786..0a834276ae 100644 --- a/src/quick/items/qquickanchors_p_p.h +++ b/src/quick/items/qquickanchors_p_p.h @@ -60,15 +60,15 @@ QT_BEGIN_NAMESPACE class QQuickAnchorLine { public: - QQuickAnchorLine() : item(0), anchorLine(QQuickAnchors::InvalidAnchor) {} + QQuickAnchorLine() {} QQuickAnchorLine(QQuickItem *i, QQuickAnchors::Anchor l) : item(i), anchorLine(l) {} QQuickAnchorLine(QQuickItem *i, uint l) : item(i) , anchorLine(static_cast<QQuickAnchors::Anchor>(l)) { Q_ASSERT(l < ((QQuickAnchors::BaselineAnchor << 1) - 1)); } - QQuickItem *item; - QQuickAnchors::Anchor anchorLine; + QQuickItem *item = nullptr; + QQuickAnchors::Anchor anchorLine = QQuickAnchors::InvalidAnchor; }; inline bool operator==(const QQuickAnchorLine& a, const QQuickAnchorLine& b) diff --git a/src/quick/items/qquickanimatedimage.cpp b/src/quick/items/qquickanimatedimage.cpp index 5bc5b0faff..26dfdb07a6 100644 --- a/src/quick/items/qquickanimatedimage.cpp +++ b/src/quick/items/qquickanimatedimage.cpp @@ -54,26 +54,26 @@ QT_BEGIN_NAMESPACE QQuickPixmap* QQuickAnimatedImagePrivate::infoForCurrentFrame(QQmlEngine *engine) { - if (!_movie) - return 0; + if (!movie) + return nullptr; - int current = _movie->currentFrameNumber(); + int current = movie->currentFrameNumber(); if (!frameMap.contains(current)) { QUrl requestedUrl; - QQuickPixmap *pixmap = 0; - if (engine && !_movie->fileName().isEmpty()) { + QQuickPixmap *pixmap = nullptr; + if (engine && !movie->fileName().isEmpty()) { requestedUrl.setUrl(QString::fromUtf8("quickanimatedimage://%1#%2") - .arg(_movie->fileName()) + .arg(movie->fileName()) .arg(current)); } if (!requestedUrl.isEmpty()) { if (QQuickPixmap::isCached(requestedUrl, QSize(), QQuickImageProviderOptions())) pixmap = new QQuickPixmap(engine, requestedUrl); else - pixmap = new QQuickPixmap(requestedUrl, _movie->currentImage()); + pixmap = new QQuickPixmap(requestedUrl, movie->currentImage()); } else { pixmap = new QQuickPixmap; - pixmap->setImage(_movie->currentImage()); + pixmap->setImage(movie->currentImage()); } frameMap.insert(current, pixmap); } @@ -138,7 +138,7 @@ QQuickPixmap* QQuickAnimatedImagePrivate::infoForCurrentFrame(QQmlEngine *engine QQuickAnimatedImage::QQuickAnimatedImage(QQuickItem *parent) : QQuickImage(*(new QQuickAnimatedImagePrivate), parent) { - QObject::connect(this, &QQuickImageBase::cacheChanged, this, &QQuickAnimatedImage::onCacheChanged); + connect(this, &QQuickImageBase::cacheChanged, this, &QQuickAnimatedImage::onCacheChanged); } QQuickAnimatedImage::~QQuickAnimatedImage() @@ -148,7 +148,7 @@ QQuickAnimatedImage::~QQuickAnimatedImage() if (d->reply) d->reply->deleteLater(); #endif - delete d->_movie; + delete d->movie; qDeleteAll(d->frameMap); d->frameMap.clear(); } @@ -164,9 +164,9 @@ QQuickAnimatedImage::~QQuickAnimatedImage() bool QQuickAnimatedImage::isPaused() const { Q_D(const QQuickAnimatedImage); - if (!d->_movie) + if (!d->movie) return d->paused; - return d->_movie->state()==QMovie::Paused; + return d->movie->state()==QMovie::Paused; } void QQuickAnimatedImage::setPaused(bool pause) @@ -174,11 +174,11 @@ void QQuickAnimatedImage::setPaused(bool pause) Q_D(QQuickAnimatedImage); if (pause == d->paused) return; - if (!d->_movie) { + if (!d->movie) { d->paused = pause; emit pausedChanged(); } else { - d->_movie->setPaused(pause); + d->movie->setPaused(pause); } } @@ -203,9 +203,9 @@ void QQuickAnimatedImage::setPaused(bool pause) bool QQuickAnimatedImage::isPlaying() const { Q_D(const QQuickAnimatedImage); - if (!d->_movie) + if (!d->movie) return d->playing; - return d->_movie->state()!=QMovie::NotRunning; + return d->movie->state()!=QMovie::NotRunning; } void QQuickAnimatedImage::setPlaying(bool play) @@ -213,15 +213,15 @@ void QQuickAnimatedImage::setPlaying(bool play) Q_D(QQuickAnimatedImage); if (play == d->playing) return; - if (!d->_movie) { + if (!d->movie) { d->playing = play; emit playingChanged(); return; } if (play) - d->_movie->start(); + d->movie->start(); else - d->_movie->stop(); + d->movie->stop(); } /*! @@ -237,27 +237,53 @@ void QQuickAnimatedImage::setPlaying(bool play) int QQuickAnimatedImage::currentFrame() const { Q_D(const QQuickAnimatedImage); - if (!d->_movie) - return d->preset_currentframe; - return d->_movie->currentFrameNumber(); + if (!d->movie) + return d->presetCurrentFrame; + return d->movie->currentFrameNumber(); } void QQuickAnimatedImage::setCurrentFrame(int frame) { Q_D(QQuickAnimatedImage); - if (!d->_movie) { - d->preset_currentframe = frame; + if (!d->movie) { + d->presetCurrentFrame = frame; return; } - d->_movie->jumpToFrame(frame); + d->movie->jumpToFrame(frame); } int QQuickAnimatedImage::frameCount() const { Q_D(const QQuickAnimatedImage); - if (!d->_movie) + if (!d->movie) return 0; - return d->_movie->frameCount(); + return d->movie->frameCount(); +} + +/*! + \qmlproperty real QtQuick::AnimatedImage::speed + \since QtQuick 2.11 + + This property holds the speed of the animation. + + The speed is measured in percentage of the original animated image speed. + The default speed is 1.0 (original speed). +*/ +qreal QQuickAnimatedImage::speed() const +{ + Q_D(const QQuickAnimatedImage); + return d->speed; +} + +void QQuickAnimatedImage::setSpeed(qreal speed) +{ + Q_D(QQuickAnimatedImage); + if (d->speed != speed) { + d->speed = speed; + if (d->movie) + d->movie->setSpeed(qRound(speed * 100.0)); + emit speedChanged(); + } } void QQuickAnimatedImage::setSource(const QUrl &url) @@ -269,7 +295,7 @@ void QQuickAnimatedImage::setSource(const QUrl &url) #if QT_CONFIG(qml_network) if (d->reply) { d->reply->deleteLater(); - d->reply = 0; + d->reply = nullptr; } #endif @@ -278,10 +304,7 @@ void QQuickAnimatedImage::setSource(const QUrl &url) d->frameMap.clear(); d->oldPlaying = isPlaying(); - if (d->_movie) { - d->setMovie(nullptr); - } - + d->setMovie(nullptr); d->url = url; emit sourceChanged(d->url); @@ -335,10 +358,8 @@ void QQuickAnimatedImage::load() req.setAttribute(QNetworkRequest::HttpPipeliningAllowedAttribute, true); d->reply = qmlEngine(this)->networkAccessManager()->get(req); - QObject::connect(d->reply, SIGNAL(finished()), - this, SLOT(movieRequestFinished())); - QObject::connect(d->reply, SIGNAL(downloadProgress(qint64,qint64)), - this, SLOT(requestProgress(qint64,qint64))); + connect(d->reply, &QNetworkReply::finished, this, &QQuickAnimatedImage::movieRequestFinished); + connect(d->reply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(requestProgress(qint64,qint64))); #endif } } @@ -369,7 +390,7 @@ void QQuickAnimatedImage::movieRequestFinished() } #endif - if (!d->_movie || !d->_movie->isValid()) { + if (!d->movie || !d->movie->isValid()) { qmlWarning(this) << "Error Reading Animated Image File " << d->url.toString(); d->setMovie(nullptr); d->setImage(QImage()); @@ -390,12 +411,11 @@ void QQuickAnimatedImage::movieRequestFinished() return; } - connect(d->_movie, SIGNAL(stateChanged(QMovie::MovieState)), - this, SLOT(playingStatusChanged())); - connect(d->_movie, SIGNAL(frameChanged(int)), - this, SLOT(movieUpdate())); + connect(d->movie, &QMovie::stateChanged, this, &QQuickAnimatedImage::playingStatusChanged); + connect(d->movie, &QMovie::frameChanged, this, &QQuickAnimatedImage::movieUpdate); if (d->cache) - d->_movie->setCacheMode(QMovie::CacheAll); + d->movie->setCacheMode(QMovie::CacheAll); + d->movie->setSpeed(qRound(d->speed * 100.0)); d->status = Ready; emit statusChanged(d->status); @@ -406,22 +426,21 @@ void QQuickAnimatedImage::movieRequestFinished() } bool pausedAtStart = d->paused; - if (d->playing) { - d->_movie->start(); - } + if (d->playing) + d->movie->start(); if (pausedAtStart) - d->_movie->setPaused(true); + d->movie->setPaused(true); if (d->paused || !d->playing) { - d->_movie->jumpToFrame(d->preset_currentframe); - d->preset_currentframe = 0; + d->movie->jumpToFrame(d->presetCurrentFrame); + d->presetCurrentFrame = 0; } d->setPixmap(*d->infoForCurrentFrame(qmlEngine(this))); if (isPlaying() != d->oldPlaying) emit playingChanged(); - if (d->_movie) - d->currentSourceSize = d->_movie->currentPixmap().size(); + if (d->movie) + d->currentSourceSize = d->movie->currentPixmap().size(); else d->currentSourceSize = QSize(0, 0); @@ -440,7 +459,7 @@ void QQuickAnimatedImage::movieUpdate() d->frameMap.clear(); } - if (d->_movie) { + if (d->movie) { d->setPixmap(*d->infoForCurrentFrame(qmlEngine(this))); emit frameChanged(); } @@ -450,12 +469,12 @@ void QQuickAnimatedImage::playingStatusChanged() { Q_D(QQuickAnimatedImage); - if ((d->_movie->state() != QMovie::NotRunning) != d->playing) { - d->playing = (d->_movie->state() != QMovie::NotRunning); + if ((d->movie->state() != QMovie::NotRunning) != d->playing) { + d->playing = (d->movie->state() != QMovie::NotRunning); emit playingChanged(); } - if ((d->_movie->state() == QMovie::Paused) != d->paused) { - d->paused = (d->_movie->state() == QMovie::Paused); + if ((d->movie->state() == QMovie::Paused) != d->paused) { + d->paused = (d->movie->state() == QMovie::Paused); emit pausedChanged(); } } @@ -466,13 +485,11 @@ void QQuickAnimatedImage::onCacheChanged() if (!cache()) { qDeleteAll(d->frameMap); d->frameMap.clear(); - if (d->_movie) { - d->_movie->setCacheMode(QMovie::CacheNone); - } + if (d->movie) + d->movie->setCacheMode(QMovie::CacheNone); } else { - if (d->_movie) { - d->_movie->setCacheMode(QMovie::CacheAll); - } + if (d->movie) + d->movie->setCacheMode(QMovie::CacheAll); } } @@ -488,13 +505,15 @@ void QQuickAnimatedImage::componentComplete() load(); } -void QQuickAnimatedImagePrivate::setMovie(QMovie *movie) +void QQuickAnimatedImagePrivate::setMovie(QMovie *m) { + if (movie == m) + return; Q_Q(QQuickAnimatedImage); const int oldFrameCount = q->frameCount(); - delete _movie; - _movie = movie; + delete movie; + movie = m; if (oldFrameCount != q->frameCount()) emit q->frameCountChanged(); diff --git a/src/quick/items/qquickanimatedimage_p.h b/src/quick/items/qquickanimatedimage_p.h index f7a6bd808b..6b5db215bd 100644 --- a/src/quick/items/qquickanimatedimage_p.h +++ b/src/quick/items/qquickanimatedimage_p.h @@ -70,12 +70,13 @@ class Q_AUTOTEST_EXPORT QQuickAnimatedImage : public QQuickImage Q_PROPERTY(bool paused READ isPaused WRITE setPaused NOTIFY pausedChanged) Q_PROPERTY(int currentFrame READ currentFrame WRITE setCurrentFrame NOTIFY frameChanged) Q_PROPERTY(int frameCount READ frameCount NOTIFY frameCountChanged) + Q_PROPERTY(qreal speed READ speed WRITE setSpeed NOTIFY speedChanged REVISION 11) // read-only for AnimatedImage Q_PROPERTY(QSize sourceSize READ sourceSize NOTIFY sourceSizeChanged) public: - QQuickAnimatedImage(QQuickItem *parent=0); + QQuickAnimatedImage(QQuickItem *parent=nullptr); ~QQuickAnimatedImage(); bool isPlaying() const; @@ -89,6 +90,9 @@ public: int frameCount() const; + qreal speed() const; + void setSpeed(qreal speed); + // Extends QQuickImage's src property void setSource(const QUrl&) override; virtual QSize sourceSize(); @@ -98,6 +102,7 @@ Q_SIGNALS: void pausedChanged(); void frameChanged(); void frameCountChanged(); + Q_REVISION(11) void speedChanged(); private Q_SLOTS: void movieUpdate(); diff --git a/src/quick/items/qquickanimatedimage_p_p.h b/src/quick/items/qquickanimatedimage_p_p.h index 68c4f2d359..1a74f67424 100644 --- a/src/quick/items/qquickanimatedimage_p_p.h +++ b/src/quick/items/qquickanimatedimage_p_p.h @@ -70,28 +70,30 @@ class QQuickAnimatedImagePrivate : public QQuickImagePrivate public: QQuickAnimatedImagePrivate() - : playing(true), paused(false), preset_currentframe(0), _movie(0), oldPlaying(false) + : playing(true), paused(false), oldPlaying(false), padding(0) + , presetCurrentFrame(0), speed(1.0), currentSourceSize(0, 0), movie(nullptr) #if QT_CONFIG(qml_network) - , reply(0), redirectCount(0) + , reply(nullptr), redirectCount(0) #endif - , currentSourceSize(0, 0) { } QQuickPixmap *infoForCurrentFrame(QQmlEngine *engine); + void setMovie(QMovie *movie); - bool playing; - bool paused; - int preset_currentframe; - QMovie *_movie; - bool oldPlaying; + bool playing : 1; + bool paused : 1; + bool oldPlaying : 1; + unsigned padding: 29; + int presetCurrentFrame; + qreal speed; + QSize currentSourceSize; + QMovie *movie; #if QT_CONFIG(qml_network) QNetworkReply *reply; int redirectCount; #endif QMap<int, QQuickPixmap *> frameMap; - QSize currentSourceSize; - void setMovie(QMovie *movie); }; QT_END_NAMESPACE diff --git a/src/quick/items/qquickanimatedsprite.cpp b/src/quick/items/qquickanimatedsprite.cpp index 4e71b0c65f..741e4607e5 100644 --- a/src/quick/items/qquickanimatedsprite.cpp +++ b/src/quick/items/qquickanimatedsprite.cpp @@ -69,9 +69,67 @@ QT_BEGIN_NAMESPACE as multiple frames in the same image file. You can play it at a fixed speed, at the frame rate of your display, or manually advance and control the progress. - For details of how a sprite animation is defined see the \l{Sprite Animations} overview. - Note that the AnimatedSprite type does not use Sprite types to define multiple animations, - but instead encapsulates a single animation itself. + Consider the following sprite sheet: + + \image animatedsprite-loading.png + + It can be divided up into four frames: + + \image animatedsprite-loading-frames.png + + To play each of these frames at a speed of 500 milliseconds per frame, the + following code can be used: + + \table + \header + \li Code + \li Result + \row + \li + \code + AnimatedSprite { + source: "loading.png" + frameWidth: 64 + frameHeight: 64 + frameCount: 4 + frameDuration: 500 + } + \endcode + \li + \image animatedsprite-loading-interpolated.gif + \endtable + + By default, the frames are interpolated (blended together) to make the + animation appear smoother. To disable this, set \l interpolate to \c false: + + \table + \header + \li Code + \li Result + \row + \li + \code + AnimatedSprite { + source: "loading.png" + frameWidth: 64 + frameHeight: 64 + frameCount: 4 + frameDuration: 500 + interpolate: false + } + \endcode + \li + \image animatedsprite-loading.gif + \endtable + + To control how AnimatedSprite responds to being scaled, use the + \l {Item::}{smooth} property. + + Note that unlike \l SpriteSequence, the AnimatedSprite type does not use + \l Sprite to define multiple animations, but instead encapsulates a + single animation itself. + + \sa {Sprite Animations} */ /*! @@ -105,7 +163,7 @@ QT_BEGIN_NAMESPACE /*! \qmlproperty int QtQuick::AnimatedSprite::frameDuration - Duration of each frame of the animation. Values equal to or below 0 are invalid. + Duration of each frame of the animation in milliseconds. Values equal to or below 0 are invalid. If frameRate is valid then it will be used to calculate the duration of the frames. If not, and frameDuration is valid, then frameDuration will be used. @@ -210,7 +268,6 @@ QT_BEGIN_NAMESPACE Stops, then starts the sprite animation. */ -//TODO: Implicitly size element to size of sprite QQuickAnimatedSprite::QQuickAnimatedSprite(QQuickItem *parent) : QQuickItem(*(new QQuickAnimatedSpritePrivate), parent) { @@ -516,6 +573,7 @@ void QQuickAnimatedSprite::setFrameHeight(int arg) if (d->m_sprite->m_frameHeight != arg) { d->m_sprite->setFrameHeight(arg); Q_EMIT frameHeightChanged(arg); + setImplicitHeight(frameHeight()); reloadImage(); } } @@ -527,6 +585,7 @@ void QQuickAnimatedSprite::setFrameWidth(int arg) if (d->m_sprite->m_frameWidth != arg) { d->m_sprite->setFrameWidth(arg); Q_EMIT frameWidthChanged(arg); + setImplicitWidth(frameWidth()); reloadImage(); } } @@ -641,6 +700,17 @@ QSGSpriteNode* QQuickAnimatedSprite::initNode() if (image.isNull()) return nullptr; + // If frameWidth or frameHeight are not explicitly set, frameWidth + // will be set to the width of the image divided by the number of frames, + // and frameHeight will be set to the height of the image. + // In this case, QQuickAnimatedSprite currently won't emit frameWidth/HeightChanged + // at all, so we have to do this here, as it's the only place where assembledImage() + // is called (which calculates the "implicit" frameWidth/Height. + // In addition, currently the "implicit" frameWidth/Height are only calculated once, + // even after changing to a different source. + setImplicitWidth(frameWidth()); + setImplicitHeight(frameHeight()); + QSGSpriteNode *node = d->sceneGraphContext()->createSpriteNode(); d->m_sheetSize = QSize(image.size()); diff --git a/src/quick/items/qquickanimatedsprite_p.h b/src/quick/items/qquickanimatedsprite_p.h index 276e6fbb92..d7e60b909c 100644 --- a/src/quick/items/qquickanimatedsprite_p.h +++ b/src/quick/items/qquickanimatedsprite_p.h @@ -94,7 +94,7 @@ class Q_AUTOTEST_EXPORT QQuickAnimatedSprite : public QQuickItem Q_PROPERTY(int currentFrame READ currentFrame WRITE setCurrentFrame NOTIFY currentFrameChanged) public: - explicit QQuickAnimatedSprite(QQuickItem *parent = 0); + explicit QQuickAnimatedSprite(QQuickItem *parent = nullptr); enum LoopParameters { Infinite = -1 }; diff --git a/src/quick/items/qquickborderimage.cpp b/src/quick/items/qquickborderimage.cpp index 75e3a3dbed..4bf34f0417 100644 --- a/src/quick/items/qquickborderimage.cpp +++ b/src/quick/items/qquickborderimage.cpp @@ -278,7 +278,7 @@ void QQuickBorderImage::setSource(const QUrl &url) #if QT_CONFIG(qml_network) if (d->sciReply) { d->sciReply->deleteLater(); - d->sciReply = 0; + d->sciReply = nullptr; } #endif @@ -559,12 +559,12 @@ void QQuickBorderImage::sciRequestFinished() if (d->sciReply->error() != QNetworkReply::NoError) { d->status = Error; d->sciReply->deleteLater(); - d->sciReply = 0; + d->sciReply = nullptr; emit statusChanged(d->status); } else { QQuickGridScaledImage sci(d->sciReply); d->sciReply->deleteLater(); - d->sciReply = 0; + d->sciReply = nullptr; setGridScaledImage(sci); } } @@ -629,7 +629,7 @@ QSGNode *QQuickBorderImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeDat if (!texture || width() <= 0 || height() <= 0) { delete oldNode; - return 0; + return nullptr; } QSGInternalImageNode *node = static_cast<QSGInternalImageNode *>(oldNode); diff --git a/src/quick/items/qquickborderimage_p.h b/src/quick/items/qquickborderimage_p.h index f43e6c8e1e..61bd26ba83 100644 --- a/src/quick/items/qquickborderimage_p.h +++ b/src/quick/items/qquickborderimage_p.h @@ -69,7 +69,7 @@ class Q_AUTOTEST_EXPORT QQuickBorderImage : public QQuickImageBase Q_PROPERTY(QSize sourceSize READ sourceSize NOTIFY sourceSizeChanged) public: - QQuickBorderImage(QQuickItem *parent=0); + QQuickBorderImage(QQuickItem *parent=nullptr); ~QQuickBorderImage(); QQuickScaleGrid *border(); diff --git a/src/quick/items/qquickdrag.cpp b/src/quick/items/qquickdrag.cpp index 6dc005a03c..d377b1dad4 100644 --- a/src/quick/items/qquickdrag.cpp +++ b/src/quick/items/qquickdrag.cpp @@ -67,8 +67,8 @@ public: return static_cast<QQuickDragAttachedPrivate *>(QObjectPrivate::get(attached)); } QQuickDragAttachedPrivate() - : attachedItem(0) - , mimeData(0) + : attachedItem(nullptr) + , mimeData(nullptr) , proposedAction(Qt::MoveAction) , supportedActions(Qt::MoveAction | Qt::CopyAction | Qt::LinkAction) , active(false) @@ -231,7 +231,7 @@ void QQuickDragAttachedPrivate::deliverLeaveEvent() if (window) { QDragLeaveEvent event; deliverEvent(window, &event); - window = 0; + window = nullptr; } } @@ -686,7 +686,7 @@ int QQuickDragAttached::drop() return acceptedAction; d->active = false; - QObject *target = 0; + QObject *target = nullptr; if (d->window) { QPoint scenePos = d->attachedItem->mapToScene(d->hotSpot).toPoint(); @@ -732,7 +732,7 @@ void QQuickDragAttached::cancel() d->deliverLeaveEvent(); if (d->target) { - d->target = 0; + d->target = nullptr; emit targetChanged(); } @@ -783,7 +783,7 @@ Qt::DropAction QQuickDragAttachedPrivate::startDrag(Qt::DropActions supportedAct deliverLeaveEvent(); if (target) { - target = 0; + target = nullptr; emit q->targetChanged(); } @@ -836,7 +836,7 @@ void QQuickDragAttached::startDrag(QQmlV4Function *args) } QQuickDrag::QQuickDrag(QObject *parent) -: QObject(parent), _target(0), _axis(XAndYAxis), _xmin(-FLT_MAX), +: QObject(parent), _target(nullptr), _axis(XAndYAxis), _xmin(-FLT_MAX), _xmax(FLT_MAX), _ymin(-FLT_MAX), _ymax(FLT_MAX), _active(false), _filterChildren(false), _smoothed(true), _threshold(QGuiApplication::styleHints()->startDragDistance()) { @@ -861,9 +861,9 @@ void QQuickDrag::setTarget(QQuickItem *t) void QQuickDrag::resetTarget() { - if (_target == 0) + if (_target == nullptr) return; - _target = 0; + _target = nullptr; emit targetChanged(); } diff --git a/src/quick/items/qquickdrag_p.h b/src/quick/items/qquickdrag_p.h index 17e9d8c690..6bfbae74c9 100644 --- a/src/quick/items/qquickdrag_p.h +++ b/src/quick/items/qquickdrag_p.h @@ -83,7 +83,7 @@ class QQuickDragGrabber typedef QIntrusiveList<Item, &Item::node> ItemList; public: - QQuickDragGrabber() : m_target(0) {} + QQuickDragGrabber() : m_target(nullptr) {} ~QQuickDragGrabber() { while (!m_items.isEmpty()) delete m_items.first(); } @@ -94,10 +94,10 @@ public: else if (!m_items.isEmpty()) return *m_items.first(); else - return 0; + return nullptr; } void setTarget(QObject *target) { m_target = target; } - void resetTarget() { m_target = 0; } + void resetTarget() { m_target = nullptr; } bool isEmpty() const { return m_items.isEmpty(); } @@ -136,7 +136,7 @@ class QQuickDragMimeData : public QMimeData Q_OBJECT public: QQuickDragMimeData() - : m_source(0) + : m_source(nullptr) { } @@ -173,7 +173,7 @@ class Q_AUTOTEST_EXPORT QQuickDrag : public QObject //### consider drag and drop public: - QQuickDrag(QObject *parent=0); + QQuickDrag(QObject *parent=nullptr); ~QQuickDrag(); enum DragType { None, Automatic, Internal }; diff --git a/src/quick/items/qquickdroparea.cpp b/src/quick/items/qquickdroparea.cpp index c7606f90e1..b77fb40cb1 100644 --- a/src/quick/items/qquickdroparea.cpp +++ b/src/quick/items/qquickdroparea.cpp @@ -78,7 +78,7 @@ public: }; QQuickDropAreaPrivate::QQuickDropAreaPrivate() - : drag(0) + : drag(nullptr) , containsDrag(false) { } @@ -303,7 +303,7 @@ void QQuickDropArea::dragLeaveEvent(QDragLeaveEvent *) emit exited(); d->containsDrag = false; - d->source = 0; + d->source = nullptr; emit containsDragChanged(); if (d->drag) emit d->drag->sourceChanged(); @@ -328,7 +328,7 @@ void QQuickDropArea::dropEvent(QDropEvent *event) emit dropped(&dragTargetEvent); d->containsDrag = false; - d->source = 0; + d->source = nullptr; emit containsDragChanged(); if (d->drag) emit d->drag->sourceChanged(); diff --git a/src/quick/items/qquickevents.cpp b/src/quick/items/qquickevents.cpp index 8653d758de..1be4bafe28 100644 --- a/src/quick/items/qquickevents.cpp +++ b/src/quick/items/qquickevents.cpp @@ -134,13 +134,13 @@ Item { It contains a bitwise combination of: \list - \li Qt.NoModifier - No modifier key is pressed. - \li Qt.ShiftModifier - A Shift key on the keyboard is pressed. - \li Qt.ControlModifier - A Ctrl key on the keyboard is pressed. - \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. + \li \l {Qt::NoModifier} {Qt.NoModifier} - No modifier key is pressed. + \li \l {Qt::ShiftModifier} {Qt.ShiftModifier} - A Shift key on the keyboard is pressed. + \li \l {Qt::ControlModifier} {Qt.ControlModifier} - A Ctrl key on the keyboard is pressed. + \li \l {Qt::AltModifier} {Qt.AltModifier} - An Alt key on the keyboard is pressed. + \li \l {Qt::MetaModifier} {Qt.MetaModifier} - A Meta key on the keyboard is pressed. + \li \l {Qt::KeypadModifier} {Qt.KeypadModifier} - A keypad button is pressed. + \li \l {Qt::GroupSwitchModifier} {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: @@ -184,7 +184,7 @@ Item { \brief Provides information about a mouse event - The position of the mouse can be found via the \l x and \l y properties. + The position of the mouse can be found via the \l {Item::x} {x} and \l {Item::y} {y} properties. The button that caused the event is available via the \l button property. \sa MouseArea @@ -218,17 +218,17 @@ Item { This property holds the button that caused the event. It can be one of: \list - \li Qt.LeftButton - \li Qt.RightButton - \li Qt.MiddleButton + \li \l {Qt::LeftButton} {Qt.LeftButton} + \li \l {Qt::RightButton} {Qt.RightButton} + \li \l {Qt::MiddleButton} {Qt.MiddleButton} \endlist */ /*! \qmlproperty bool QtQuick::MouseEvent::wasHeld - This property is true if the mouse button has been held pressed longer the - threshold (800ms). + This property is true if the mouse button has been held pressed longer + than the threshold (800ms). */ /*! @@ -241,9 +241,9 @@ Item { It contains a bitwise combination of: \list - \li Qt.LeftButton - \li Qt.RightButton - \li Qt.MiddleButton + \li \l {Qt::LeftButton} {Qt.LeftButton} + \li \l {Qt::RightButton} {Qt.RightButton} + \li \l {Qt::MiddleButton} {Qt.MiddleButton} \endlist */ @@ -255,12 +255,12 @@ Item { It contains a bitwise combination of: \list - \li Qt.NoModifier - No modifier key is pressed. - \li Qt.ShiftModifier - A Shift key on the keyboard is pressed. - \li Qt.ControlModifier - A Ctrl key on the keyboard is pressed. - \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 \l {Qt::NoModifier} {Qt.NoModifier} - No modifier key is pressed. + \li \l {Qt::ShiftModifier} {Qt.ShiftModifier} - A Shift key on the keyboard is pressed. + \li \l {Qt::ControlModifier} {Qt.ControlModifier} - A Ctrl key on the keyboard is pressed. + \li \l {Qt::AltModifier} {Qt.AltModifier} - An Alt key on the keyboard is pressed. + \li \l {Qt::MetaModifier} {Qt.MetaModifier} - A Meta key on the keyboard is pressed. + \li \l {Qt::KeypadModifier} {Qt.KeypadModifier} - A keypad button is pressed. \endlist For example, to react to a Shift key + Left mouse button click: @@ -288,20 +288,24 @@ Item { The value can be one of: - \value Qt.MouseEventNotSynthesized The most common value. On platforms where - such information is available, this value indicates that the event - represents a genuine mouse event from the system. + \list + \li \l{Qt::MouseEventNotSynthesized} {Qt.MouseEventNotSynthesized} + - The most common value. On platforms where such information is + available, this value indicates that the event represents a genuine + mouse event from the system. - \value Qt.MouseEventSynthesizedBySystem Indicates that the mouse event was + \li \l{Qt::MouseEventSynthesizedBySystem} {Qt.MouseEventSynthesizedBySystem} - Indicates that the mouse event was synthesized from a touch or tablet event by the platform. - \value Qt.MouseEventSynthesizedByQt Indicates that the mouse event was - synthesized from an unhandled touch or tablet event by Qt. + \li \l{Qt::MouseEventSynthesizedByQt} {Qt.MouseEventSynthesizedByQt} + - Indicates that the mouse event was synthesized from an unhandled + touch or tablet event by Qt. - \value Qt.MouseEventSynthesizedByApplication Indicates that the mouse event - was synthesized by the application. This allows distinguishing - application-generated mouse events from the ones that are coming from the - system or are synthesized by Qt. + \li \l{Qt::MouseEventSynthesizedByApplication} {Qt.MouseEventSynthesizedByApplication} + - Indicates that the mouse event was synthesized by the application. + This allows distinguishing application-generated mouse events from + the ones that are coming from the system or are synthesized by Qt. + \endlist For example, to react only to events which come from an actual mouse: \qml @@ -326,13 +330,29 @@ Item { */ /*! + \qmlproperty int QtQuick::MouseEvent::flags + \since 5.11 + + This property holds the flags that provide additional information about the + mouse event. + + \list + \li \l {Qt::MouseEventCreatedDoubleClick} {Qt.MouseEventCreatedDoubleClick} + - Indicates that Qt has created a double click event from this event. + This flag is set in the event originating from a button press, and not + in the resulting double click event. + \endlist +*/ + +/*! \qmltype WheelEvent \instantiates QQuickWheelEvent \inqmlmodule QtQuick \ingroup qtquick-input-events \brief Provides information about a mouse wheel event - The position of the mouse can be found via the \l x and \l y properties. + The position of the mouse can be found via the + \l {Item::x} {x} and \l {Item::y} {y} properties. \sa MouseArea */ @@ -366,9 +386,9 @@ Item { It contains a bitwise combination of: \list - \li Qt.LeftButton - \li Qt.RightButton - \li Qt.MiddleButton + \li \l {Qt::LeftButton} {Qt.LeftButton} + \li \l {Qt::RightButton} {Qt.RightButton} + \li \l {Qt::MiddleButton} {Qt.MiddleButton} \endlist */ @@ -406,12 +426,12 @@ Item { It contains a bitwise combination of: \list - \li Qt.NoModifier - No modifier key is pressed. - \li Qt.ShiftModifier - A Shift key on the keyboard is pressed. - \li Qt.ControlModifier - A Ctrl key on the keyboard is pressed. - \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 \l {Qt::NoModifier} {Qt.NoModifier} - No modifier key is pressed. + \li \l {Qt::ShiftModifier} {Qt.ShiftModifier} - A Shift key on the keyboard is pressed. + \li \l {Qt::ControlModifier} {Qt.ControlModifier} - A Ctrl key on the keyboard is pressed. + \li \l {Qt::AltModifier} {Qt.AltModifier} - An Alt key on the keyboard is pressed. + \li \l {Qt::MetaModifier} {Qt.MetaModifier} - A Meta key on the keyboard is pressed. + \li \l {Qt::KeypadModifier} {Qt.KeypadModifier} - A keypad button is pressed. \endlist For example, to react to a Control key pressed during the wheel event: @@ -485,13 +505,46 @@ Item { \l {QTabletEvent::tangentialPressure}{tangentialPressure} \value DeviceType.Puck a device that is similar to a flat mouse with a - transparent circle with cross-hairs (same as \l QTabletEvent::Puck) + transparent circle with cross-hairs + (same as \l {QTabletEvent::Puck} {Puck}) + \value DeviceType.AllDevices + any of the above; used as a default value for construction \sa QTouchDevice::DeviceType */ /*! \readonly + \qmlproperty enumeration QtQuick::PointerDevice::pointerType + + This property holds a value indicating what is interacting with + the device. Think of the device as having a planar 2D surface, and + the value of this property as identifying what interacts with the + device. + + There is some redundancy between this property and \l {PointerDevice::type}. + If a tocuchscreen is used, then the device is TouchScreen and + pointerType is Finger (always). + + Valid values are: + + \value PointerDevice.GenericPointer + a mouse or something acting like a mouse (the core pointer on X11) + \value PointerDevice.Finger + the user's finger + \value PointerDevice.Pen + the drawing end of a stylus + \value PointerDevice.Eraser + the other end of the stylus (if it has a virtual eraser on the other end) + \value PointerDevice.Cursor + a cursor in the pre-computer sense of the word + \value PointerDevice.AllPointerTypes + any of the above (used as a default value in constructors) +*/ + + +/*! + \readonly \qmlproperty enumeration QtQuick::PointerDevice::capabilities This property holds a bitwise combination of the capabilities of the @@ -508,11 +561,11 @@ Item { \value CapabilityFlag.Pressure the \l {QtQuick::EventTouchPoint::pressure}{pressure} property \value CapabilityFlag.Velocity - the \l {QtQuick::PointerEvent::velocity}{velocity} property + the \l {QtQuick::EventPoint::velocity}{velocity} property \value CapabilityFlag.Scroll - a \l {QtQuick::PointerDevice::DeviceType::Mouse}{Mouse} has a wheel, or the + a \l {QtQuick::PointerDevice::type}{Mouse} has a wheel, or the operating system recognizes scroll gestures on a - \l {QtQuick::PointerDevice::DeviceType::TouchPad}{TouchPad} + \l {QtQuick::PointerDevice::type}{TouchPad} \value CapabilityFlag.Hover events are sent even when no button is pressed, or the finger or stylus is not in contact with the surface @@ -572,8 +625,7 @@ QQuickPointerDevice *QQuickPointerDevice::touchDevice(const QTouchDevice *d) int maximumTouchPoints = 10; QQuickPointerDevice::Capabilities caps = QQuickPointerDevice::Capabilities(QTouchDevice::Position); if (d) { - QQuickPointerDevice::Capabilities caps = - static_cast<QQuickPointerDevice::Capabilities>(static_cast<int>(d->capabilities()) & 0x0F); + caps = static_cast<QQuickPointerDevice::Capabilities>(static_cast<int>(d->capabilities()) & 0xFF); if (d->type() == QTouchDevice::TouchPad) { type = QQuickPointerDevice::TouchPad; caps |= QQuickPointerDevice::Scroll; @@ -639,8 +691,8 @@ QQuickPointerDevice *QQuickPointerDevice::tabletDevice(qint64 id) \qmlproperty point QtQuick::EventPoint::scenePosition This property holds the coordinates of the position supplied by the event, - relative to the scene. If a contact patch is available from the \l device, - this point represents its centroid. + relative to the scene. If a contact patch is available from the + \l {QtQuick::PointerEvent::device} {device}, this point represents its centroid. */ /*! @@ -698,7 +750,7 @@ QQuickPointerDevice *QQuickPointerDevice::tabletDevice(qint64 id) presses a finger against the touchscreen, it will be a larger number. In other cases, it will be -1. - \sa PointerDevice.uniqueId + \sa {QtQuick::EventTouchPoint::uniqueId}{uniqueId} */ /*! @@ -790,17 +842,19 @@ QQuickItem *QQuickEventPoint::grabberItem() const void QQuickEventPoint::setGrabberItem(QQuickItem *grabber) { if (grabber != m_exclusiveGrabber.data()) { + QQuickPointerHandler *oldGrabberHandler = grabberPointerHandler(); + if (oldGrabberHandler && !oldGrabberHandler->approveGrabTransition(this, grabber)) + return; if (Q_UNLIKELY(lcPointerGrab().isDebugEnabled())) { qCDebug(lcPointerGrab) << pointDeviceName(this) << "point" << hex << m_pointId << pointStateString(this) << ": grab" << m_exclusiveGrabber << "->" << grabber; } - QQuickPointerHandler *oldGrabberHandler = grabberPointerHandler(); - QQuickItem *oldGrabberItem = grabberItem(); m_exclusiveGrabber = QPointer<QObject>(grabber); m_grabberIsHandler = false; m_sceneGrabPos = m_scenePos; + QQuickItem *oldGrabberItem = grabberItem(); if (oldGrabberHandler) - oldGrabberHandler->onGrabChanged(oldGrabberHandler, CancelGrabExclusive, this); + oldGrabberHandler->onGrabChanged(oldGrabberHandler, (grabber ? CancelGrabExclusive : UngrabExclusive), this); else if (oldGrabberItem && oldGrabberItem != grabber && grabber && pointerEvent()->asPointerTouchEvent()) oldGrabberItem->touchUngrabEvent(); for (QPointer<QQuickPointerHandler> passiveGrabber : m_passiveGrabbers) @@ -837,26 +891,24 @@ void QQuickEventPoint::setGrabberPointerHandler(QQuickPointerHandler *grabber, b } if (exclusive) { if (grabber != m_exclusiveGrabber.data()) { + QQuickPointerHandler *oldGrabberHandler = grabberPointerHandler(); + QQuickItem *oldGrabberItem = grabberItem(); + m_exclusiveGrabber = QPointer<QObject>(grabber); + m_grabberIsHandler = true; + m_sceneGrabPos = m_scenePos; if (grabber) { - // set variables before notifying the new grabber - m_exclusiveGrabber = QPointer<QObject>(grabber); - m_grabberIsHandler = true; - m_sceneGrabPos = m_scenePos; grabber->onGrabChanged(grabber, GrabExclusive, this); for (QPointer<QQuickPointerHandler> passiveGrabber : m_passiveGrabbers) { if (passiveGrabber != grabber) passiveGrabber->onGrabChanged(grabber, OverrideGrabPassive, this); } - } else if (QQuickPointerHandler *oldGrabberPointerHandler = qmlobject_cast<QQuickPointerHandler *>(m_exclusiveGrabber.data())) { - oldGrabberPointerHandler->onGrabChanged(oldGrabberPointerHandler, UngrabExclusive, this); - } else if (!m_exclusiveGrabber.isNull()) { - // If there is a previous grabber and it's not a PointerHandler, it must be an Item. - QQuickItem *oldGrabberItem = static_cast<QQuickItem *>(m_exclusiveGrabber.data()); - // If this point came from a touchscreen, notify that previous grabber Item that it's losing its touch grab. - if (pointerEvent()->asPointerTouchEvent()) - oldGrabberItem->touchUngrabEvent(); } - // set variables after notifying the old grabber + if (oldGrabberHandler) + oldGrabberHandler->onGrabChanged(oldGrabberHandler, (grabber ? CancelGrabExclusive : UngrabExclusive), this); + else if (oldGrabberItem && pointerEvent()->asPointerTouchEvent()) + oldGrabberItem->touchUngrabEvent(); + // touchUngrabEvent() can result in the grabber being set to null (MPTA does that, for example). + // So set it again to ensure that final state is what we want. m_exclusiveGrabber = QPointer<QObject>(grabber); m_grabberIsHandler = true; m_sceneGrabPos = m_scenePos; @@ -1032,22 +1084,27 @@ void QQuickEventPoint::setAccepted(bool accepted) \qmlproperty size QtQuick::EventTouchPoint::ellipseDiameters This property holds the diameters of the contact patch, if the event - comes from a touchpoint and the \l device provides this information. - - A touchpoint is modeled as an elliptical area where the finger is pressed - against the touchscreen. (In fact, it could also be modeled as a bitmap; but - in that case we expect an elliptical bounding estimate to be fitted to the - contact patch before the event is sent.) The harder the user presses, the - larger the contact patch; so, these diameters provide an alternate way of - detecting pressure, in case the device does not include a separate pressure - sensor. The ellipse is centered on \l scenePos (\l pos in the PointerHandler's + comes from a touchpoint and the \l {QtQuick::PointerEvent::device} {device} + provides this information. + + A touchpoint is modeled as an elliptical area where the finger is + pressed against the touchscreen. (In fact, it could also be + modeled as a bitmap; but in that case we expect an elliptical + bounding estimate to be fitted to the contact patch before the + event is sent.) The harder the user presses, the larger the + contact patch; so, these diameters provide an alternate way of + detecting pressure, in case the device does not include a separate + pressure sensor. The ellipse is centered on + \l {QtQuick::EventPoint::scenePosition} {scenePosition} + (\l {QtQuick::EventPoint::position} {position} in the PointerHandler's Item's local coordinates). The \l rotation property provides the - rotation of the ellipse, if known. It is expected that if the \l rotation - is zero, the verticalDiameter of the ellipse is the larger one (the major axis), - because of the usual hand position, reaching upward or outward across the surface. + rotation of the ellipse, if known. It is expected that if the + \l rotation is zero, the verticalDiameter of the ellipse is the + larger one (the major axis), because of the usual hand position, + reaching upward or outward across the surface. - If the contact patch is unknown, or the \l device is not a touchscreen, - these values will be zero. + If the contact patch is unknown, or the \l {QtQuick::PointerEvent::device} {device} + is not a touchscreen, these values will be zero. */ QQuickEventTouchPoint::QQuickEventTouchPoint(QQuickPointerTouchEvent *parent) @@ -1131,8 +1188,8 @@ QVector2D QQuickEventPoint::estimatedVelocity() const A PointerEvent is an event describing contact or movement across a surface, provided by a mouse, a touchpoint (single finger on a touchscreen), or a - stylus on a graphics tablet. The \l device property provides more - information about where the event came from. + stylus on a graphics tablet. The \l {QtQuick::PointerEvent::device} {device} + property provides more information about where the event came from. \sa PointerHandler @@ -1158,8 +1215,8 @@ QVector2D QQuickEventPoint::estimatedVelocity() const \qmlproperty enumeration QtQuick::PointerEvent::button This property holds the \l {Qt::MouseButton}{button} that caused the event, - if any. If the \l device does not have buttons, or the event is a hover - event, it will be \c Qt.NoButton. + if any. If the \l {QtQuick::PointerEvent::device} {device} does not have + buttons, or the event is a hover event, it will be \c Qt.NoButton. */ /*! diff --git a/src/quick/items/qquickevents_p_p.h b/src/quick/items/qquickevents_p_p.h index 09a63febdc..c4f0b60d92 100644 --- a/src/quick/items/qquickevents_p_p.h +++ b/src/quick/items/qquickevents_p_p.h @@ -84,7 +84,7 @@ class QQuickKeyEvent : public QObject public: QQuickKeyEvent() - : event(QEvent::None, 0, 0) + : event(QEvent::None, 0, nullptr) {} void reset(QEvent::Type type, int key, Qt::KeyboardModifiers modifiers, @@ -131,15 +131,18 @@ class Q_QUICK_PRIVATE_EXPORT QQuickMouseEvent : public QObject Q_PROPERTY(bool wasHeld READ wasHeld) Q_PROPERTY(bool isClick READ isClick) Q_PROPERTY(bool accepted READ isAccepted WRITE setAccepted) + Q_REVISION(11) Q_PROPERTY(int flags READ flags) public: QQuickMouseEvent() - : _x(0), _y(0), _button(Qt::NoButton), _buttons(Qt::NoButton), _modifiers(Qt::NoModifier) - , _source(Qt::MouseEventNotSynthesized), _wasHeld(false), _isClick(false), _accepted(false) + : _buttons(Qt::NoButton), _modifiers(Qt::NoModifier) + , _wasHeld(false), _isClick(false), _accepted(false) + , _flags(Qt::MouseEventFlags(nullptr)) {} void reset(qreal x, qreal y, Qt::MouseButton button, Qt::MouseButtons buttons, - Qt::KeyboardModifiers modifiers, bool isClick = false, bool wasHeld = false) + Qt::KeyboardModifiers modifiers, bool isClick = false, bool wasHeld = false, + Qt::MouseEventFlags flags = nullptr) { _x = x; _y = y; @@ -150,6 +153,7 @@ public: _wasHeld = wasHeld; _isClick = isClick; _accepted = true; + _flags = flags; } qreal x() const { return _x; } @@ -169,17 +173,18 @@ public: bool isAccepted() { return _accepted; } void setAccepted(bool accepted) { _accepted = accepted; } - + int flags() const { return _flags; } private: - qreal _x; - qreal _y; - Qt::MouseButton _button; + qreal _x = 0; + qreal _y = 0; + Qt::MouseButton _button = Qt::NoButton; Qt::MouseButtons _buttons; Qt::KeyboardModifiers _modifiers; - Qt::MouseEventSource _source; + Qt::MouseEventSource _source = Qt::MouseEventNotSynthesized; bool _wasHeld : 1; bool _isClick : 1; bool _accepted : 1; + Qt::MouseEventFlags _flags; }; class QQuickWheelEvent : public QObject @@ -196,8 +201,7 @@ class QQuickWheelEvent : public QObject public: QQuickWheelEvent() - : _x(0), _y(0), _buttons(Qt::NoButton), _modifiers(Qt::NoModifier) - , _inverted(false), _accepted(false) + : _buttons(Qt::NoButton), _modifiers(Qt::NoModifier) {} void reset(qreal x, qreal y, const QPoint &angleDelta, const QPoint &pixelDelta, @@ -224,14 +228,14 @@ public: void setAccepted(bool accepted) { _accepted = accepted; } private: - qreal _x; - qreal _y; + qreal _x = 0; + qreal _y = 0; QPoint _angleDelta; QPoint _pixelDelta; Qt::MouseButtons _buttons; Qt::KeyboardModifiers _modifiers; - bool _inverted; - bool _accepted; + bool _inverted = false; + bool _accepted = false; }; class Q_QUICK_PRIVATE_EXPORT QQuickCloseEvent : public QObject @@ -240,14 +244,13 @@ class Q_QUICK_PRIVATE_EXPORT QQuickCloseEvent : public QObject Q_PROPERTY(bool accepted READ isAccepted WRITE setAccepted) public: - QQuickCloseEvent() - : _accepted(true) {} + QQuickCloseEvent() {} bool isAccepted() { return _accepted; } void setAccepted(bool accepted) { _accepted = accepted; } private: - bool _accepted; + bool _accepted = true; }; class Q_QUICK_PRIVATE_EXPORT QQuickEventPoint : public QObject @@ -306,7 +309,6 @@ public: void setExclusiveGrabber(QObject *exclusiveGrabber); QQuickItem *grabberItem() const; - Q_DECL_DEPRECATED QQuickItem *grabber() const { return grabberItem(); } void setGrabberItem(QQuickItem *exclusiveGrabber); QQuickPointerHandler *grabberPointerHandler() const; @@ -390,12 +392,10 @@ public: QQuickPointerEvent(QObject *parent = nullptr, QQuickPointerDevice *device = nullptr) : QObject(parent) , m_device(device) - , m_event(nullptr) - , m_button(Qt::NoButton) , m_pressedButtons(Qt::NoButton) - { } + {} - virtual ~QQuickPointerEvent(); + ~QQuickPointerEvent() override; public: // property accessors QQuickPointerDevice *device() const { return m_device; } @@ -437,8 +437,8 @@ public: // helpers for C++ only (during event delivery) protected: QQuickPointerDevice *m_device; - QInputEvent *m_event; // original event as received by QQuickWindow - Qt::MouseButton m_button; + QInputEvent *m_event = nullptr; // original event as received by QQuickWindow + Qt::MouseButton m_button = Qt::NoButton; Qt::MouseButtons m_pressedButtons; Q_DISABLE_COPY(QQuickPointerEvent) @@ -483,9 +483,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPointerTouchEvent : public QQuickPointerEvent public: QQuickPointerTouchEvent(QObject *parent = nullptr, QQuickPointerDevice *device = nullptr) : QQuickPointerEvent(parent, device) - , m_pointCount(0) , m_synthMouseEvent(QEvent::MouseMove, QPointF(), Qt::NoButton, Qt::NoButton, Qt::NoModifier) - { } + {} QQuickPointerEvent *reset(QEvent *) override; void localize(QQuickItem *target) override; @@ -511,7 +510,7 @@ public: QTouchEvent *asTouchEvent() const; private: - int m_pointCount; + int m_pointCount = 0; QVector<QQuickEventTouchPoint *> m_touchPoints; mutable QMouseEvent m_synthMouseEvent; @@ -567,7 +566,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPointerDevice : public QObject Q_PROPERTY(QPointingDeviceUniqueId uniqueId READ uniqueId CONSTANT) public: - enum DeviceType { + enum DeviceType : qint16 { UnknownDevice = 0x0000, Mouse = 0x0001, TouchScreen = 0x0002, @@ -575,25 +574,25 @@ public: Puck = 0x0008, Stylus = 0x0010, Airbrush = 0x0020, - AllDevices = 0x003F + AllDevices = 0x7FFF }; Q_DECLARE_FLAGS(DeviceTypes, DeviceType) Q_ENUM(DeviceType) Q_FLAG(DeviceTypes) - enum PointerType { + enum PointerType : qint16 { GenericPointer = 0x0001, Finger = 0x0002, Pen = 0x0004, Eraser = 0x0008, Cursor = 0x0010, - AllPointerTypes = 0x001F + AllPointerTypes = 0x7FFF }; Q_DECLARE_FLAGS(PointerTypes, PointerType) Q_ENUM(PointerType) Q_FLAG(PointerTypes) - enum CapabilityFlag { + enum CapabilityFlag : qint16 { Position = QTouchDevice::Position, Area = QTouchDevice::Area, Pressure = QTouchDevice::Pressure, @@ -611,7 +610,7 @@ public: DeviceType type() const { return m_deviceType; } PointerType pointerType() const { return m_pointerType; } - Capabilities capabilities() const { return m_capabilities; } + Capabilities capabilities() const { return static_cast<Capabilities>(m_capabilities); } bool hasCapability(CapabilityFlag cap) { return m_capabilities & cap; } int maximumTouchPoints() const { return m_maximumTouchPoints; } int buttonCount() const { return m_buttonCount; } @@ -627,19 +626,21 @@ public: private: QQuickPointerDevice(DeviceType devType, PointerType pType, Capabilities caps, int maxPoints, int buttonCount, const QString &name, qint64 uniqueId = 0) - : m_deviceType(devType), m_pointerType(pType), m_capabilities(caps) - , m_maximumTouchPoints(maxPoints), m_buttonCount(buttonCount), m_name(name) + : m_deviceType(devType), m_pointerType(pType), m_capabilities(static_cast<qint16>(caps)) + , m_maximumTouchPoints(static_cast<qint8>(maxPoints)), m_buttonCount(static_cast<qint8>(buttonCount)), m_name(name) , m_uniqueId(QPointingDeviceUniqueId::fromNumericId(uniqueId)) { } - ~QQuickPointerDevice() { } + ~QQuickPointerDevice() override { } private: + // begin 64-bit field DeviceType m_deviceType; PointerType m_pointerType; - Capabilities m_capabilities; - int m_maximumTouchPoints; - int m_buttonCount; + qint16 m_capabilities; + qint8 m_maximumTouchPoints; + qint8 m_buttonCount; + // end 64-bit field QString m_name; QPointingDeviceUniqueId m_uniqueId; QVector<QQuickPointerHandler *> m_eventDeliveryTargets; // during delivery, handlers which have already seen the event diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp index cd918cef5f..8cb64377cc 100644 --- a/src/quick/items/qquickflickable.cpp +++ b/src/quick/items/qquickflickable.cpp @@ -172,13 +172,13 @@ class QQuickFlickableReboundTransition : public QQuickTransitionManager { public: QQuickFlickableReboundTransition(QQuickFlickable *f, const QString &name) - : flickable(f), axisData(0), propName(name), active(false) + : flickable(f), axisData(nullptr), propName(name), active(false) { } ~QQuickFlickableReboundTransition() { - flickable = 0; + flickable = nullptr; } bool startTransition(QQuickFlickablePrivate::AxisData *data, qreal toPos) { @@ -252,12 +252,12 @@ QQuickFlickablePrivate::QQuickFlickablePrivate() , lastPressTime(0) , deceleration(QML_FLICK_DEFAULTDECELERATION) , maxVelocity(QML_FLICK_DEFAULTMAXVELOCITY), reportedVelocitySmoothing(100) - , delayedPressEvent(0), pressDelay(0), fixupDuration(400) - , flickBoost(1.0), fixupMode(Normal), vTime(0), visibleArea(0) + , delayedPressEvent(nullptr), pressDelay(0), fixupDuration(400) + , flickBoost(1.0), fixupMode(Normal), vTime(0), visibleArea(nullptr) , flickableDirection(QQuickFlickable::AutoFlickDirection) , boundsBehavior(QQuickFlickable::DragAndOvershootBounds) , boundsMovement(QQuickFlickable::FollowBoundsBehavior) - , rebound(0) + , rebound(nullptr) { } @@ -317,7 +317,7 @@ void QQuickFlickablePrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometr { Q_Q(QQuickFlickable); if (item == contentItem) { - Qt::Orientations orient = 0; + Qt::Orientations orient = nullptr; if (change.xChange()) orient |= Qt::Horizontal; if (change.yChange()) @@ -725,7 +725,19 @@ QQuickFlickable::~QQuickFlickable() These properties hold the surface coordinate currently at the top-left corner of the Flickable. For example, if you flick an image up 100 pixels, - \c contentY will be 100. + \c contentY will increase by 100. + + \note If you flick back to the origin (the top-left corner), after the + rebound animation, \c contentX will settle to the same value as \c originX, + and \c contentY to \c originY. These are usually (0,0), however ListView + and GridView may have an arbitrary origin due to delegate size variation, + or item insertion/removal outside the visible region. So if you want to + implement something like a vertical scrollbar, one way is to use + \c {y: (contentY - originY) * (height / contentHeight)} + for the position; another way is to use the normalized values in + \l {QtQuick::Flickable::visibleArea}{visibleArea}. + + \sa originX, originY */ qreal QQuickFlickable::contentX() const { @@ -739,7 +751,8 @@ void QQuickFlickable::setContentX(qreal pos) d->hData.explicitValue = true; d->resetTimeline(d->hData); d->hData.vTime = d->timeline.time(); - movementEnding(true, false); + if (isMoving() || isFlicking()) + movementEnding(true, false); if (-pos != d->hData.move.value()) d->hData.move.setValue(-pos); } @@ -756,7 +769,8 @@ void QQuickFlickable::setContentY(qreal pos) d->vData.explicitValue = true; d->resetTimeline(d->vData); d->vData.vTime = d->timeline.time(); - movementEnding(false, true); + if (isMoving() || isFlicking()) + movementEnding(false, true); if (-pos != d->vData.move.value()) d->vData.move.setValue(-pos); } @@ -1421,17 +1435,23 @@ void QQuickFlickable::wheelEvent(QWheelEvent *event) case Qt::ScrollUpdate: if (d->scrollingPhase) d->pressed = true; -#ifdef Q_OS_OSX +#ifdef Q_OS_MACOS + // TODO eliminate this timer when ScrollMomentum has been added d->movementEndingTimer.start(MovementEndingTimerInterval, this); #endif break; case Qt::ScrollEnd: + // TODO most of this should be done at transition to ScrollMomentum phase, + // then do what the movementEndingTimer triggers at transition to ScrollEnd phase d->pressed = false; d->scrollingPhase = false; d->draggingEnding(); event->accept(); returnToBounds(); d->lastPosTime = -1; +#ifdef Q_OS_MACOS + d->movementEndingTimer.start(MovementEndingTimerInterval, this); +#endif return; } @@ -1535,7 +1555,7 @@ void QQuickFlickablePrivate::clearDelayedPress() if (delayedPressEvent) { delayedPressTimer.stop(); delete delayedPressEvent; - delayedPressEvent = 0; + delayedPressEvent = nullptr; } } @@ -1545,7 +1565,7 @@ void QQuickFlickablePrivate::replayDelayedPress() if (delayedPressEvent) { // Losing the grab will clear the delayed press event; take control of it here QScopedPointer<QMouseEvent> mouseEvent(delayedPressEvent); - delayedPressEvent = 0; + delayedPressEvent = nullptr; delayedPressTimer.stop(); // If we have the grab, release before delivering the event @@ -1838,7 +1858,7 @@ int QQuickFlickablePrivate::data_count(QQmlListProperty<QObject> *) QObject *QQuickFlickablePrivate::data_at(QQmlListProperty<QObject> *, int) { // XXX todo - return 0; + return nullptr; } void QQuickFlickablePrivate::data_clear(QQmlListProperty<QObject> *) @@ -2150,6 +2170,8 @@ void QQuickFlickable::setRightMargin(qreal m) This is usually (0,0), however ListView and GridView may have an arbitrary origin due to delegate size variation, or item insertion/removal outside the visible region. + + \sa contentX, contentY */ qreal QQuickFlickable::originY() const @@ -2180,25 +2202,25 @@ qreal QQuickFlickable::originX() const void QQuickFlickable::resizeContent(qreal w, qreal h, QPointF center) { Q_D(QQuickFlickable); - if (w != d->hData.viewSize) { - qreal oldSize = d->hData.viewSize; - d->hData.viewSize = w; - d->contentItem->setWidth(w); + const qreal oldHSize = d->hData.viewSize; + const qreal oldVSize = d->vData.viewSize; + const bool needToUpdateWidth = w != oldHSize; + const bool needToUpdateHeight = h != oldVSize; + d->hData.viewSize = w; + d->vData.viewSize = h; + d->contentItem->setSize(QSizeF(w, h)); + if (needToUpdateWidth) emit contentWidthChanged(); - if (center.x() != 0) { - qreal pos = center.x() * w / oldSize; - setContentX(contentX() + pos - center.x()); - } - } - if (h != d->vData.viewSize) { - qreal oldSize = d->vData.viewSize; - d->vData.viewSize = h; - d->contentItem->setHeight(h); + if (needToUpdateHeight) emit contentHeightChanged(); - if (center.y() != 0) { - qreal pos = center.y() * h / oldSize; - setContentY(contentY() + pos - center.y()); - } + + if (center.x() != 0) { + qreal pos = center.x() * w / oldHSize; + setContentX(contentX() + pos - center.x()); + } + if (center.y() != 0) { + qreal pos = center.y() * h / oldVSize; + setContentY(contentY() + pos - center.y()); } d->updateBeginningEnd(); } @@ -2654,13 +2676,15 @@ void QQuickFlickable::movementEnding(bool hMovementEnding, bool vMovementEnding) if (hMovementEnding && d->hData.moving && (!d->pressed && !d->stealMouse)) { d->hData.moving = false; - d->hMoved = false; + if (!d->scrollingPhase) + d->hMoved = false; emit movingHorizontallyChanged(); } if (vMovementEnding && d->vData.moving && (!d->pressed && !d->stealMouse)) { d->vData.moving = false; - d->vMoved = false; + if (!d->scrollingPhase) + d->vMoved = false; emit movingVerticallyChanged(); } if (wasMoving && !isMoving()) { diff --git a/src/quick/items/qquickflickable_p.h b/src/quick/items/qquickflickable_p.h index 4ad01323a4..939e3af698 100644 --- a/src/quick/items/qquickflickable_p.h +++ b/src/quick/items/qquickflickable_p.h @@ -115,7 +115,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickFlickable : public QQuickItem Q_CLASSINFO("DefaultProperty", "flickableData") public: - QQuickFlickable(QQuickItem *parent=0); + QQuickFlickable(QQuickItem *parent=nullptr); ~QQuickFlickable(); QQmlListProperty<QObject> flickableData(); diff --git a/src/quick/items/qquickflickable_p_p.h b/src/quick/items/qquickflickable_p_p.h index 54cc67875a..08f069e830 100644 --- a/src/quick/items/qquickflickable_p_p.h +++ b/src/quick/items/qquickflickable_p_p.h @@ -99,16 +99,17 @@ public: struct AxisData { AxisData(QQuickFlickablePrivate *fp, void (QQuickFlickablePrivate::*func)(qreal)) : move(fp, func) - , transitionToBounds(0) + , transitionToBounds(nullptr) , viewSize(-1), lastPos(0), previousDragDelta(0), velocity(0), startMargin(0), endMargin(0) , origin(0), overshoot(0) , transitionTo(0) , continuousFlickVelocity(0), velocityTime(), vTime(0) , smoothVelocity(fp), atEnd(false), atBeginning(true) , transitionToSet(false) - , fixingUp(false), inOvershoot(false), moving(false), flicking(false) + , fixingUp(false), inOvershoot(false), inRebound(false), moving(false), flicking(false) , dragging(false), extentsChanged(false) , explicitValue(false), minExtentDirty(true), maxExtentDirty(true) + , unused(0) {} ~AxisData(); @@ -168,6 +169,7 @@ public: bool explicitValue : 1; mutable bool minExtentDirty : 1; mutable bool maxExtentDirty : 1; + uint unused : 19; }; bool flickX(qreal velocity); @@ -282,7 +284,7 @@ class QQuickFlickableVisibleArea : public QObject Q_PROPERTY(qreal heightRatio READ heightRatio NOTIFY heightRatioChanged) public: - QQuickFlickableVisibleArea(QQuickFlickable *parent=0); + QQuickFlickableVisibleArea(QQuickFlickable *parent=nullptr); qreal xPosition() const; qreal widthRatio() const; diff --git a/src/quick/items/qquickflipable.cpp b/src/quick/items/qquickflipable.cpp index 4273ed4881..fbba8eed89 100644 --- a/src/quick/items/qquickflipable.cpp +++ b/src/quick/items/qquickflipable.cpp @@ -68,7 +68,7 @@ class QQuickFlipablePrivate : public QQuickItemPrivate { Q_DECLARE_PUBLIC(QQuickFlipable) public: - QQuickFlipablePrivate() : current(QQuickFlipable::Front), front(0), back(0), sideDirty(false) {} + QQuickFlipablePrivate() : current(QQuickFlipable::Front), front(nullptr), back(nullptr), sideDirty(false) {} void transformChanged() override; void updateSide(); @@ -178,7 +178,7 @@ void QQuickFlipable::setBack(QQuickItem *back) qmlWarning(this) << tr("back is a write-once property"); return; } - if (back == 0) + if (back == nullptr) return; d->back = back; d->back->setParentItem(this); diff --git a/src/quick/items/qquickflipable_p.h b/src/quick/items/qquickflipable_p.h index ec922725ef..d70cd02d35 100644 --- a/src/quick/items/qquickflipable_p.h +++ b/src/quick/items/qquickflipable_p.h @@ -74,7 +74,7 @@ class Q_AUTOTEST_EXPORT QQuickFlipable : public QQuickItem //### flipAxis //### flipRotation public: - QQuickFlipable(QQuickItem *parent=0); + QQuickFlipable(QQuickItem *parent=nullptr); ~QQuickFlipable(); QQuickItem *front() const; diff --git a/src/quick/items/qquickfocusscope_p.h b/src/quick/items/qquickfocusscope_p.h index b65e543343..af750fc127 100644 --- a/src/quick/items/qquickfocusscope_p.h +++ b/src/quick/items/qquickfocusscope_p.h @@ -59,7 +59,7 @@ class Q_AUTOTEST_EXPORT QQuickFocusScope : public QQuickItem { Q_OBJECT public: - QQuickFocusScope(QQuickItem *parent=0); + QQuickFocusScope(QQuickItem *parent=nullptr); virtual ~QQuickFocusScope(); }; diff --git a/src/quick/items/qquickframebufferobject.cpp b/src/quick/items/qquickframebufferobject.cpp index 5a40d6b705..48f8b8db5c 100644 --- a/src/quick/items/qquickframebufferobject.cpp +++ b/src/quick/items/qquickframebufferobject.cpp @@ -57,7 +57,7 @@ public: QQuickFramebufferObjectPrivate() : followsItemSize(true) , mirrorVertically(false) - , node(0) + , node(nullptr) { } @@ -194,10 +194,10 @@ class QSGFramebufferObjectNode : public QSGTextureProvider, public QSGSimpleText public: QSGFramebufferObjectNode() - : window(0) - , fbo(0) - , msDisplayFbo(0) - , renderer(0) + : window(nullptr) + , fbo(nullptr) + , msDisplayFbo(nullptr) + , renderer(nullptr) , renderPending(true) , invalidatePending(false) , devicePixelRatio(1) @@ -282,13 +282,13 @@ QSGNode *QQuickFramebufferObject::updatePaintNode(QSGNode *node, UpdatePaintNode // that easily so with this logic, the renderer only goes away when // the scenegraph is invalidated or it is removed from the scene. if (!n && (width() <= 0 || height() <= 0)) - return 0; + return nullptr; Q_D(QQuickFramebufferObject); if (!n) { if (!isOpenGL(d->sceneGraphRenderContext())) - return 0; + return nullptr; if (!d->node) d->node = new QSGFramebufferObjectNode; n = d->node; @@ -313,10 +313,11 @@ QSGNode *QQuickFramebufferObject::updatePaintNode(QSGNode *node, UpdatePaintNode desiredFboSize *= n->devicePixelRatio; if (n->fbo && ((d->followsItemSize && n->fbo->size() != desiredFboSize) || n->invalidatePending)) { + delete n->texture(); delete n->fbo; - n->fbo = 0; + n->fbo = nullptr; delete n->msDisplayFbo; - n->msDisplayFbo = 0; + n->msDisplayFbo = nullptr; n->invalidatePending = false; } @@ -367,10 +368,10 @@ QSGTextureProvider *QQuickFramebufferObject::textureProvider() const QQuickWindow *w = window(); if (!w || !w->openglContext() || QThread::currentThread() != w->openglContext()->thread()) { qWarning("QQuickFramebufferObject::textureProvider: can only be queried on the rendering thread of an exposed window"); - return 0; + return nullptr; } if (!isOpenGL(d->sceneGraphRenderContext())) - return 0; + return nullptr; if (!d->node) d->node = new QSGFramebufferObjectNode; return d->node; @@ -385,13 +386,13 @@ void QQuickFramebufferObject::releaseResources() // forget about the node. Since it is the node we returned from updatePaintNode // it will be managed by the scene graph. Q_D(QQuickFramebufferObject); - d->node = 0; + d->node = nullptr; } void QQuickFramebufferObject::invalidateSceneGraph() { Q_D(QQuickFramebufferObject); - d->node = 0; + d->node = nullptr; } /*! @@ -410,7 +411,7 @@ void QQuickFramebufferObject::invalidateSceneGraph() * GUI thread is blocked. */ QQuickFramebufferObject::Renderer::Renderer() - : data(0) + : data(nullptr) { } @@ -438,7 +439,7 @@ QQuickFramebufferObject::Renderer::~Renderer() */ QOpenGLFramebufferObject *QQuickFramebufferObject::Renderer::framebufferObject() const { - return data ? ((QSGFramebufferObjectNode *) data)->fbo : 0; + return data ? ((QSGFramebufferObjectNode *) data)->fbo : nullptr; } /*! diff --git a/src/quick/items/qquickgenericshadereffect.cpp b/src/quick/items/qquickgenericshadereffect.cpp index 305ef7e778..248c2b6ec3 100644 --- a/src/quick/items/qquickgenericshadereffect.cpp +++ b/src/quick/items/qquickgenericshadereffect.cpp @@ -61,7 +61,7 @@ QQuickGenericShaderEffect::QQuickGenericShaderEffect(QQuickShaderEffect *item, Q , m_mgr(nullptr) , m_fragNeedsUpdate(true) , m_vertNeedsUpdate(true) - , m_dirty(0) + , m_dirty(nullptr) { qRegisterMetaType<QSGGuiThreadShaderEffectManager::ShaderInfo::Type>("ShaderInfo::Type"); for (int i = 0; i < NShader; ++i) @@ -134,7 +134,7 @@ void QQuickGenericShaderEffect::setMesh(const QVariant &mesh) return; if (m_mesh) - disconnect(m_mesh, SIGNAL(geometryChanged()), this, 0); + disconnect(m_mesh, SIGNAL(geometryChanged()), this, nullptr); m_mesh = newMesh; @@ -290,7 +290,7 @@ QSGNode *QQuickGenericShaderEffect::handleUpdatePaintNode(QSGNode *oldNode, QQui m_dirty &= ~QSGShaderEffectNode::DirtyShaderGeometry; } - m_dirty = 0; + m_dirty = nullptr; for (int i = 0; i < NShader; ++i) { m_dirtyConstants[i].clear(); m_dirtyTextures[i].clear(); diff --git a/src/quick/items/qquickgenericshadereffect_p.h b/src/quick/items/qquickgenericshadereffect_p.h index ab19816493..3f6f92921b 100644 --- a/src/quick/items/qquickgenericshadereffect_p.h +++ b/src/quick/items/qquickgenericshadereffect_p.h @@ -66,7 +66,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickGenericShaderEffect : public QObject Q_OBJECT public: - QQuickGenericShaderEffect(QQuickShaderEffect *item, QObject *parent = 0); + QQuickGenericShaderEffect(QQuickShaderEffect *item, QObject *parent = nullptr); ~QQuickGenericShaderEffect(); QByteArray fragmentShader() const { return m_fragShader; } diff --git a/src/quick/items/qquickgraphicsinfo.cpp b/src/quick/items/qquickgraphicsinfo.cpp index a36133874b..e809bdd827 100644 --- a/src/quick/items/qquickgraphicsinfo.cpp +++ b/src/quick/items/qquickgraphicsinfo.cpp @@ -63,7 +63,7 @@ QT_BEGIN_NAMESPACE QQuickGraphicsInfo::QQuickGraphicsInfo(QQuickItem *item) : QObject(item) - , m_window(0) + , m_window(nullptr) , m_api(Unknown) , m_shaderType(UnknownShadingLanguage) , m_shaderCompilationType(ShaderCompilationType(0)) diff --git a/src/quick/items/qquickgridview.cpp b/src/quick/items/qquickgridview.cpp index 10262e8cc0..1f5cda9d18 100644 --- a/src/quick/items/qquickgridview.cpp +++ b/src/quick/items/qquickgridview.cpp @@ -230,7 +230,7 @@ public: : flow(QQuickGridView::FlowLeftToRight) , cellWidth(100), cellHeight(100), columns(1) , snapMode(QQuickGridView::NoSnap) - , highlightXAnimator(0), highlightYAnimator(0) + , highlightXAnimator(nullptr), highlightYAnimator(nullptr) {} ~QQuickGridViewPrivate() { @@ -390,7 +390,7 @@ FxViewItem *QQuickGridViewPrivate::snapItemAt(qreal pos) const if (itemTop+rowSize()/2 >= pos && itemTop - rowSize()/2 <= pos) return item; } - return 0; + return nullptr; } int QQuickGridViewPrivate::snapIndex() const @@ -508,12 +508,14 @@ bool QQuickGridViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, qreal } int colNum = qFloor((colPos+colSize()/2) / colSize()); - FxGridItemSG *item = 0; + FxGridItemSG *item = nullptr; bool changed = false; + QQmlIncubator::IncubationMode incubationMode = doBuffer ? QQmlIncubator::Asynchronous : QQmlIncubator::AsynchronousIfNested; + while (modelIndex < model->count() && rowPos <= fillTo + rowSize()*(columns - colNum)/(columns+1)) { qCDebug(lcItemViewDelegateLifecycle) << "refill: append item" << modelIndex << colPos << rowPos; - if (!(item = static_cast<FxGridItemSG*>(createItem(modelIndex, doBuffer)))) + if (!(item = static_cast<FxGridItemSG*>(createItem(modelIndex, incubationMode)))) break; if (!transitioner || !transitioner->canTransition(QQuickItemViewTransitioner::PopulateTransition, true)) // pos will be set by layoutVisibleItems() item->setPosition(colPos, rowPos, true); @@ -535,20 +537,19 @@ bool QQuickGridViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, qreal if (visibleItems.count()) { FxGridItemSG *firstItem = static_cast<FxGridItemSG*>(visibleItems.constFirst()); rowPos = firstItem->rowPos(); - colNum = qFloor((firstItem->colPos()+colSize()/2) / colSize()); - if (--colNum < 0) { - colNum = columns - 1; - rowPos -= rowSize(); - } - } else { - colNum = qFloor((colPos+colSize()/2) / colSize()); + colPos = firstItem->colPos(); + } + colNum = qFloor((colPos+colSize()/2) / colSize()); + if (--colNum < 0) { + colNum = columns - 1; + rowPos -= rowSize(); } // Prepend colPos = colNum * colSize(); while (visibleIndex > 0 && rowPos + rowSize() - 1 >= fillFrom - rowSize()*(colNum+1)/(columns+1)){ qCDebug(lcItemViewDelegateLifecycle) << "refill: prepend item" << visibleIndex-1 << "top pos" << rowPos << colPos; - if (!(item = static_cast<FxGridItemSG*>(createItem(visibleIndex-1, doBuffer)))) + if (!(item = static_cast<FxGridItemSG*>(createItem(visibleIndex-1, incubationMode)))) break; --visibleIndex; if (!transitioner || !transitioner->canTransition(QQuickItemViewTransitioner::PopulateTransition, true)) // pos will be set by layoutVisibleItems() @@ -579,7 +580,7 @@ void QQuickGridViewPrivate::removeItem(FxViewItem *item) bool QQuickGridViewPrivate::removeNonVisibleItems(qreal bufferFrom, qreal bufferTo) { - FxGridItemSG *item = 0; + FxGridItemSG *item = nullptr; bool changed = false; while (visibleItems.count() > 1 @@ -699,14 +700,14 @@ void QQuickGridViewPrivate::createHighlight() bool changed = false; if (highlight) { if (trackedItem == highlight) - trackedItem = 0; + trackedItem = nullptr; delete highlight; - highlight = 0; + highlight = nullptr; delete highlightXAnimator; delete highlightYAnimator; - highlightXAnimator = 0; - highlightYAnimator = 0; + highlightXAnimator = nullptr; + highlightYAnimator = nullptr; changed = true; } @@ -892,7 +893,6 @@ void QQuickGridViewPrivate::initializeCurrentItem() void QQuickGridViewPrivate::fixupPosition() { - moveReason = Other; if (flow == QQuickGridView::FlowLeftToRight) fixupY(); else @@ -2410,11 +2410,11 @@ bool QQuickGridViewPrivate::applyInsertionChange(const QQmlChangeSet::Change &ch } else { while (i >= 0) { // item is before first visible e.g. in cache buffer - FxViewItem *item = 0; + FxViewItem *item = nullptr; if (change.isMove() && (item = currentChanges.removedItems.take(change.moveKey(modelIndex + i)))) item->index = modelIndex + i; if (!item) - item = createItem(modelIndex + i); + item = createItem(modelIndex + i, QQmlIncubator::Synchronous); if (!item) return false; @@ -2462,12 +2462,12 @@ bool QQuickGridViewPrivate::applyInsertionChange(const QQmlChangeSet::Change &ch int i = 0; int to = buffer+displayMarginEnd+tempPos+size()-1; while (i < count && rowPos <= to + rowSize()*(columns - colNum)/qreal(columns+1)) { - FxViewItem *item = 0; + FxViewItem *item = nullptr; if (change.isMove() && (item = currentChanges.removedItems.take(change.moveKey(modelIndex + i)))) item->index = modelIndex + i; bool newItem = !item; if (!item) - item = createItem(modelIndex + i); + item = createItem(modelIndex + i, QQmlIncubator::Synchronous); if (!item) return false; diff --git a/src/quick/items/qquickgridview_p.h b/src/quick/items/qquickgridview_p.h index 5c6da2b433..7daeaf41a1 100644 --- a/src/quick/items/qquickgridview_p.h +++ b/src/quick/items/qquickgridview_p.h @@ -81,7 +81,7 @@ public: }; Q_ENUM(Flow) - QQuickGridView(QQuickItem *parent=0); + QQuickGridView(QQuickItem *parent=nullptr); ~QQuickGridView(); void setHighlightFollowsCurrentItem(bool) override; diff --git a/src/quick/items/qquickimage.cpp b/src/quick/items/qquickimage.cpp index 7e13e5e0e1..dc2cd17b4e 100644 --- a/src/quick/items/qquickimage.cpp +++ b/src/quick/items/qquickimage.cpp @@ -57,7 +57,7 @@ class QQuickImageTextureProvider : public QSGTextureProvider Q_OBJECT public: QQuickImageTextureProvider() - : m_texture(0) + : m_texture(nullptr) , m_smooth(false) { } @@ -97,7 +97,7 @@ QQuickImagePrivate::QQuickImagePrivate() , mipmap(false) , hAlign(QQuickImage::AlignHCenter) , vAlign(QQuickImage::AlignVCenter) - , provider(0) + , provider(nullptr) { } @@ -583,7 +583,7 @@ QSGTextureProvider *QQuickImage::textureProvider() const if (!d->window || !d->sceneGraphRenderContext() || QThread::currentThread() != d->sceneGraphRenderContext()->thread()) { qWarning("QQuickImage::textureProvider: can only be queried on the rendering thread of an exposed window"); - return 0; + return nullptr; } if (!d->provider) { @@ -601,7 +601,7 @@ void QQuickImage::invalidateSceneGraph() { Q_D(QQuickImage); delete d->provider; - d->provider = 0; + d->provider = nullptr; } void QQuickImage::releaseResources() @@ -609,7 +609,7 @@ void QQuickImage::releaseResources() Q_D(QQuickImage); if (d->provider) { QQuickWindowQObjectCleanupJob::schedule(window(), d->provider); - d->provider = 0; + d->provider = nullptr; } } @@ -628,7 +628,7 @@ QSGNode *QQuickImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) if (!texture || width() <= 0 || height() <= 0) { delete oldNode; - return 0; + return nullptr; } QSGInternalImageNode *node = static_cast<QSGInternalImageNode *>(oldNode); @@ -736,7 +736,7 @@ QSGNode *QQuickImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) || nsrect.isEmpty() || !qt_is_finite(nsrect.width()) || !qt_is_finite(nsrect.height())) { delete node; - return 0; + return nullptr; } if (d->pixmapChanged) { diff --git a/src/quick/items/qquickimage_p.h b/src/quick/items/qquickimage_p.h index 09b2c1eeb7..7fb4413900 100644 --- a/src/quick/items/qquickimage_p.h +++ b/src/quick/items/qquickimage_p.h @@ -70,7 +70,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickImage : public QQuickImageBase Q_PROPERTY(bool autoTransform READ autoTransform WRITE setAutoTransform NOTIFY autoTransformChanged REVISION 2) public: - QQuickImage(QQuickItem *parent=0); + QQuickImage(QQuickItem *parent=nullptr); ~QQuickImage(); enum HAlignment { AlignLeft = Qt::AlignLeft, diff --git a/src/quick/items/qquickimagebase_p.h b/src/quick/items/qquickimagebase_p.h index 4d4a6fceaf..eb04a1d162 100644 --- a/src/quick/items/qquickimagebase_p.h +++ b/src/quick/items/qquickimagebase_p.h @@ -70,7 +70,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickImageBase : public QQuickImplicitSizeItem Q_PROPERTY(bool mirror READ mirror WRITE setMirror NOTIFY mirrorChanged) public: - QQuickImageBase(QQuickItem *parent=0); + QQuickImageBase(QQuickItem *parent=nullptr); ~QQuickImageBase(); enum Status { Null, Ready, Loading, Error }; Q_ENUM(Status) diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index f8374bdbc2..3a0aea517c 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -87,8 +87,9 @@ QT_BEGIN_NAMESPACE Q_DECLARE_LOGGING_CATEGORY(DBG_MOUSE_TARGET) Q_DECLARE_LOGGING_CATEGORY(DBG_HOVER_TRACE) +Q_DECLARE_LOGGING_CATEGORY(lcTransient) -void debugFocusTree(QQuickItem *item, QQuickItem *scope = 0, int depth = 1) +void debugFocusTree(QQuickItem *item, QQuickItem *scope = nullptr, int depth = 1) { if (DBG_FOCUS().isEnabled(QtDebugMsg)) { qCDebug(DBG_FOCUS) @@ -302,9 +303,9 @@ void QQuickContents::itemChildAdded(QQuickItem *, QQuickItem *item) } QQuickItemKeyFilter::QQuickItemKeyFilter(QQuickItem *item) -: m_processPost(false), m_next(0) +: m_processPost(false), m_next(nullptr) { - QQuickItemPrivate *p = item?QQuickItemPrivate::get(item):0; + QQuickItemPrivate *p = item?QQuickItemPrivate::get(item):nullptr; if (p) { m_next = p->extra.value().keyHandler; p->extra->keyHandler = this; @@ -785,7 +786,7 @@ const SigMap sigMap[] = { { Qt::Key_Menu, "menuPressed" }, { Qt::Key_VolumeUp, "volumeUpPressed" }, { Qt::Key_VolumeDown, "volumeDownPressed" }, - { 0, 0 } + { 0, nullptr } }; QByteArray QQuickKeysAttached::keyToSignal(int key) @@ -970,7 +971,7 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const Keys.onEscapePressed: { console.log("escapeItem is handling escape"); - event.accepted = true; + // event.accepted is set to true by default for the specific key handlers } } @@ -1543,6 +1544,13 @@ QQuickKeysAttached *QQuickKeysAttached::qmlAttachedProperties(QObject *obj) mirroring is not the desired behavior, or if the child item already implements mirroring in some custom way. + To set the layout direction based on the \l {Default Layout Direction}{default layout direction} + of the application, use the following code: + + \code + LayoutMirroring.enabled: Qt.application.layoutDirection === Qt.RightToLeft + \endcode + See \l {Right-to-left User Interfaces} for further details on using \c LayoutMirroring and other related features to implement right-to-left support for an application. */ @@ -1569,7 +1577,7 @@ QQuickKeysAttached *QQuickKeysAttached::qmlAttachedProperties(QObject *obj) */ -QQuickLayoutMirroringAttached::QQuickLayoutMirroringAttached(QObject *parent) : QObject(parent), itemPrivate(0) +QQuickLayoutMirroringAttached::QQuickLayoutMirroringAttached(QObject *parent) : QObject(parent), itemPrivate(nullptr) { if (QQuickItem *item = qobject_cast<QQuickItem *>(parent)) itemPrivate = QQuickItemPrivate::get(item); @@ -1723,7 +1731,7 @@ void QQuickItemPrivate::setLayoutMirror(bool mirror) */ QQuickEnterKeyAttached::QQuickEnterKeyAttached(QObject *parent) - : QObject(parent), itemPrivate(0), keyType(Qt::EnterKeyDefault) + : QObject(parent), itemPrivate(nullptr), keyType(Qt::EnterKeyDefault) { if (QQuickItem *item = qobject_cast<QQuickItem*>(parent)) { itemPrivate = QQuickItemPrivate::get(item); @@ -1776,7 +1784,7 @@ void QQuickItemPrivate::updateSubFocusItem(QQuickItem *scope, bool focus) if (oldSubFocusItem) { QQuickItem *sfi = scopePrivate->subFocusItem->parentItem(); while (sfi && sfi != scope) { - QQuickItemPrivate::get(sfi)->subFocusItem = 0; + QQuickItemPrivate::get(sfi)->subFocusItem = nullptr; sfi = sfi->parentItem(); } } @@ -1789,7 +1797,7 @@ void QQuickItemPrivate::updateSubFocusItem(QQuickItem *scope, bool focus) sfi = sfi->parentItem(); } } else { - scopePrivate->subFocusItem = 0; + scopePrivate->subFocusItem = nullptr; } } @@ -2067,7 +2075,7 @@ void QQuickItemPrivate::updateSubFocusItem(QQuickItem *scope, bool focus) In the QPainter / QWidget world, it is some times favorable to cache complex content in a pixmap, image or texture. In Qt Quick, because of the techniques already applied by the \l {Qt Quick - Scene Graph Renderer} {scene graph renderer}, this will in most + Scene Graph OpenGL Renderer} {scene graph renderer}, this will in most cases not be the case. Excessive draw calls are already reduced because of batching and a cache will in most cases end up blending more pixels than the original content. The overhead of rendering @@ -2374,13 +2382,13 @@ QQuickItem::~QQuickItem() if (d->windowRefCount > 1) d->windowRefCount = 1; // Make sure window is set to null in next call to derefWindow(). if (d->parentItem) - setParentItem(0); + setParentItem(nullptr); else if (d->window) d->derefWindow(); // XXX todo - optimize while (!d->childItems.isEmpty()) - d->childItems.constFirst()->setParentItem(0); + d->childItems.constFirst()->setParentItem(nullptr); if (!d->changeListeners.isEmpty()) { const auto listeners = d->changeListeners; // NOTE: intentional copy (QTBUG-54732) @@ -2420,14 +2428,14 @@ QQuickItem::~QQuickItem() } if (d->extra.isAllocated()) { - delete d->extra->contents; d->extra->contents = 0; + delete d->extra->contents; d->extra->contents = nullptr; #if QT_CONFIG(quick_shadereffect) - delete d->extra->layer; d->extra->layer = 0; + delete d->extra->layer; d->extra->layer = nullptr; #endif } - delete d->_anchors; d->_anchors = 0; - delete d->_stateGroup; d->_stateGroup = 0; + delete d->_anchors; d->_anchors = nullptr; + delete d->_stateGroup; d->_stateGroup = nullptr; } /*! @@ -2542,7 +2550,7 @@ QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, boo bool all = QGuiApplication::styleHints()->tabFocusBehavior() == Qt::TabFocusAllControls; - QQuickItem *from = 0; + QQuickItem *from = nullptr; bool isTabFence = item->d_func()->isTabFence; if (forward) { if (!isTabFence) @@ -2677,7 +2685,7 @@ void QQuickItem::setParentItem(QQuickItem *parentItem) if (parentItem) { QQuickItem *itemAncestor = parentItem; - while (itemAncestor != 0) { + while (itemAncestor != nullptr) { if (Q_UNLIKELY(itemAncestor == this)) { qWarning() << "QQuickItem::setParentItem: Parent" << parentItem << "is already part of the subtree of" << this; return; @@ -2689,12 +2697,12 @@ void QQuickItem::setParentItem(QQuickItem *parentItem) d->removeFromDirtyList(); QQuickItem *oldParentItem = d->parentItem; - QQuickItem *scopeFocusedItem = 0; + QQuickItem *scopeFocusedItem = nullptr; if (oldParentItem) { QQuickItemPrivate *op = QQuickItemPrivate::get(oldParentItem); - QQuickItem *scopeItem = 0; + QQuickItem *scopeItem = nullptr; if (hasFocus() || op->subFocusItem == this) scopeFocusedItem = this; @@ -2724,7 +2732,7 @@ void QQuickItem::setParentItem(QQuickItem *parentItem) QQuickWindowPrivate::get(d->window)->parentlessItems.remove(this); } - QQuickWindow *parentWindow = parentItem ? QQuickItemPrivate::get(parentItem)->window : 0; + QQuickWindow *parentWindow = parentItem ? QQuickItemPrivate::get(parentItem)->window : nullptr; if (d->window == parentWindow) { // Avoid freeing and reallocating resources if the window stays the same. d->parentItem = parentItem; @@ -2744,7 +2752,7 @@ void QQuickItem::setParentItem(QQuickItem *parentItem) QQuickWindowPrivate::get(d->window)->parentlessItems.insert(this); d->setEffectiveVisibleRecur(d->calcEffectiveVisible()); - d->setEffectiveEnableRecur(0, d->calcEffectiveEnable()); + d->setEffectiveEnableRecur(nullptr, d->calcEffectiveEnable()); if (d->parentItem) { if (!scopeFocusedItem) { @@ -2808,7 +2816,8 @@ void QQuickItem::stackBefore(const QQuickItem *sibling) { Q_D(QQuickItem); if (!sibling || sibling == this || !d->parentItem || d->parentItem != QQuickItemPrivate::get(sibling)->parentItem) { - qWarning("QQuickItem::stackBefore: Cannot stack before %p, which must be a sibling", sibling); + qWarning().nospace() << "QQuickItem::stackBefore: Cannot stack " + << this << " before " << sibling << ", which must be a sibling"; return; } @@ -2852,7 +2861,8 @@ void QQuickItem::stackAfter(const QQuickItem *sibling) { Q_D(QQuickItem); if (!sibling || sibling == this || !d->parentItem || d->parentItem != QQuickItemPrivate::get(sibling)->parentItem) { - qWarning("QQuickItem::stackAfter: Cannot stack after %p, which must be a sibling", sibling); + qWarning().nospace() << "QQuickItem::stackAfter: Cannot stack " + << this << " after " << sibling << ", which must be a sibling"; return; } @@ -2942,6 +2952,7 @@ void QQuickItemPrivate::addChild(QQuickItem *child) if (childPrivate->subtreeHoverEnabled && !subtreeHoverEnabled) setHasHoverInChild(true); + childPrivate->recursiveRefFromEffectItem(extra.value().recursiveEffectRefCount); markSortedChildrenDirty(child); dirty(QQuickItemPrivate::ChildrenChanged); @@ -2970,6 +2981,7 @@ void QQuickItemPrivate::removeChild(QQuickItem *child) if (childPrivate->subtreeHoverEnabled && subtreeHoverEnabled) setHasHoverInChild(false); + childPrivate->recursiveRefFromEffectItem(-extra.value().recursiveEffectRefCount); markSortedChildrenDirty(child); dirty(QQuickItemPrivate::ChildrenChanged); @@ -2990,7 +3002,7 @@ void QQuickItemPrivate::refWindow(QQuickWindow *c) // derefWindow() decrements the reference count. Q_Q(QQuickItem); - Q_ASSERT((window != 0) == (windowRefCount > 0)); + Q_ASSERT((window != nullptr) == (windowRefCount > 0)); Q_ASSERT(c); if (++windowRefCount > 1) { if (c != window) @@ -2998,7 +3010,7 @@ void QQuickItemPrivate::refWindow(QQuickWindow *c) return; // Window already set. } - Q_ASSERT(window == 0); + Q_ASSERT(window == nullptr); window = c; if (polishScheduled) @@ -3022,7 +3034,7 @@ void QQuickItemPrivate::refWindow(QQuickWindow *c) void QQuickItemPrivate::derefWindow() { Q_Q(QQuickItem); - Q_ASSERT((window != 0) == (windowRefCount > 0)); + Q_ASSERT((window != nullptr) == (windowRefCount > 0)); if (!window) return; // This can happen when destroying recursive shader effect sources. @@ -3038,7 +3050,7 @@ void QQuickItemPrivate::derefWindow() c->removeGrabber(q); #if QT_CONFIG(cursor) if (c->cursorItem == q) { - c->cursorItem = 0; + c->cursorItem = nullptr; window->unsetCursor(); } #endif @@ -3048,17 +3060,17 @@ void QQuickItemPrivate::derefWindow() if (!parentItem) c->parentlessItems.remove(q); - window = 0; + window = nullptr; - itemNodeInstance = 0; + itemNodeInstance = nullptr; if (extra.isAllocated()) { - extra->opacityNode = 0; - extra->clipNode = 0; - extra->rootNode = 0; + extra->opacityNode = nullptr; + extra->clipNode = nullptr; + extra->rootNode = nullptr; } - paintNode = 0; + paintNode = nullptr; for (int ii = 0; ii < childItems.count(); ++ii) { QQuickItem *child = childItems.at(ii); @@ -3068,8 +3080,8 @@ void QQuickItemPrivate::derefWindow() dirty(Window); if (extra.isAllocated() && extra->screenAttached) - extra->screenAttached->windowChanged(0); - itemChange(QQuickItem::ItemSceneChange, (QQuickWindow *)0); + extra->screenAttached->windowChanged(nullptr); + itemChange(QQuickItem::ItemSceneChange, (QQuickWindow *)nullptr); } @@ -3155,8 +3167,8 @@ bool QQuickItem::isComponentComplete() const } QQuickItemPrivate::QQuickItemPrivate() - : _anchors(0) - , _stateGroup(0) + : _anchors(nullptr) + , _stateGroup(nullptr) , flags(0) , widthValid(false) , heightValid(false) @@ -3197,13 +3209,13 @@ QQuickItemPrivate::QQuickItemPrivate() , touchEnabled(false) #endif , dirtyAttributes(0) - , nextDirtyItem(0) - , prevDirtyItem(0) - , window(0) + , nextDirtyItem(nullptr) + , prevDirtyItem(nullptr) + , window(nullptr) , windowRefCount(0) - , parentItem(0) + , parentItem(nullptr) , sortedChildItems(&childItems) - , subFocusItem(0) + , subFocusItem(nullptr) , x(0) , y(0) , width(0) @@ -3211,8 +3223,8 @@ QQuickItemPrivate::QQuickItemPrivate() , implicitWidth(0) , implicitHeight(0) , baselineOffset(0) - , itemNodeInstance(0) - , paintNode(0) + , itemNodeInstance(nullptr) + , paintNode(nullptr) { } @@ -3253,7 +3265,7 @@ void QQuickItemPrivate::data_append(QQmlListProperty<QObject> *prop, QObject *o) // because there can be multiple handlers... that->setAcceptedMouseButtons(Qt::AllButtons); QQuickItemPrivate *p = QQuickItemPrivate::get(that); - p->extra.value().pointerHandlers.append(pointerHandler); + p->extra.value().pointerHandlers.prepend(pointerHandler); } else { QQuickWindow *thisWindow = qmlobject_cast<QQuickWindow *>(o); QQuickItem *item = that; @@ -3264,11 +3276,13 @@ void QQuickItemPrivate::data_append(QQmlListProperty<QObject> *prop, QObject *o) } if (thisWindow) { - if (itemWindow) + if (itemWindow) { + qCDebug(lcTransient) << thisWindow << "is transient for" << itemWindow; thisWindow->setTransientParent(itemWindow); - else + } else { QObject::connect(item, SIGNAL(windowChanged(QQuickWindow*)), thisWindow, SLOT(setTransientParent_helper(QQuickWindow*))); + } } o->setParent(that); } @@ -3335,7 +3349,7 @@ QObject *QQuickItemPrivate::data_at(QQmlListProperty<QObject> *property, int i) const int j = i - resourcesCount; if (j < children_count(&childrenProperty)) return children_at(&childrenProperty, j); - return 0; + return nullptr; } void QQuickItemPrivate::data_clear(QQmlListProperty<QObject> *property) @@ -3389,7 +3403,7 @@ QQuickItem *QQuickItemPrivate::children_at(QQmlListProperty<QQuickItem> *prop, i { QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object)); if (index >= p->childItems.count() || index < 0) - return 0; + return nullptr; else return p->childItems.at(index); } @@ -3401,7 +3415,7 @@ void QQuickItemPrivate::children_append(QQmlListProperty<QQuickItem> *prop, QQui QQuickItem *that = static_cast<QQuickItem *>(prop->object); if (o->parentItem() == that) - o->setParentItem(0); + o->setParentItem(nullptr); o->setParentItem(that); } @@ -3417,7 +3431,7 @@ void QQuickItemPrivate::children_clear(QQmlListProperty<QQuickItem> *prop) QQuickItem *that = static_cast<QQuickItem *>(prop->object); QQuickItemPrivate *p = QQuickItemPrivate::get(that); while (!p->childItems.isEmpty()) - p->childItems.at(0)->setParentItem(0); + p->childItems.at(0)->setParentItem(nullptr); } int QQuickItemPrivate::visibleChildren_count(QQmlListProperty<QQuickItem> *prop) @@ -3437,14 +3451,14 @@ QQuickItem *QQuickItemPrivate::visibleChildren_at(QQmlListProperty<QQuickItem> * QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object)); const int childCount = p->childItems.count(); if (index >= childCount || index < 0) - return 0; + return nullptr; int visibleCount = -1; for (int i = 0; i < childCount; i++) { if (p->childItems.at(i)->isVisible()) visibleCount++; if (visibleCount == index) return p->childItems.at(i); } - return 0; + return nullptr; } int QQuickItemPrivate::transform_count(QQmlListProperty<QQuickTransform> *prop) @@ -3508,7 +3522,7 @@ QQuickTransform *QQuickItemPrivate::transform_at(QQmlListProperty<QQuickTransfor QQuickItemPrivate *p = QQuickItemPrivate::get(that); if (idx < 0 || idx >= p->transforms.count()) - return 0; + return nullptr; else return p->transforms.at(idx); } @@ -3655,7 +3669,7 @@ void QQuickItemPrivate::siblingOrderChanged() QQmlListProperty<QObject> QQuickItemPrivate::data() { - return QQmlListProperty<QObject>(q_func(), 0, QQuickItemPrivate::data_append, + return QQmlListProperty<QObject>(q_func(), nullptr, QQuickItemPrivate::data_append, QQuickItemPrivate::data_count, QQuickItemPrivate::data_at, QQuickItemPrivate::data_clear); @@ -3667,8 +3681,9 @@ QQmlListProperty<QObject> QQuickItemPrivate::data() \qmlproperty real QtQuick::Item::childrenRect.y \qmlproperty real QtQuick::Item::childrenRect.width \qmlproperty real QtQuick::Item::childrenRect.height + \readonly - This property holds the collective position and size of the item's + This read-only property holds the collective position and size of the item's children. This property is useful if you need to access the collective geometry @@ -3833,11 +3848,11 @@ QSGNode *QQuickItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *upda { Q_UNUSED(updatePaintNodeData) delete oldNode; - return 0; + return nullptr; } QQuickItem::UpdatePaintNodeData::UpdatePaintNodeData() -: transformNode(0) +: transformNode(nullptr) { } @@ -3948,8 +3963,8 @@ void QQuickItem::inputMethodEvent(QInputMethodEvent *event) /*! This event handler can be reimplemented in a subclass to receive focus-in - events for an item. The event information is provided by the - \a event parameter. + events for an item. The event information is provided by the \c event + parameter. */ void QQuickItem::focusInEvent(QFocusEvent * /*event*/) { @@ -3965,8 +3980,8 @@ void QQuickItem::focusInEvent(QFocusEvent * /*event*/) /*! This event handler can be reimplemented in a subclass to receive focus-out - events for an item. The event information is provided by the - \a event parameter. + events for an item. The event information is provided by the \c event + parameter. */ void QQuickItem::focusOutEvent(QFocusEvent * /*event*/) { @@ -4402,7 +4417,7 @@ void QQuickItem::mapFromItem(QQmlV4Function *args) const QV4::Scope scope(v4); QV4::ScopedValue item(scope, (*args)[0]); - QQuickItem *itemObj = 0; + QQuickItem *itemObj = nullptr; if (!item->isNull()) { QV4::Scoped<QV4::QObjectWrapper> qobjectWrapper(scope, item->as<QV4::QObjectWrapper>()); if (qobjectWrapper) @@ -4490,7 +4505,7 @@ void QQuickItem::mapToItem(QQmlV4Function *args) const QV4::Scope scope(v4); QV4::ScopedValue item(scope, (*args)[0]); - QQuickItem *itemObj = 0; + QQuickItem *itemObj = nullptr; if (!item->isNull()) { QV4::Scoped<QV4::QObjectWrapper> qobjectWrapper(scope, item->as<QV4::QObjectWrapper>()); if (qobjectWrapper) @@ -4723,12 +4738,12 @@ QQuickItem *QQuickItem::childAt(qreal x, qreal y) const && child->height() > point.y()) return child; } - return 0; + return nullptr; } QQmlListProperty<QObject> QQuickItemPrivate::resources() { - return QQmlListProperty<QObject>(q_func(), 0, QQuickItemPrivate::resources_append, + return QQmlListProperty<QObject>(q_func(), nullptr, QQuickItemPrivate::resources_append, QQuickItemPrivate::resources_count, QQuickItemPrivate::resources_at, QQuickItemPrivate::resources_clear); @@ -4753,7 +4768,7 @@ QQmlListProperty<QObject> QQuickItemPrivate::resources() */ QQmlListProperty<QQuickItem> QQuickItemPrivate::children() { - return QQmlListProperty<QQuickItem>(q_func(), 0, QQuickItemPrivate::children_append, + return QQmlListProperty<QQuickItem>(q_func(), nullptr, QQuickItemPrivate::children_append, QQuickItemPrivate::children_count, QQuickItemPrivate::children_at, QQuickItemPrivate::children_clear); @@ -4773,7 +4788,7 @@ QQmlListProperty<QQuickItem> QQuickItemPrivate::children() QQmlListProperty<QQuickItem> QQuickItemPrivate::visibleChildren() { return QQmlListProperty<QQuickItem>(q_func(), - 0, + nullptr, QQuickItemPrivate::visibleChildren_count, QQuickItemPrivate::visibleChildren_at); @@ -4923,7 +4938,7 @@ void QQuickItem::setState(const QString &state) */ QQmlListProperty<QQuickTransform> QQuickItem::transform() { - return QQmlListProperty<QQuickTransform>(this, 0, QQuickItemPrivate::transform_append, + return QQmlListProperty<QQuickTransform>(this, nullptr, QQuickItemPrivate::transform_append, QQuickItemPrivate::transform_count, QQuickItemPrivate::transform_at, QQuickItemPrivate::transform_clear); @@ -5171,8 +5186,8 @@ void QQuickItem::updateInputMethod(Qt::InputMethodQueries queries) } #endif // im -/*! \internal */ // XXX todo - do we want/need this anymore? +/*! \internal */ QRectF QQuickItem::boundingRect() const { Q_D(const QQuickItem); @@ -5806,19 +5821,24 @@ bool QQuickItem::isVisible() const return d->effectiveVisible; } -void QQuickItem::setVisible(bool v) +void QQuickItemPrivate::setVisible(bool visible) { - Q_D(QQuickItem); - if (v == d->explicitVisible) + if (visible == explicitVisible) return; - d->explicitVisible = v; - if (!v) - d->dirty(QQuickItemPrivate::Visible); + explicitVisible = visible; + if (!visible) + dirty(QQuickItemPrivate::Visible); - const bool childVisibilityChanged = d->setEffectiveVisibleRecur(d->calcEffectiveVisible()); - if (childVisibilityChanged && d->parentItem) - emit d->parentItem->visibleChildrenChanged(); // signal the parent, not this! + const bool childVisibilityChanged = setEffectiveVisibleRecur(calcEffectiveVisible()); + if (childVisibilityChanged && parentItem) + emit parentItem->visibleChildrenChanged(); // signal the parent, not this! +} + +void QQuickItem::setVisible(bool v) +{ + Q_D(QQuickItem); + d->setVisible(v); } /*! @@ -6052,8 +6072,8 @@ void QQuickItemPrivate::removeFromDirtyList() if (prevDirtyItem) { if (nextDirtyItem) QQuickItemPrivate::get(nextDirtyItem)->prevDirtyItem = prevDirtyItem; *prevDirtyItem = nextDirtyItem; - prevDirtyItem = 0; - nextDirtyItem = 0; + prevDirtyItem = nullptr; + nextDirtyItem = nullptr; } Q_ASSERT(!prevDirtyItem); Q_ASSERT(!nextDirtyItem); @@ -6062,28 +6082,48 @@ void QQuickItemPrivate::removeFromDirtyList() void QQuickItemPrivate::refFromEffectItem(bool hide) { ++extra.value().effectRefCount; - if (1 == extra->effectRefCount) { + if (extra->effectRefCount == 1) { dirty(EffectReference); - if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged); + if (parentItem) + QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged); } if (hide) { if (++extra->hideRefCount == 1) dirty(HideReference); } + recursiveRefFromEffectItem(1); +} + +void QQuickItemPrivate::recursiveRefFromEffectItem(int refs) +{ + Q_Q(QQuickItem); + if (!refs) + return; + extra.value().recursiveEffectRefCount += refs; + for (int ii = 0; ii < childItems.count(); ++ii) { + QQuickItem *child = childItems.at(ii); + QQuickItemPrivate::get(child)->recursiveRefFromEffectItem(refs); + } + // Polish may rely on the effect ref count so trigger one, if item is not visible + // (if visible, it will be triggered automatically). + if (!effectiveVisible && refs > 0 && extra.value().recursiveEffectRefCount == 1) // it wasn't referenced, now it's referenced + q->polish(); } void QQuickItemPrivate::derefFromEffectItem(bool unhide) { Q_ASSERT(extra->effectRefCount); --extra->effectRefCount; - if (0 == extra->effectRefCount) { + if (extra->effectRefCount == 0) { dirty(EffectReference); - if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged); + if (parentItem) + QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged); } if (unhide) { if (--extra->hideRefCount == 0) dirty(HideReference); } + recursiveRefFromEffectItem(-1); } void QQuickItemPrivate::setCulled(bool cull) @@ -7102,7 +7142,7 @@ QQuickItem *QQuickItem::scopedFocusItem() const { Q_D(const QQuickItem); if (!isFocusScope()) - return 0; + return nullptr; else return d->subFocusItem; } @@ -7409,10 +7449,18 @@ void QQuickItem::unsetCursor() void QQuickItem::grabMouse() { Q_D(QQuickItem); - if (!d->window) + if (!d->window || d->window->mouseGrabberItem() == this) return; QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(d->window); - windowPriv->setMouseGrabber(this); + bool fromTouch = windowPriv->isDeliveringTouchAsMouse(); + auto point = fromTouch ? + windowPriv->pointerEventInstance(windowPriv->touchMouseDevice)->pointById(windowPriv->touchMouseId) : + windowPriv->pointerEventInstance(QQuickPointerDevice::genericMouseDevice())->point(0); + if (point) { + QQuickItem *oldGrabber = point->grabberItem(); + point->setGrabberItem(this); + windowPriv->sendUngrabEvent(oldGrabber, fromTouch); + } } /*! @@ -7430,7 +7478,7 @@ void QQuickItem::ungrabMouse() if (!d->window) return; QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(d->window); - windowPriv->removeGrabber(this, true, false); + windowPriv->removeGrabber(this, true, windowPriv->isDeliveringTouchAsMouse()); } @@ -7560,9 +7608,75 @@ void QQuickItem::setKeepTouchGrab(bool keep) bool QQuickItem::contains(const QPointF &point) const { Q_D(const QQuickItem); - qreal x = point.x(); - qreal y = point.y(); - return x >= 0 && y >= 0 && x <= d->width && y <= d->height; + if (d->mask) { + bool res = false; + d->extra->maskContains.invoke(d->mask, + Qt::DirectConnection, + Q_RETURN_ARG(bool, res), + Q_ARG(QPointF, point)); + return res; + } else { + qreal x = point.x(); + qreal y = point.y(); + return x >= 0 && y >= 0 && x <= d->width && y <= d->height; + } +} + +/*! + \qmlproperty QObject* QtQuick::Item::containmentMask + \since 5.11 + This property holds an optional mask for the Item to be used in the + QtQuick::Item::contains method. + QtQuick::Item::contains main use is currently to determine whether + an input event has landed into the item or not. + + By default the \l contains method will return true for any point + within the Item's bounding box. \c containmentMask allows for a + more fine-grained control. For example, the developer could + define and use an AnotherItem element as containmentMask, + which has a specialized contains method, like: + + \code + Item { id: item; containmentMask: AnotherItem { id: anotherItem } } + \endcode + + \e{item}'s contains method would then return true only if + \e{anotherItem}'s contains implementation returns true. +*/ +QObject *QQuickItem::containmentMask() const +{ + Q_D(const QQuickItem); + return d->mask.data(); +} + +void QQuickItem::setContainmentMask(QObject *mask) +{ + Q_D(QQuickItem); + // an Item can't mask itself (to prevent infinite loop in contains()) + if (d->mask.data() == mask || mask == static_cast<QObject *>(this)) + return; + + QQuickItem *quickMask = qobject_cast<QQuickItem *>(d->mask); + if (quickMask) { + QQuickItemPrivate *maskPrivate = QQuickItemPrivate::get(quickMask); + maskPrivate->registerAsContainmentMask(this, false); // removed from use as my mask + } + + if (mask) { + int methodIndex = mask->metaObject()->indexOfMethod(QByteArrayLiteral("contains(QPointF)")); + if (methodIndex < 0) { + qmlWarning(this) << QStringLiteral("QQuickItem: Object set as mask does not have an invokable contains method, ignoring it."); + return; + } + d->extra.value().maskContains = mask->metaObject()->method(methodIndex); + } + d->mask = mask; + quickMask = qobject_cast<QQuickItem *>(mask); + if (quickMask) { + QQuickItemPrivate *maskPrivate = QQuickItemPrivate::get(quickMask); + maskPrivate->registerAsContainmentMask(this, true); // telling maskPrivate that "this" is using it as mask + } + emit containmentMaskChanged(); } /*! @@ -7949,7 +8063,7 @@ QSGTextureProvider *QQuickItem::textureProvider() const #if QT_CONFIG(quick_shadereffect) Q_D(const QQuickItem); return d->extra.isAllocated() && d->extra->layer && d->extra->layer->effectSource() ? - d->extra->layer->effectSource()->textureProvider() : 0; + d->extra->layer->effectSource()->textureProvider() : nullptr; #else return 0; #endif @@ -7988,9 +8102,9 @@ QQuickItemLayer::QQuickItemLayer(QQuickItem *item) , m_wrapMode(QQuickShaderEffectSource::ClampToEdge) , m_format(QQuickShaderEffectSource::RGBA) , m_name("source") - , m_effectComponent(0) - , m_effect(0) - , m_effectSource(0) + , m_effectComponent(nullptr) + , m_effect(nullptr) + , m_effectSource(nullptr) , m_textureMirroring(QQuickShaderEffectSource::MirrorVertically) , m_samples(0) { @@ -8091,7 +8205,7 @@ void QQuickItemLayer::deactivate() deactivateEffect(); delete m_effectSource; - m_effectSource = 0; + m_effectSource = nullptr; QQuickItemPrivate *id = QQuickItemPrivate::get(m_item); id->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Opacity | QQuickItemPrivate::Parent | QQuickItemPrivate::Visibility | QQuickItemPrivate::SiblingOrder); @@ -8128,7 +8242,7 @@ void QQuickItemLayer::deactivateEffect() Q_ASSERT(m_effectComponent); delete m_effect; - m_effect = 0; + m_effect = nullptr; } @@ -8436,7 +8550,7 @@ void QQuickItemLayer::itemParentChanged(QQuickItem *item, QQuickItem *parent) Q_UNUSED(item) Q_ASSERT(item == m_item); Q_ASSERT(parent != m_effectSource); - Q_ASSERT(parent == 0 || parent != m_effect); + Q_ASSERT(parent == nullptr || parent != m_effect); m_effectSource->setParentItem(parent); if (parent) @@ -8508,15 +8622,16 @@ void QQuickItemLayer::updateMatrix() QQuickItemPrivate::ExtraData::ExtraData() : z(0), scale(1), rotation(0), opacity(1), - contents(0), screenAttached(0), layoutDirectionAttached(0), - enterKeyAttached(0), - keyHandler(0), + contents(nullptr), screenAttached(nullptr), layoutDirectionAttached(nullptr), + enterKeyAttached(nullptr), + keyHandler(nullptr), #if QT_CONFIG(quick_shadereffect) - layer(0), + layer(nullptr), #endif effectRefCount(0), hideRefCount(0), - opacityNode(0), clipNode(0), rootNode(0), - acceptedMouseButtons(0), origin(QQuickItem::Center), + recursiveEffectRefCount(0), + opacityNode(nullptr), clipNode(nullptr), rootNode(nullptr), + acceptedMouseButtons(nullptr), origin(QQuickItem::Center), transparentForPositioner(false) { } diff --git a/src/quick/items/qquickitem.h b/src/quick/items/qquickitem.h index f6ee54e94d..cfdb2ad5b7 100644 --- a/src/quick/items/qquickitem.h +++ b/src/quick/items/qquickitem.h @@ -60,7 +60,7 @@ class Q_QUICK_EXPORT QQuickTransform : public QObject Q_OBJECT public: explicit QQuickTransform(QObject *parent = nullptr); - ~QQuickTransform(); + ~QQuickTransform() override; void appendToItem(QQuickItem *); void prependToItem(QQuickItem *); @@ -144,6 +144,7 @@ class Q_QUICK_EXPORT QQuickItem : public QObject, public QQmlParserStatus Q_PROPERTY(bool antialiasing READ antialiasing WRITE setAntialiasing NOTIFY antialiasingChanged RESET resetAntialiasing) Q_PROPERTY(qreal implicitWidth READ implicitWidth WRITE setImplicitWidth NOTIFY implicitWidthChanged) Q_PROPERTY(qreal implicitHeight READ implicitHeight WRITE setImplicitHeight NOTIFY implicitHeightChanged) + Q_PROPERTY(QObject *containmentMask READ containmentMask WRITE setContainmentMask NOTIFY containmentMaskChanged REVISION 11) Q_PRIVATE_PROPERTY(QQuickItem::d_func(), QQuickItemLayer *layer READ layer DESIGNABLE false CONSTANT FINAL) @@ -197,7 +198,7 @@ public: Q_ENUM(TransformOrigin) explicit QQuickItem(QQuickItem *parent = nullptr); - virtual ~QQuickItem(); + ~QQuickItem() override; QQuickWindow *window() const; QQuickItem *parentItem() const; @@ -320,6 +321,8 @@ public: QSharedPointer<QQuickItemGrabResult> grabToImage(const QSize &targetSize = QSize()); Q_INVOKABLE virtual bool contains(const QPointF &point) const; + QObject *containmentMask() const; + void setContainmentMask(QObject *mask); QTransform itemTransform(QQuickItem *, bool *) const; QPointF mapToItem(const QQuickItem *item, const QPointF &point) const; @@ -390,6 +393,7 @@ Q_SIGNALS: void zChanged(); void implicitWidthChanged(); void implicitHeightChanged(); + Q_REVISION(11) void containmentMaskChanged(); protected: bool event(QEvent *) override; diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h index 9ed5286f22..93287cf0aa 100644 --- a/src/quick/items/qquickitem_p.h +++ b/src/quick/items/qquickitem_p.h @@ -93,11 +93,11 @@ class QQuickContents : public QQuickItemChangeListener { public: QQuickContents(QQuickItem *item); - ~QQuickContents(); + ~QQuickContents() override; QRectF rectF() const { return m_contents; } - inline void calcGeometry(QQuickItem *changed = 0); + inline void calcGeometry(QQuickItem *changed = nullptr); void complete(); protected: @@ -108,8 +108,8 @@ protected: //void itemVisibilityChanged(QQuickItem *item) private: - bool calcHeight(QQuickItem *changed = 0); - bool calcWidth(QQuickItem *changed = 0); + bool calcHeight(QQuickItem *changed = nullptr); + bool calcWidth(QQuickItem *changed = nullptr); void updateRect(); QQuickItem *m_item; @@ -154,7 +154,7 @@ class QQuickItemLayer : public QObject, public QQuickItemChangeListener public: QQuickItemLayer(QQuickItem *item); - ~QQuickItemLayer(); + ~QQuickItemLayer() override; void classBegin(); void componentComplete(); @@ -255,7 +255,7 @@ public: static const QQuickItemPrivate* get(const QQuickItem *item) { return item->d_func(); } QQuickItemPrivate(); - ~QQuickItemPrivate(); + ~QQuickItemPrivate() override; void init(QQuickItem *parent); QQmlListProperty<QObject> data(); @@ -311,7 +311,6 @@ public: static void transform_clear(QQmlListProperty<QQuickTransform> *list); void _q_resourceObjectDeleted(QObject *); - void _q_windowChanged(QQuickWindow *w); quint64 _q_createJSWrapper(QV4::ExecutionEngine *engine); enum ChangeType { @@ -331,7 +330,7 @@ public: Q_DECLARE_FLAGS(ChangeTypes, ChangeType) struct ChangeListener { - ChangeListener(QQuickItemChangeListener *l = nullptr, QQuickItemPrivate::ChangeTypes t = 0) : listener(l), types(t), gTypes(QQuickGeometryChange::All) {} + ChangeListener(QQuickItemChangeListener *l = nullptr, QQuickItemPrivate::ChangeTypes t = nullptr) : listener(l), types(t), gTypes(QQuickGeometryChange::All) {} ChangeListener(QQuickItemChangeListener *l, QQuickGeometryChange gt) : listener(l), types(Geometry), gTypes(gt) {} QQuickItemChangeListener *listener; QQuickItemPrivate::ChangeTypes types; @@ -361,13 +360,19 @@ public: #endif QPointF userTransformOriginPoint; + // these do not include child items int effectRefCount; int hideRefCount; + // updated recursively for child items as well + int recursiveEffectRefCount; QSGOpacityNode *opacityNode; QQuickDefaultClipNode *clipNode; QSGRootNode *rootNode; + // Mask contains() method + QMetaMethod maskContains; + QObjectList resourcesList; // Although acceptedMouseButtons is inside ExtraData, we actually store @@ -382,6 +387,10 @@ public: // 26 bits padding }; QLazilyAllocated<ExtraData> extra; + // Contains mask + QPointer<QObject> mask; + // If the mask is an Item, inform it that it's being used as a mask (true) or is no longer being used (false) + virtual void registerAsContainmentMask(QQuickItem * /* maskedItem */, bool /* set */) { } QQuickAnchors *anchors() const; mutable QQuickAnchors *_anchors; @@ -574,6 +583,8 @@ public: virtual bool handlePointerEvent(QQuickPointerEvent *, bool avoidExclusiveGrabber = false); + virtual void setVisible(bool visible); + bool isTransparentForPositioner() const; void setTransparentForPositioner(bool trans); @@ -594,9 +605,9 @@ public: - (rootNode) (shader effect source's root node) */ - QSGOpacityNode *opacityNode() const { return extra.isAllocated()?extra->opacityNode:0; } - QQuickDefaultClipNode *clipNode() const { return extra.isAllocated()?extra->clipNode:0; } - QSGRootNode *rootNode() const { return extra.isAllocated()?extra->rootNode:0; } + QSGOpacityNode *opacityNode() const { return extra.isAllocated()?extra->opacityNode:nullptr; } + QQuickDefaultClipNode *clipNode() const { return extra.isAllocated()?extra->clipNode:nullptr; } + QSGRootNode *rootNode() const { return extra.isAllocated()?extra->rootNode:nullptr; } QSGTransformNode *itemNodeInstance; QSGNode *paintNode; @@ -606,6 +617,7 @@ public: // A reference from an effect item means that this item is used by the effect, so // it should insert a root node. void refFromEffectItem(bool hide); + void recursiveRefFromEffectItem(int refs); void derefFromEffectItem(bool unhide); void itemChange(QQuickItem::ItemChange, const QQuickItem::ItemChangeData &); @@ -627,7 +639,7 @@ public: class QQuickItemKeyFilter { public: - QQuickItemKeyFilter(QQuickItem * = 0); + QQuickItemKeyFilter(QQuickItem * = nullptr); virtual ~QQuickItemKeyFilter(); virtual void keyPressed(QKeyEvent *event, bool post); @@ -649,17 +661,15 @@ class QQuickKeyNavigationAttachedPrivate : public QObjectPrivate { public: QQuickKeyNavigationAttachedPrivate() - : QObjectPrivate(), - left(0), right(0), up(0), down(0), tab(0), backtab(0), - leftSet(false), rightSet(false), upSet(false), downSet(false), + : leftSet(false), rightSet(false), upSet(false), downSet(false), tabSet(false), backtabSet(false) {} - QQuickItem *left; - QQuickItem *right; - QQuickItem *up; - QQuickItem *down; - QQuickItem *tab; - QQuickItem *backtab; + QQuickItem *left = nullptr; + QQuickItem *right = nullptr; + QQuickItem *up = nullptr; + QQuickItem *down = nullptr; + QQuickItem *tab = nullptr; + QQuickItem *backtab = nullptr; bool leftSet : 1; bool rightSet : 1; bool upSet : 1; @@ -682,7 +692,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickKeyNavigationAttached : public QObject, publi Q_PROPERTY(Priority priority READ priority WRITE setPriority NOTIFY priorityChanged) public: - QQuickKeyNavigationAttached(QObject * = 0); + QQuickKeyNavigationAttached(QObject * = nullptr); QQuickItem *left() const; void setLeft(QQuickItem *); @@ -727,7 +737,7 @@ class QQuickLayoutMirroringAttached : public QObject Q_PROPERTY(bool childrenInherit READ childrenInherit WRITE setChildrenInherit NOTIFY childrenInheritChanged) public: - explicit QQuickLayoutMirroringAttached(QObject *parent = 0); + explicit QQuickLayoutMirroringAttached(QObject *parent = nullptr); bool enabled() const; void setEnabled(bool); @@ -770,8 +780,7 @@ class QQuickKeysAttachedPrivate : public QObjectPrivate { public: QQuickKeysAttachedPrivate() - : QObjectPrivate(), inPress(false), inRelease(false) - , inIM(false), enabled(true), imeItem(0), item(0) + : inPress(false), inRelease(false), inIM(false), enabled(true) {} //loop detection @@ -781,9 +790,9 @@ public: bool enabled : 1; - QQuickItem *imeItem; + QQuickItem *imeItem = nullptr; QList<QQuickItem *> targets; - QQuickItem *item; + QQuickItem *item = nullptr; QQuickKeyEvent theKeyEvent; }; @@ -797,8 +806,8 @@ class QQuickKeysAttached : public QObject, public QQuickItemKeyFilter Q_PROPERTY(Priority priority READ priority WRITE setPriority NOTIFY priorityChanged) public: - QQuickKeysAttached(QObject *parent=0); - ~QQuickKeysAttached(); + QQuickKeysAttached(QObject *parent=nullptr); + ~QQuickKeysAttached() override; bool enabled() const { Q_D(const QQuickKeysAttached); return d->enabled; } void setEnabled(bool enabled) { @@ -886,7 +895,7 @@ private: Qt::MouseButtons QQuickItemPrivate::acceptedMouseButtons() const { return ((extra.flag() ? Qt::LeftButton : Qt::MouseButton(0)) | - (extra.isAllocated() ? extra->acceptedMouseButtons : Qt::MouseButtons(0))); + (extra.isAllocated() ? extra->acceptedMouseButtons : Qt::MouseButtons(nullptr))); } QSGContext *QQuickItemPrivate::sceneGraphContext() const @@ -908,7 +917,7 @@ void QQuickItemPrivate::markSortedChildrenDirty(QQuickItem *child) if (child->z() != 0. || sortedChildItems != &childItems) { if (sortedChildItems != &childItems) delete sortedChildItems; - sortedChildItems = 0; + sortedChildItems = nullptr; } } diff --git a/src/quick/items/qquickitemanimation.cpp b/src/quick/items/qquickitemanimation.cpp index 4b5c81b4d4..e913e5ba05 100644 --- a/src/quick/items/qquickitemanimation.cpp +++ b/src/quick/items/qquickitemanimation.cpp @@ -371,7 +371,7 @@ QAbstractAnimationJob* QQuickParentAnimation::transition(QQuickStateActions &act if (data->actions.count()) { QSequentialAnimationGroupJob *topLevelGroup = new QSequentialAnimationGroupJob; - QActionAnimation *viaAction = d->via ? new QActionAnimation : 0; + QActionAnimation *viaAction = d->via ? new QActionAnimation : nullptr; QActionAnimation *targetAction = new QActionAnimation; //we'll assume the common case by far is to have children, and always create ag QParallelAnimationGroupJob *ag = new QParallelAnimationGroupJob; @@ -409,7 +409,7 @@ QAbstractAnimationJob* QQuickParentAnimation::transition(QQuickStateActions &act delete data; delete viaData; } - return 0; + return nullptr; } /*! @@ -922,12 +922,12 @@ QAbstractAnimationJob* QQuickPathAnimation::transition(QQuickStateActions &actio pa->setEasingCurve(d->easingCurve); return initInstance(pa); } else { - pa->setFromSourcedValue(0); - pa->setAnimValue(0); + pa->setFromSourcedValue(nullptr); + pa->setAnimValue(nullptr); delete pa; delete data; } - return 0; + return nullptr; } void QQuickPathAnimationUpdater::setValue(qreal v) @@ -955,7 +955,7 @@ void QQuickPathAnimationUpdater::setValue(qreal v) qreal angle; bool fixed = orientation == QQuickPathAnimation::Fixed; - QPointF currentPos = !painterPath.isEmpty() ? path->sequentialPointAt(painterPath, pathLength, attributePoints, prevBez, v, fixed ? 0 : &angle) : path->sequentialPointAt(v, fixed ? 0 : &angle); + QPointF currentPos = !painterPath.isEmpty() ? path->sequentialPointAt(painterPath, pathLength, attributePoints, prevBez, v, fixed ? nullptr : &angle) : path->sequentialPointAt(v, fixed ? nullptr : &angle); //adjust position according to anchor point if (!anchorPoint.isNull()) { diff --git a/src/quick/items/qquickitemanimation_p.h b/src/quick/items/qquickitemanimation_p.h index 3b3fad9cc4..b803455f12 100644 --- a/src/quick/items/qquickitemanimation_p.h +++ b/src/quick/items/qquickitemanimation_p.h @@ -68,7 +68,7 @@ class Q_AUTOTEST_EXPORT QQuickParentAnimation : public QQuickAnimationGroup Q_PROPERTY(QQuickItem *via READ via WRITE setVia NOTIFY viaChanged) public: - QQuickParentAnimation(QObject *parent=0); + QQuickParentAnimation(QObject *parent=nullptr); virtual ~QQuickParentAnimation(); QQuickItem *target() const; @@ -89,7 +89,7 @@ protected: QAbstractAnimationJob* transition(QQuickStateActions &actions, QQmlProperties &modified, TransitionDirection direction, - QObject *defaultTarget = 0) override; + QObject *defaultTarget = nullptr) override; }; class QQuickAnchorAnimationPrivate; @@ -102,7 +102,7 @@ class Q_AUTOTEST_EXPORT QQuickAnchorAnimation : public QQuickAbstractAnimation Q_PROPERTY(QEasingCurve easing READ easing WRITE setEasing NOTIFY easingChanged) public: - QQuickAnchorAnimation(QObject *parent=0); + QQuickAnchorAnimation(QObject *parent=nullptr); virtual ~QQuickAnchorAnimation(); QQmlListProperty<QQuickItem> targets(); @@ -121,7 +121,7 @@ protected: QAbstractAnimationJob* transition(QQuickStateActions &actions, QQmlProperties &modified, TransitionDirection direction, - QObject *defaultTarget = 0) override; + QObject *defaultTarget = nullptr) override; }; #if QT_CONFIG(quick_path) @@ -145,7 +145,7 @@ class Q_AUTOTEST_EXPORT QQuickPathAnimation : public QQuickAbstractAnimation Q_PROPERTY(qreal endRotation READ endRotation WRITE setEndRotation NOTIFY endRotationChanged) public: - QQuickPathAnimation(QObject *parent=0); + QQuickPathAnimation(QObject *parent=nullptr); virtual ~QQuickPathAnimation(); enum Orientation { @@ -188,7 +188,7 @@ protected: QAbstractAnimationJob* transition(QQuickStateActions &actions, QQmlProperties &modified, TransitionDirection direction, - QObject *defaultTarget = 0) override; + QObject *defaultTarget = nullptr) override; Q_SIGNALS: void durationChanged(int); void easingChanged(const QEasingCurve &); diff --git a/src/quick/items/qquickitemanimation_p_p.h b/src/quick/items/qquickitemanimation_p_p.h index 2d075dfab3..83b9899197 100644 --- a/src/quick/items/qquickitemanimation_p_p.h +++ b/src/quick/items/qquickitemanimation_p_p.h @@ -65,7 +65,7 @@ class QQuickParentAnimationPrivate : public QQuickAnimationGroupPrivate Q_DECLARE_PUBLIC(QQuickParentAnimation) public: QQuickParentAnimationPrivate() - : QQuickAnimationGroupPrivate(), target(0), newParent(0), via(0) {} + : QQuickAnimationGroupPrivate(), target(nullptr), newParent(nullptr), via(nullptr) {} QQuickItem *target; QQuickItem *newParent; @@ -91,7 +91,7 @@ public: class QQuickPathAnimationUpdater : public QQuickBulkValueUpdater { public: - QQuickPathAnimationUpdater() : path(0), pathLength(0), target(0), reverse(false), + QQuickPathAnimationUpdater() : path(nullptr), pathLength(0), target(nullptr), reverse(false), fromSourced(false), fromDefined(false), toDefined(false), toX(0), toY(0), currentV(0), orientation(QQuickPathAnimation::Fixed), entryInterval(0), exitInterval(0) {} @@ -128,10 +128,10 @@ class QQuickPathAnimationPrivate; class QQuickPathAnimationAnimator : public QQuickBulkValueAnimator { public: - QQuickPathAnimationAnimator(QQuickPathAnimationPrivate * = 0); + QQuickPathAnimationAnimator(QQuickPathAnimationPrivate * = nullptr); ~QQuickPathAnimationAnimator(); - void clearTemplate() { animationTemplate = 0; } + void clearTemplate() { animationTemplate = nullptr; } QQuickPathAnimationUpdater *pathUpdater() const { return static_cast<QQuickPathAnimationUpdater*>(getAnimValue()); } private: @@ -142,7 +142,7 @@ class QQuickPathAnimationPrivate : public QQuickAbstractAnimationPrivate { Q_DECLARE_PUBLIC(QQuickPathAnimation) public: - QQuickPathAnimationPrivate() : path(0), target(0), + QQuickPathAnimationPrivate() : path(nullptr), target(nullptr), orientation(QQuickPathAnimation::Fixed), entryDuration(0), exitDuration(0), duration(250) {} QQuickPath *path; diff --git a/src/quick/items/qquickitemchangelistener_p.h b/src/quick/items/qquickitemchangelistener_p.h index cb0af75c4c..31d06c9983 100644 --- a/src/quick/items/qquickitemchangelistener_p.h +++ b/src/quick/items/qquickitemchangelistener_p.h @@ -135,7 +135,7 @@ public: virtual void itemImplicitWidthChanged(QQuickItem *) {} virtual void itemImplicitHeightChanged(QQuickItem *) {} - virtual QQuickAnchorsPrivate *anchorPrivate() { return 0; } + virtual QQuickAnchorsPrivate *anchorPrivate() { return nullptr; } }; QT_END_NAMESPACE diff --git a/src/quick/items/qquickitemgrabresult.cpp b/src/quick/items/qquickitemgrabresult.cpp index c3f8d4f024..003fde8c9e 100644 --- a/src/quick/items/qquickitemgrabresult.cpp +++ b/src/quick/items/qquickitemgrabresult.cpp @@ -62,9 +62,9 @@ class QQuickItemGrabResultPrivate : public QObjectPrivate { public: QQuickItemGrabResultPrivate() - : cacheEntry(0) - , qmlEngine(0) - , texture(0) + : cacheEntry(nullptr) + , qmlEngine(nullptr) + , texture(nullptr) { } @@ -266,7 +266,7 @@ void QQuickItemGrabResult::render() d->image = d->texture->toImage(); delete d->texture; - d->texture = 0; + d->texture = nullptr; disconnect(d->window.data(), &QQuickWindow::beforeSynchronizing, this, &QQuickItemGrabResult::setup); disconnect(d->window.data(), &QQuickWindow::afterRendering, this, &QQuickItemGrabResult::render); @@ -281,17 +281,17 @@ QQuickItemGrabResult *QQuickItemGrabResultPrivate::create(QQuickItem *item, cons if (size.width() < 1 || size.height() < 1) { qmlWarning(item) << "grabToImage: item has invalid dimensions"; - return 0; + return nullptr; } if (!item->window()) { qmlWarning(item) << "grabToImage: item is not attached to a window"; - return 0; + return nullptr; } if (!item->window()->isVisible()) { qmlWarning(item) << "grabToImage: item's window is not visible"; - return 0; + return nullptr; } QQuickItemGrabResult *result = new QQuickItemGrabResult(); diff --git a/src/quick/items/qquickitemsmodule.cpp b/src/quick/items/qquickitemsmodule.cpp index 62312845b2..51a91e1f7a 100644 --- a/src/quick/items/qquickitemsmodule.cpp +++ b/src/quick/items/qquickitemsmodule.cpp @@ -74,7 +74,9 @@ #if QT_CONFIG(quick_positioners) #include "qquickpositioners_p.h" #endif +#if QT_CONFIG(quick_repeater) #include "qquickrepeater_p.h" +#endif #include "qquickloader_p.h" #if QT_CONFIG(quick_animatedimage) #include "qquickanimatedimage_p.h" @@ -111,6 +113,10 @@ #include <private/qqmlmetatype_p.h> #include <QtQuick/private/qquickaccessibleattached_p.h> +QT_BEGIN_NAMESPACE +Q_DECLARE_LOGGING_CATEGORY(lcTransient) +QT_END_NAMESPACE + static QQmlPrivate::AutoParentResult qquickitem_autoParent(QObject *obj, QObject *parent) { // When setting a parent (especially during dynamic object creation) in QML, @@ -125,6 +131,7 @@ static QQmlPrivate::AutoParentResult qquickitem_autoParent(QObject *obj, QObject QQuickWindow *win = qmlobject_cast<QQuickWindow *>(obj); if (win) { // A Window inside an Item should be transient for that item's window + qCDebug(lcTransient) << win << "is transient for" << parentItem->window(); win->setTransientParent(parentItem->window()); return QQmlPrivate::Parented; } @@ -134,6 +141,7 @@ static QQmlPrivate::AutoParentResult qquickitem_autoParent(QObject *obj, QObject QQuickWindow *win = qmlobject_cast<QQuickWindow *>(obj); if (win) { // A Window inside a Window should be transient for it + qCDebug(lcTransient) << win << "is transient for" << parentWindow; win->setTransientParent(parentWindow); return QQmlPrivate::Parented; } else { @@ -207,7 +215,9 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor) qmlRegisterType<QQuickPathView>(uri,major,minor,"PathView"); #endif qmlRegisterType<QQuickRectangle>(uri,major,minor,"Rectangle"); +#if QT_CONFIG(quick_repeater) qmlRegisterType<QQuickRepeater>(uri,major,minor,"Repeater"); +#endif qmlRegisterType<QQuickTranslate>(uri,major,minor,"Translate"); qmlRegisterType<QQuickRotation>(uri,major,minor,"Rotation"); qmlRegisterType<QQuickScale>(uri,major,minor,"Scale"); @@ -290,7 +300,8 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor) qmlRegisterType<QQuickMultiPointTouchArea>("QtQuick", 2, 0, "MultiPointTouchArea"); qmlRegisterType<QQuickTouchPoint>("QtQuick", 2, 0, "TouchPoint"); - qmlRegisterType<QQuickGrabGestureEvent>(); + qmlRegisterUncreatableType<QQuickGrabGestureEvent>(uri,major,minor, "GestureEvent", + QQuickMouseEvent::tr("GestureEvent is only available in the context of handling the gestureStarted signal from MultiPointTouchArea")); #if QT_CONFIG(accessibility) qmlRegisterUncreatableType<QQuickAccessibleAttached>("QtQuick", 2, 0, "Accessible",QQuickAccessibleAttached::tr("Accessible is only available via attached properties")); @@ -406,6 +417,11 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor) #if QT_CONFIG(quick_path) qmlRegisterType<QQuickPathAngleArc>(uri, 2, 11, "PathAngleArc"); #endif + +#if QT_CONFIG(quick_animatedimage) + qmlRegisterType<QQuickAnimatedImage, 11>(uri, 2, 11,"AnimatedImage"); +#endif + qmlRegisterType<QQuickItem, 11>(uri, 2, 11,"Item"); } static void initResources() diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp index 1d0d042839..f2e055e874 100644 --- a/src/quick/items/qquickitemview.cpp +++ b/src/quick/items/qquickitemview.cpp @@ -54,7 +54,7 @@ Q_LOGGING_CATEGORY(lcItemViewDelegateLifecycle, "qt.quick.itemview.lifecycle") FxViewItem::FxViewItem(QQuickItem *i, QQuickItemView *v, bool own, QQuickItemViewAttached *attached) : item(i) , view(v) - , transitionableItem(0) + , transitionableItem(nullptr) , attached(attached) , ownItem(own) , releaseAfterTransition(false) @@ -69,9 +69,9 @@ FxViewItem::~FxViewItem() delete transitionableItem; if (ownItem && item) { trackGeometry(false); - item->setParentItem(0); + item->setParentItem(nullptr); item->deleteLater(); - item = 0; + item = nullptr; } } @@ -275,7 +275,7 @@ QQuickItemView::~QQuickItemView() QQuickItem *QQuickItemView::currentItem() const { Q_D(const QQuickItemView); - return d->currentItem ? d->currentItem->item : 0; + return d->currentItem ? d->currentItem->item : nullptr; } QVariant QQuickItemView::model() const @@ -304,12 +304,12 @@ void QQuickItemView::setModel(const QVariant &m) QQmlInstanceModel *oldModel = d->model; d->clear(); - d->model = 0; + d->model = nullptr; d->setPosition(d->contentStartOffset()); d->modelVariant = model; QObject *object = qvariant_cast<QObject*>(model); - QQmlInstanceModel *vim = 0; + QQmlInstanceModel *vim = nullptr; if (object && (vim = qobject_cast<QQmlInstanceModel *>(object))) { if (d->ownModel) { delete oldModel; @@ -362,7 +362,7 @@ QQmlComponent *QQuickItemView::delegate() const return dataModel->delegate(); } - return 0; + return nullptr; } void QQuickItemView::setDelegate(QQmlComponent *delegate) @@ -382,7 +382,7 @@ void QQuickItemView::setDelegate(QQmlComponent *delegate) if (isComponentComplete()) { d->releaseVisibleItems(); d->releaseItem(d->currentItem); - d->currentItem = 0; + d->currentItem = nullptr; d->updateSectionCriteria(); d->refill(); d->moveReason = QQuickItemViewPrivate::SetIndex; @@ -586,7 +586,7 @@ QQmlComponent *QQuickItemView::header() const QQuickItem *QQuickItemView::headerItem() const { Q_D(const QQuickItemView); - return d->header ? d->header->item : 0; + return d->header ? d->header->item : nullptr; } void QQuickItemView::setHeader(QQmlComponent *headerComponent) @@ -595,7 +595,7 @@ void QQuickItemView::setHeader(QQmlComponent *headerComponent) if (d->headerComponent != headerComponent) { d->applyPendingChanges(); delete d->header; - d->header = 0; + d->header = nullptr; d->headerComponent = headerComponent; d->markExtentsDirty(); @@ -621,7 +621,7 @@ QQmlComponent *QQuickItemView::footer() const QQuickItem *QQuickItemView::footerItem() const { Q_D(const QQuickItemView); - return d->footer ? d->footer->item : 0; + return d->footer ? d->footer->item : nullptr; } void QQuickItemView::setFooter(QQmlComponent *footerComponent) @@ -630,7 +630,7 @@ void QQuickItemView::setFooter(QQmlComponent *footerComponent) if (d->footerComponent != footerComponent) { d->applyPendingChanges(); delete d->footer; - d->footer = 0; + d->footer = nullptr; d->footerComponent = footerComponent; if (isComponentComplete()) { @@ -666,7 +666,7 @@ void QQuickItemView::setHighlight(QQmlComponent *highlightComponent) QQuickItem *QQuickItemView::highlightItem() const { Q_D(const QQuickItemView); - return d->highlight ? d->highlight->item : 0; + return d->highlight ? d->highlight->item : nullptr; } bool QQuickItemView::highlightFollowsCurrentItem() const @@ -799,7 +799,7 @@ void QQuickItemView::setHighlightMoveDuration(int duration) QQuickTransition *QQuickItemView::populateTransition() const { Q_D(const QQuickItemView); - return d->transitioner ? d->transitioner->populateTransition : 0; + return d->transitioner ? d->transitioner->populateTransition : nullptr; } void QQuickItemView::setPopulateTransition(QQuickTransition *transition) @@ -815,7 +815,7 @@ void QQuickItemView::setPopulateTransition(QQuickTransition *transition) QQuickTransition *QQuickItemView::addTransition() const { Q_D(const QQuickItemView); - return d->transitioner ? d->transitioner->addTransition : 0; + return d->transitioner ? d->transitioner->addTransition : nullptr; } void QQuickItemView::setAddTransition(QQuickTransition *transition) @@ -831,7 +831,7 @@ void QQuickItemView::setAddTransition(QQuickTransition *transition) QQuickTransition *QQuickItemView::addDisplacedTransition() const { Q_D(const QQuickItemView); - return d->transitioner ? d->transitioner->addDisplacedTransition : 0; + return d->transitioner ? d->transitioner->addDisplacedTransition : nullptr; } void QQuickItemView::setAddDisplacedTransition(QQuickTransition *transition) @@ -847,7 +847,7 @@ void QQuickItemView::setAddDisplacedTransition(QQuickTransition *transition) QQuickTransition *QQuickItemView::moveTransition() const { Q_D(const QQuickItemView); - return d->transitioner ? d->transitioner->moveTransition : 0; + return d->transitioner ? d->transitioner->moveTransition : nullptr; } void QQuickItemView::setMoveTransition(QQuickTransition *transition) @@ -863,7 +863,7 @@ void QQuickItemView::setMoveTransition(QQuickTransition *transition) QQuickTransition *QQuickItemView::moveDisplacedTransition() const { Q_D(const QQuickItemView); - return d->transitioner ? d->transitioner->moveDisplacedTransition : 0; + return d->transitioner ? d->transitioner->moveDisplacedTransition : nullptr; } void QQuickItemView::setMoveDisplacedTransition(QQuickTransition *transition) @@ -879,7 +879,7 @@ void QQuickItemView::setMoveDisplacedTransition(QQuickTransition *transition) QQuickTransition *QQuickItemView::removeTransition() const { Q_D(const QQuickItemView); - return d->transitioner ? d->transitioner->removeTransition : 0; + return d->transitioner ? d->transitioner->removeTransition : nullptr; } void QQuickItemView::setRemoveTransition(QQuickTransition *transition) @@ -895,7 +895,7 @@ void QQuickItemView::setRemoveTransition(QQuickTransition *transition) QQuickTransition *QQuickItemView::removeDisplacedTransition() const { Q_D(const QQuickItemView); - return d->transitioner ? d->transitioner->removeDisplacedTransition : 0; + return d->transitioner ? d->transitioner->removeDisplacedTransition : nullptr; } void QQuickItemView::setRemoveDisplacedTransition(QQuickTransition *transition) @@ -911,7 +911,7 @@ void QQuickItemView::setRemoveDisplacedTransition(QQuickTransition *transition) QQuickTransition *QQuickItemView::displacedTransition() const { Q_D(const QQuickItemView); - return d->transitioner ? d->transitioner->displacedTransition : 0; + return d->transitioner ? d->transitioner->displacedTransition : nullptr; } void QQuickItemView::setDisplacedTransition(QQuickTransition *transition) @@ -926,7 +926,6 @@ void QQuickItemView::setDisplacedTransition(QQuickTransition *transition) void QQuickItemViewPrivate::positionViewAtIndex(int index, int mode) { - Q_Q(QQuickItemView); if (!isValid()) return; if (mode < QQuickItemView::Beginning || mode > QQuickItemView::SnapPosition) @@ -953,11 +952,16 @@ void QQuickItemViewPrivate::positionViewAtIndex(int index, int mode) item = visibleItem(idx); } if (item) { + const bool stickyHeader = hasStickyHeader(); + const bool stickyFooter = hasStickyFooter(); + const qreal stickyHeaderSize = stickyHeader ? headerSize() : 0; + const qreal stickyFooterSize = stickyFooter ? footerSize() : 0; + const qreal itemPos = item->position(); switch (mode) { case QQuickItemView::Beginning: pos = itemPos; - if (header && (index < 0 || hasStickyHeader())) + if (header && (index < 0 || stickyHeader)) pos -= headerSize(); break; case QQuickItemView::Center: @@ -965,30 +969,29 @@ void QQuickItemViewPrivate::positionViewAtIndex(int index, int mode) break; case QQuickItemView::End: pos = itemPos - viewSize + item->size(); - if (footer && (index >= modelCount || hasStickyFooter())) + if (footer && (index >= modelCount || stickyFooter)) pos += footerSize(); break; case QQuickItemView::Visible: - if (itemPos > pos + viewSize) - pos = itemPos - viewSize + item->size(); - else if (item->endPosition() <= pos) - pos = itemPos; + if (itemPos > pos + viewSize - stickyFooterSize) + pos = item->endPosition() - viewSize + stickyFooterSize; + else if (item->endPosition() <= pos - stickyHeaderSize) + pos = itemPos - stickyHeaderSize; break; case QQuickItemView::Contain: - if (item->endPosition() >= pos + viewSize) - pos = itemPos - viewSize + item->size(); - if (itemPos < pos) - pos = itemPos; + if (item->endPosition() >= pos + viewSize + stickyFooterSize) + pos = itemPos - viewSize + item->size() + stickyFooterSize; + if (itemPos - stickyHeaderSize < pos) + pos = itemPos - stickyHeaderSize; break; case QQuickItemView::SnapPosition: - pos = itemPos - highlightRangeStart; + pos = itemPos - highlightRangeStart - stickyHeaderSize; break; } pos = qMin(pos, maxExtent); qreal minExtent = calculatedMinExtent(); pos = qMax(pos, minExtent); moveReason = QQuickItemViewPrivate::Other; - q->cancelFlick(); setPosition(pos); if (highlight) { @@ -1231,7 +1234,7 @@ void QQuickItemViewPrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometry // start new transitions bool prevInLayout = inLayout; if (!inLayout) { - FxViewItem *actualItem = transitioner ? visibleItem(currentIndex) : 0; + FxViewItem *actualItem = transitioner ? visibleItem(currentIndex) : nullptr; if (actualItem && actualItem->transitionRunning()) inLayout = true; } @@ -1246,16 +1249,26 @@ void QQuickItemViewPrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometry void QQuickItemView::destroyRemoved() { Q_D(QQuickItemView); + + bool hasRemoveTransition = false; + bool hasRemoveTransitionAsTarget = false; + if (d->transitioner) { + hasRemoveTransition = d->transitioner->canTransition(QQuickItemViewTransitioner::RemoveTransition, false); + hasRemoveTransitionAsTarget = d->transitioner->canTransition(QQuickItemViewTransitioner::RemoveTransition, true); + } + for (QList<FxViewItem*>::Iterator it = d->visibleItems.begin(); it != d->visibleItems.end();) { FxViewItem *item = *it; if (item->index == -1 && (!item->attached || item->attached->delayRemove() == false)) { - if (d->transitioner && d->transitioner->canTransition(QQuickItemViewTransitioner::RemoveTransition, true)) { + if (hasRemoveTransitionAsTarget) { // don't remove from visibleItems until next layout() d->runDelayedRemoveTransition = true; QObject::disconnect(item->attached, SIGNAL(delayRemoveChanged()), this, SLOT(destroyRemoved())); ++it; } else { + if (hasRemoveTransition) + d->runDelayedRemoveTransition = true; d->releaseItem(item); it = d->visibleItems.erase(it); } @@ -1384,7 +1397,6 @@ void QQuickItemView::trackedPositionChanged() pos = qMax(trackedPos, toItemPos); } if (viewPos != pos) { - cancelFlick(); d->calcVelocity = true; d->setPosition(pos); d->calcVelocity = false; @@ -1546,14 +1558,14 @@ QQuickItemViewPrivate::QQuickItemViewPrivate() , layoutDirection(Qt::LeftToRight), verticalLayoutDirection(QQuickItemView::TopToBottom) , moveReason(Other) , visibleIndex(0) - , currentIndex(-1), currentItem(0) - , trackedItem(0), requestedIndex(-1) - , highlightComponent(0), highlight(0) + , currentIndex(-1), currentItem(nullptr) + , trackedItem(nullptr), requestedIndex(-1) + , highlightComponent(nullptr), highlight(nullptr) , highlightRange(QQuickItemView::NoHighlightRange) , highlightRangeStart(0), highlightRangeEnd(0) , highlightMoveDuration(150) - , headerComponent(0), header(0), footerComponent(0), footer(0) - , transitioner(0) + , headerComponent(nullptr), header(nullptr), footerComponent(nullptr), footer(nullptr) + , transitioner(nullptr) , minExtent(0), maxExtent(0) , ownModel(false), wrap(false) , keyNavigationEnabled(true) @@ -1571,7 +1583,7 @@ QQuickItemViewPrivate::QQuickItemViewPrivate() QQuickItemViewPrivate::~QQuickItemViewPrivate() { if (transitioner) - transitioner->setChangeListener(0); + transitioner->setChangeListener(nullptr); delete transitioner; } @@ -1637,7 +1649,7 @@ FxViewItem *QQuickItemViewPrivate::visibleItem(int modelIndex) const { return item; } } - return 0; + return nullptr; } // should rename to firstItemInView() to avoid confusion with other "*visible*" methods @@ -1697,7 +1709,7 @@ void QQuickItemViewPrivate::updateCurrent(int modelIndex) if (currentItem->attached) currentItem->attached->setIsCurrentItem(false); releaseItem(currentItem); - currentItem = 0; + currentItem = nullptr; currentIndex = modelIndex; emit q->currentIndexChanged(); emit q->currentItemChanged(); @@ -1717,7 +1729,7 @@ void QQuickItemViewPrivate::updateCurrent(int modelIndex) FxViewItem *oldCurrentItem = currentItem; int oldCurrentIndex = currentIndex; currentIndex = modelIndex; - currentItem = createItem(modelIndex, false); + currentItem = createItem(modelIndex, QQmlIncubator::AsynchronousIfNested); if (oldCurrentItem && oldCurrentItem->attached && (!currentItem || oldCurrentItem->item != currentItem->item)) oldCurrentItem->attached->setIsCurrentItem(false); if (currentItem) { @@ -1738,7 +1750,9 @@ void QQuickItemViewPrivate::updateCurrent(int modelIndex) void QQuickItemViewPrivate::clear() { + Q_Q(QQuickItemView); currentChanges.reset(); + bufferedChanges.reset(); timeline.clear(); releaseVisibleItems(); @@ -1750,10 +1764,13 @@ void QQuickItemViewPrivate::clear() } releasePendingTransition.clear(); + auto oldCurrentItem = currentItem; releaseItem(currentItem); - currentItem = 0; + currentItem = nullptr; + if (oldCurrentItem) + emit q->currentItemChanged(); createHighlight(); - trackedItem = 0; + trackedItem = nullptr; if (requestedIndex >= 0) { if (model) @@ -1796,56 +1813,61 @@ void QQuickItemViewPrivate::refill(qreal from, qreal to) if (!isValid() || !q->isComponentComplete()) return; - bufferPause.stop(); - currentChanges.reset(); + do { + bufferPause.stop(); + if (currentChanges.hasPendingChanges() || bufferedChanges.hasPendingChanges()) { + currentChanges.reset(); + bufferedChanges.reset(); + releaseVisibleItems(); + } - int prevCount = itemCount; - itemCount = model->count(); - qreal bufferFrom = from - buffer; - qreal bufferTo = to + buffer; - qreal fillFrom = from; - qreal fillTo = to; - - bool added = addVisibleItems(fillFrom, fillTo, bufferFrom, bufferTo, false); - bool removed = removeNonVisibleItems(bufferFrom, bufferTo); - - if (requestedIndex == -1 && buffer && bufferMode != NoBuffer) { - if (added) { - // We've already created a new delegate this frame. - // Just schedule a buffer refill. - bufferPause.start(); - } else { - if (bufferMode & BufferAfter) - fillTo = bufferTo; - if (bufferMode & BufferBefore) - fillFrom = bufferFrom; - added |= addVisibleItems(fillFrom, fillTo, bufferFrom, bufferTo, true); + int prevCount = itemCount; + itemCount = model->count(); + qreal bufferFrom = from - buffer; + qreal bufferTo = to + buffer; + qreal fillFrom = from; + qreal fillTo = to; + + bool added = addVisibleItems(fillFrom, fillTo, bufferFrom, bufferTo, false); + bool removed = removeNonVisibleItems(bufferFrom, bufferTo); + + if (requestedIndex == -1 && buffer && bufferMode != NoBuffer) { + if (added) { + // We've already created a new delegate this frame. + // Just schedule a buffer refill. + bufferPause.start(); + } else { + if (bufferMode & BufferAfter) + fillTo = bufferTo; + if (bufferMode & BufferBefore) + fillFrom = bufferFrom; + added |= addVisibleItems(fillFrom, fillTo, bufferFrom, bufferTo, true); + } } - } - if (added || removed) { - markExtentsDirty(); - updateBeginningEnd(); - visibleItemsChanged(); - updateHeader(); - updateFooter(); - updateViewport(); - } + if (added || removed) { + markExtentsDirty(); + updateBeginningEnd(); + visibleItemsChanged(); + updateHeader(); + updateFooter(); + updateViewport(); + } - if (prevCount != itemCount) - emit q->countChanged(); + if (prevCount != itemCount) + emit q->countChanged(); + } while (currentChanges.hasPendingChanges() || bufferedChanges.hasPendingChanges()); } void QQuickItemViewPrivate::regenerate(bool orientationChanged) { Q_Q(QQuickItemView); if (q->isComponentComplete()) { - currentChanges.reset(); if (orientationChanged) { delete header; - header = 0; + header = nullptr; delete footer; - footer = 0; + footer = nullptr; } clear(); updateHeader(); @@ -1876,6 +1898,9 @@ void QQuickItemViewPrivate::layout() inLayout = true; + // viewBounds contains bounds before any add/remove/move operation to the view + QRectF viewBounds(q->contentX(), q->contentY(), q->width(), q->height()); + if (!isValid() && !visibleItems.count()) { clear(); setPosition(contentStartOffset()); @@ -1934,14 +1959,14 @@ void QQuickItemViewPrivate::layout() if (transitioner) { // items added in the last refill() may need to be transitioned in - e.g. a remove // causes items to slide up into view - if (transitioner->canTransition(QQuickItemViewTransitioner::MoveTransition, false) - || transitioner->canTransition(QQuickItemViewTransitioner::RemoveTransition, false)) { + if (lastIndexInView != -1 && + (transitioner->canTransition(QQuickItemViewTransitioner::MoveTransition, false) + || transitioner->canTransition(QQuickItemViewTransitioner::RemoveTransition, false))) { translateAndTransitionItemsAfter(lastIndexInView, insertionPosChanges, removalPosChanges); } prepareVisibleItemTransitions(); - QRectF viewBounds(q->contentX(), q->contentY(), q->width(), q->height()); for (QList<FxViewItem*>::Iterator it = releasePendingTransition.begin(); it != releasePendingTransition.end(); ) { FxViewItem *item = *it; @@ -1978,7 +2003,6 @@ bool QQuickItemViewPrivate::applyModelChanges(ChangeResult *totalInsertionResult } updateUnrequestedIndexes(); - moveReason = QQuickItemViewPrivate::Other; FxViewItem *prevVisibleItemsFirst = visibleItems.count() ? *visibleItems.constBegin() : 0; int prevItemCount = itemCount; @@ -2100,8 +2124,11 @@ bool QQuickItemViewPrivate::applyModelChanges(ChangeResult *totalInsertionResult if (currentChanges.currentRemoved && currentItem) { if (currentItem->item && currentItem->attached) currentItem->attached->setIsCurrentItem(false); + auto oldCurrentItem = currentItem; releaseItem(currentItem); - currentItem = 0; + currentItem = nullptr; + if (oldCurrentItem) + emit q->currentItemChanged(); } if (!currentIndexCleared) updateCurrent(currentChanges.newCurrentIndex); @@ -2313,12 +2340,12 @@ void QQuickItemViewPrivate::viewItemTransitionFinished(QQuickItemViewTransitiona When the item becomes available, refill() will be called and the item will be returned on the next call to createItem(). */ -FxViewItem *QQuickItemViewPrivate::createItem(int modelIndex, bool asynchronous) +FxViewItem *QQuickItemViewPrivate::createItem(int modelIndex, QQmlIncubator::IncubationMode incubationMode) { Q_Q(QQuickItemView); - if (requestedIndex == modelIndex && asynchronous) - return 0; + if (requestedIndex == modelIndex && incubationMode == QQmlIncubator::Asynchronous) + return nullptr; for (int i=0; i<releasePendingTransition.count(); i++) { if (releasePendingTransition.at(i)->index == modelIndex @@ -2328,14 +2355,20 @@ FxViewItem *QQuickItemViewPrivate::createItem(int modelIndex, bool asynchronous) } } - if (asynchronous) - requestedIndex = modelIndex; inRequest = true; - QObject* object = model->object(modelIndex, asynchronous); + QObject* object = model->object(modelIndex, incubationMode); QQuickItem *item = qmlobject_cast<QQuickItem*>(object); + if (!item) { - if (object) { + if (!object) { + if (requestedIndex == -1 && model->incubationStatus(modelIndex) == QQmlIncubator::Loading) { + // The reason we didn't receive an item is because it's incubating async. We keep track + // of this by assigning the index we're waiting for to 'requestedIndex'. This will e.g. let + // the view avoid unnecessary layout calls until the item has been loaded. + requestedIndex = modelIndex; + } + } else { model->release(object); if (!delegateValidated) { delegateValidated = true; @@ -2344,7 +2377,7 @@ FxViewItem *QQuickItemViewPrivate::createItem(int modelIndex, bool asynchronous) } } inRequest = false; - return 0; + return nullptr; } else { item->setParentItem(q->contentItem()); if (requestedIndex == modelIndex) @@ -2397,7 +2430,7 @@ void QQuickItemView::destroyingItem(QObject *object) Q_D(QQuickItemView); QQuickItem* item = qmlobject_cast<QQuickItem*>(object); if (item) { - item->setParentItem(0); + item->setParentItem(nullptr); d->unrequestedItems.remove(item); } } @@ -2408,7 +2441,7 @@ bool QQuickItemViewPrivate::releaseItem(FxViewItem *item) if (!item || !model) return true; if (trackedItem == item) - trackedItem = 0; + trackedItem = nullptr; item->trackGeometry(false); QQmlInstanceModel::ReleaseFlags flags = model->release(item->item); @@ -2418,7 +2451,7 @@ bool QQuickItemViewPrivate::releaseItem(FxViewItem *item) QQuickItemPrivate::get(item->item)->setCulled(true); unrequestedItems.insert(item->item, model->indexOf(item->item, q)); } else if (flags & QQmlInstanceModel::Destroyed) { - item->item->setParentItem(0); + item->item->setParentItem(nullptr); } } delete item; @@ -2434,7 +2467,7 @@ QQuickItem *QQuickItemViewPrivate::createComponentItem(QQmlComponent *component, { Q_Q(const QQuickItemView); - QQuickItem *item = 0; + QQuickItem *item = nullptr; if (component) { QQmlContext *creationContext = component->creationContext(); QQmlContext *context = new QQmlContext( diff --git a/src/quick/items/qquickitemview_p.h b/src/quick/items/qquickitemview_p.h index b38bc6174f..483fc1a09f 100644 --- a/src/quick/items/qquickitemview_p.h +++ b/src/quick/items/qquickitemview_p.h @@ -128,7 +128,7 @@ public: }; Q_ENUM(VerticalLayoutDirection) - QQuickItemView(QQuickFlickablePrivate &dd, QQuickItem *parent = 0); + QQuickItemView(QQuickFlickablePrivate &dd, QQuickItem *parent = nullptr); ~QQuickItemView(); QVariant model() const; diff --git a/src/quick/items/qquickitemview_p_p.h b/src/quick/items/qquickitemview_p_p.h index 374b8388ba..e250cf0ccb 100644 --- a/src/quick/items/qquickitemview_p_p.h +++ b/src/quick/items/qquickitemview_p_p.h @@ -206,7 +206,7 @@ public: void refill(qreal from, qreal to); void mirrorChange() override; - FxViewItem *createItem(int modelIndex, bool asynchronous = false); + FxViewItem *createItem(int modelIndex,QQmlIncubator::IncubationMode incubationMode = QQmlIncubator::AsynchronousIfNested); virtual bool releaseItem(FxViewItem *item); QQuickItem *createHighlightItem() const; diff --git a/src/quick/items/qquickitemviewtransition.cpp b/src/quick/items/qquickitemviewtransition.cpp index 745e5b275f..5cd28d0acb 100644 --- a/src/quick/items/qquickitemviewtransition.cpp +++ b/src/quick/items/qquickitemviewtransition.cpp @@ -69,11 +69,11 @@ protected: QQuickItemViewTransitionJob::QQuickItemViewTransitionJob() - : m_transitioner(0) - , m_item(0) + : m_transitioner(nullptr) + , m_item(nullptr) , m_type(QQuickItemViewTransitioner::NoTransition) , m_isTarget(false) - , m_wasDeleted(0) + , m_wasDeleted(nullptr) { } @@ -143,12 +143,12 @@ void QQuickItemViewTransitionJob::finished() m_transitioner->finishedTransition(this, m_item); if (deleted) return; - m_wasDeleted = 0; + m_wasDeleted = nullptr; - m_transitioner = 0; + m_transitioner = nullptr; } - m_item = 0; + m_item = nullptr; m_toPos.setX(0); m_toPos.setY(0); m_type = QQuickItemViewTransitioner::NoTransition; @@ -157,12 +157,12 @@ void QQuickItemViewTransitionJob::finished() QQuickItemViewTransitioner::QQuickItemViewTransitioner() - : populateTransition(0) - , addTransition(0), addDisplacedTransition(0) - , moveTransition(0), moveDisplacedTransition(0) - , removeTransition(0), removeDisplacedTransition(0) - , displacedTransition(0) - , changeListener(0) + : populateTransition(nullptr) + , addTransition(nullptr), addDisplacedTransition(nullptr) + , moveTransition(nullptr), moveDisplacedTransition(nullptr) + , removeTransition(nullptr), removeDisplacedTransition(nullptr) + , displacedTransition(nullptr) + , changeListener(nullptr) , usePopulateTransition(false) { } @@ -172,7 +172,7 @@ QQuickItemViewTransitioner::~QQuickItemViewTransitioner() typedef QSet<QQuickItemViewTransitionJob *>::iterator JobIt; for (JobIt it = runningJobs.begin(), end = runningJobs.end(); it != end; ++it) - (*it)->m_transitioner = 0; + (*it)->m_transitioner = nullptr; } bool QQuickItemViewTransitioner::canTransition(QQuickItemViewTransitioner::TransitionType type, bool asTarget) const @@ -249,12 +249,12 @@ void QQuickItemViewTransitioner::resetTargetLists() QQuickTransition *QQuickItemViewTransitioner::transitionObject(QQuickItemViewTransitioner::TransitionType type, bool asTarget) const { if (type == QQuickItemViewTransitioner::NoTransition) - return 0; + return nullptr; if (type == PopulateTransition) asTarget = true; // no separate displaced transition - QQuickTransition *trans = 0; + QQuickTransition *trans = nullptr; switch (type) { case NoTransition: break; @@ -276,7 +276,7 @@ QQuickTransition *QQuickItemViewTransitioner::transitionObject(QQuickItemViewTra trans = displacedTransition; if (trans && trans->enabled()) return trans; - return 0; + return nullptr; } const QList<int> &QQuickItemViewTransitioner::targetIndexes(QQuickItemViewTransitioner::TransitionType type) const @@ -328,7 +328,7 @@ void QQuickItemViewTransitioner::finishedTransition(QQuickItemViewTransitionJob QQuickItemViewTransitionableItem::QQuickItemViewTransitionableItem(QQuickItem *i) : item(i) - , transition(0) + , transition(nullptr) , nextTransitionType(QQuickItemViewTransitioner::NoTransition) , isTransitionTarget(false) , nextTransitionToSet(false) @@ -563,7 +563,7 @@ void QQuickItemViewTransitionableItem::stopTransition() QQuickViewTransitionAttached::QQuickViewTransitionAttached(QObject *parent) - : QObject(parent), m_item(0), m_index(-1) + : QObject(parent), m_item(nullptr), m_index(-1) { } /*! diff --git a/src/quick/items/qquickitemviewtransition_p.h b/src/quick/items/qquickitemviewtransition_p.h index 3d2f5361b1..29a62f7f10 100644 --- a/src/quick/items/qquickitemviewtransition_p.h +++ b/src/quick/items/qquickitemviewtransition_p.h @@ -58,6 +58,8 @@ QT_REQUIRE_CONFIG(quick_viewtransitions); #include <QtCore/qobject.h> #include <QtCore/qpoint.h> #include <QtQml/qqml.h> +#include <private/qqmlguard_p.h> +#include <private/qquicktransition_p.h> QT_BEGIN_NAMESPACE @@ -115,14 +117,14 @@ public: QList<QObject *> moveTransitionTargets; QList<QObject *> removeTransitionTargets; - QQuickTransition *populateTransition; - QQuickTransition *addTransition; - QQuickTransition *addDisplacedTransition; - QQuickTransition *moveTransition; - QQuickTransition *moveDisplacedTransition; - QQuickTransition *removeTransition; - QQuickTransition *removeDisplacedTransition; - QQuickTransition *displacedTransition; + QQmlGuard<QQuickTransition> populateTransition; + QQmlGuard<QQuickTransition> addTransition; + QQmlGuard<QQuickTransition> addDisplacedTransition; + QQmlGuard<QQuickTransition> moveTransition; + QQmlGuard<QQuickTransition> moveDisplacedTransition; + QQmlGuard<QQuickTransition> removeTransition; + QQmlGuard<QQuickTransition> removeDisplacedTransition; + QQmlGuard<QQuickTransition> displacedTransition; private: friend class QQuickItemViewTransitionJob; diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp index a6236d9801..33becd71ec 100644 --- a/src/quick/items/qquicklistview.cpp +++ b/src/quick/items/qquicklistview.cpp @@ -176,9 +176,9 @@ public: , snapMode(QQuickListView::NoSnap) , headerPositioning(QQuickListView::InlineHeader) , footerPositioning(QQuickListView::InlineFooter) - , highlightPosAnimator(0), highlightWidthAnimator(0), highlightHeightAnimator(0) + , highlightPosAnimator(nullptr), highlightWidthAnimator(nullptr), highlightHeightAnimator(nullptr) , highlightMoveVelocity(400), highlightResizeVelocity(400), highlightResizeDuration(-1) - , sectionCriteria(0), currentSectionItem(0), nextSectionItem(0) + , sectionCriteria(nullptr), currentSectionItem(nullptr), nextSectionItem(nullptr) , overshootDist(0.0), correctFlick(false), inFlickCorrection(false) { highlightMoveDuration = -1; //override default value set in base class @@ -195,8 +195,8 @@ public: //---------------------------------------------------------------------------- QQuickViewSection::QQuickViewSection(QQuickListView *parent) - : QObject(parent), m_criteria(FullString), m_delegate(0), m_labelPositioning(InlineLabels) - , m_view(parent ? QQuickListViewPrivate::get(parent) : 0) + : QObject(parent), m_criteria(FullString), m_delegate(nullptr), m_labelPositioning(InlineLabels) + , m_view(parent ? QQuickListViewPrivate::get(parent) : nullptr) { } @@ -258,7 +258,7 @@ public: } inline QQuickItem *section() const { - return item && attached ? static_cast<QQuickListViewAttached*>(attached)->m_sectionItem : 0; + return item && attached ? static_cast<QQuickListViewAttached*>(attached)->m_sectionItem : nullptr; } void setSection(QQuickItem *s) { static_cast<QQuickListViewAttached*>(attached)->m_sectionItem = s; @@ -389,7 +389,7 @@ bool QQuickListViewPrivate::isBottomToTop() const FxViewItem *QQuickListViewPrivate::itemBefore(int modelIndex) const { if (modelIndex < visibleIndex) - return 0; + return nullptr; int idx = 1; int lastIndex = -1; while (idx < visibleItems.count()) { @@ -402,7 +402,7 @@ FxViewItem *QQuickListViewPrivate::itemBefore(int modelIndex) const } if (lastIndex == modelIndex-1) return visibleItems.constLast(); - return 0; + return nullptr; } void QQuickListViewPrivate::setPosition(qreal pos) @@ -530,7 +530,7 @@ qreal QQuickListViewPrivate::snapPosAt(qreal pos) FxViewItem *QQuickListViewPrivate::snapItemAt(qreal pos) { - FxViewItem *snapItem = 0; + FxViewItem *snapItem = nullptr; qreal prevItemSize = 0; for (FxViewItem *item : qAsConst(visibleItems)) { if (item->index == -1) @@ -561,13 +561,13 @@ void QQuickListViewPrivate::clear() { for (int i = 0; i < sectionCacheSize; ++i) { delete sectionCache[i]; - sectionCache[i] = 0; + sectionCache[i] = nullptr; } visiblePos = 0; releaseSectionItem(currentSectionItem); - currentSectionItem = 0; + currentSectionItem = nullptr; releaseSectionItem(nextSectionItem); - nextSectionItem = 0; + nextSectionItem = nullptr; lastVisibleSection = QString(); QQuickItemViewPrivate::clear(); } @@ -629,13 +629,13 @@ bool QQuickListViewPrivate::releaseItem(FxViewItem *item) if (!sectionCache[i]) { sectionCache[i] = att->m_sectionItem; sectionCache[i]->setVisible(false); - att->m_sectionItem = 0; + att->m_sectionItem = nullptr; break; } ++i; } while (i < sectionCacheSize); delete att->m_sectionItem; - att->m_sectionItem = 0; + att->m_sectionItem = nullptr; } return released; @@ -669,11 +669,13 @@ bool QQuickListViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, qreal } } + QQmlIncubator::IncubationMode incubationMode = doBuffer ? QQmlIncubator::Asynchronous : QQmlIncubator::AsynchronousIfNested; + bool changed = false; - FxListItemSG *item = 0; + FxListItemSG *item = nullptr; qreal pos = itemEnd; while (modelIndex < model->count() && pos <= fillTo) { - if (!(item = static_cast<FxListItemSG*>(createItem(modelIndex, doBuffer)))) + if (!(item = static_cast<FxListItemSG*>(createItem(modelIndex, incubationMode)))) break; qCDebug(lcItemViewDelegateLifecycle) << "refill: append item" << modelIndex << "pos" << pos << "buffer" << doBuffer << "item" << (QObject *)(item->item); if (!transitioner || !transitioner->canTransition(QQuickItemViewTransitioner::PopulateTransition, true)) // pos will be set by layoutVisibleItems() @@ -690,7 +692,7 @@ bool QQuickListViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, qreal return changed; while (visibleIndex > 0 && visibleIndex <= model->count() && visiblePos > fillFrom) { - if (!(item = static_cast<FxListItemSG*>(createItem(visibleIndex-1, doBuffer)))) + if (!(item = static_cast<FxListItemSG*>(createItem(visibleIndex-1, incubationMode)))) break; qCDebug(lcItemViewDelegateLifecycle) << "refill: prepend item" << visibleIndex-1 << "current top pos" << visiblePos << "buffer" << doBuffer << "item" << (QObject *)(item->item); --visibleIndex; @@ -720,7 +722,7 @@ void QQuickListViewPrivate::removeItem(FxViewItem *item) bool QQuickListViewPrivate::removeNonVisibleItems(qreal bufferFrom, qreal bufferTo) { - FxViewItem *item = 0; + FxViewItem *item = nullptr; bool changed = false; // Remove items from the start of the view. @@ -862,16 +864,16 @@ void QQuickListViewPrivate::createHighlight() bool changed = false; if (highlight) { if (trackedItem == highlight) - trackedItem = 0; + trackedItem = nullptr; delete highlight; - highlight = 0; + highlight = nullptr; delete highlightPosAnimator; delete highlightWidthAnimator; delete highlightHeightAnimator; - highlightPosAnimator = 0; - highlightWidthAnimator = 0; - highlightHeightAnimator = 0; + highlightPosAnimator = nullptr; + highlightWidthAnimator = nullptr; + highlightHeightAnimator = nullptr; changed = true; } @@ -960,13 +962,13 @@ bool QQuickListViewPrivate::movingFromHighlight() QQuickItem * QQuickListViewPrivate::getSectionItem(const QString §ion) { Q_Q(QQuickListView); - QQuickItem *sectionItem = 0; + QQuickItem *sectionItem = nullptr; int i = sectionCacheSize-1; while (i >= 0 && !sectionCache[i]) --i; if (i >= 0) { sectionItem = sectionCache[i]; - sectionCache[i] = 0; + sectionCache[i] = nullptr; sectionItem->setVisible(true); QQmlContext *context = QQmlEngine::contextForObject(sectionItem)->parentContext(); context->setContextProperty(QLatin1String("section"), section); @@ -1023,13 +1025,13 @@ void QQuickListViewPrivate::releaseSectionItems() if (listItem->section()) { qreal pos = listItem->position(); releaseSectionItem(listItem->section()); - listItem->setSection(0); + listItem->setSection(nullptr); listItem->setPosition(pos); } } for (int i = 0; i < sectionCacheSize; ++i) { delete sectionCache[i]; - sectionCache[i] = 0; + sectionCache[i] = nullptr; } } @@ -1051,7 +1053,7 @@ void QQuickListViewPrivate::updateInlineSection(FxListItemSG *listItem) } else if (listItem->section()) { qreal pos = listItem->position(); releaseSectionItem(listItem->section()); - listItem->setSection(0); + listItem->setSection(nullptr); listItem->setPosition(pos); } } @@ -1067,8 +1069,8 @@ void QQuickListViewPrivate::updateStickySections() qreal startPos = hasStickyHeader() ? header->endPosition() : viewPos; qreal endPos = hasStickyFooter() ? footer->position() : viewPos + size(); - QQuickItem *sectionItem = 0; - QQuickItem *lastSectionItem = 0; + QQuickItem *sectionItem = nullptr; + QQuickItem *lastSectionItem = nullptr; int index = 0; while (index < visibleItems.count()) { if (QQuickItem *section = static_cast<FxListItemSG *>(visibleItems.at(index))->section()) { @@ -1127,7 +1129,7 @@ void QQuickListViewPrivate::updateStickySections() currentSectionItem->setX(pos); } else if (currentSectionItem) { releaseSectionItem(currentSectionItem); - currentSectionItem = 0; + currentSectionItem = nullptr; } // Next section footer @@ -1159,7 +1161,7 @@ void QQuickListViewPrivate::updateStickySections() nextSectionItem->setX(pos); } else if (nextSectionItem) { releaseSectionItem(nextSectionItem); - nextSectionItem = 0; + nextSectionItem = nullptr; } } @@ -1175,7 +1177,7 @@ void QQuickListViewPrivate::updateSections() QString prevSection; if (visibleIndex > 0) prevSection = sectionAt(visibleIndex-1); - QQuickListViewAttached *prevAtt = 0; + QQuickListViewAttached *prevAtt = nullptr; int prevIdx = -1; int idx = -1; for (FxViewItem *item : qAsConst(visibleItems)) { @@ -1466,9 +1468,6 @@ void QQuickListViewPrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometry void QQuickListViewPrivate::fixupPosition() { - if ((haveHighlightRange && highlightRange == QQuickListView::StrictlyEnforceRange) - || snapMode != QQuickListView::NoSnap) - moveReason = Other; if (orient == QQuickListView::Vertical) fixupY(); else @@ -3267,11 +3266,11 @@ bool QQuickListViewPrivate::applyInsertionChange(const QQmlChangeSet::Change &ch } else { for (i = count-1; i >= 0 && pos >= from; --i) { // item is before first visible e.g. in cache buffer - FxViewItem *item = 0; + FxViewItem *item = nullptr; if (change.isMove() && (item = currentChanges.removedItems.take(change.moveKey(modelIndex + i)))) item->index = modelIndex + i; if (!item) - item = createItem(modelIndex + i); + item = createItem(modelIndex + i, QQmlIncubator::Synchronous); if (!item) return false; @@ -3308,12 +3307,12 @@ bool QQuickListViewPrivate::applyInsertionChange(const QQmlChangeSet::Change &ch } else { for (int i = 0; i < count && pos <= lastVisiblePos; ++i) { visibleAffected = true; - FxViewItem *item = 0; + FxViewItem *item = nullptr; if (change.isMove() && (item = currentChanges.removedItems.take(change.moveKey(modelIndex + i)))) item->index = modelIndex + i; bool newItem = !item; if (!item) - item = createItem(modelIndex + i); + item = createItem(modelIndex + i, QQmlIncubator::Synchronous); if (!item) return false; diff --git a/src/quick/items/qquicklistview_p.h b/src/quick/items/qquicklistview_p.h index f8db0f0f8f..9a9b325b1e 100644 --- a/src/quick/items/qquicklistview_p.h +++ b/src/quick/items/qquicklistview_p.h @@ -71,7 +71,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickViewSection : public QObject Q_PROPERTY(QQmlComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged) Q_PROPERTY(int labelPositioning READ labelPositioning WRITE setLabelPositioning NOTIFY labelPositioningChanged) public: - QQuickViewSection(QQuickListView *parent=0); + QQuickViewSection(QQuickListView *parent=nullptr); QString property() const { return m_property; } void setProperty(const QString &); @@ -132,7 +132,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickListView : public QQuickItemView Q_CLASSINFO("DefaultProperty", "data") public: - QQuickListView(QQuickItem *parent=0); + QQuickListView(QQuickItem *parent=nullptr); ~QQuickListView(); qreal spacing() const; @@ -206,7 +206,7 @@ class QQuickListViewAttached : public QQuickItemViewAttached public: QQuickListViewAttached(QObject *parent) - : QQuickItemViewAttached(parent), m_sectionItem(0) {} + : QQuickItemViewAttached(parent), m_sectionItem(nullptr) {} ~QQuickListViewAttached() {} public: diff --git a/src/quick/items/qquickloader.cpp b/src/quick/items/qquickloader.cpp index 27afe5a5db..34f30e81a3 100644 --- a/src/quick/items/qquickloader.cpp +++ b/src/quick/items/qquickloader.cpp @@ -48,11 +48,13 @@ QT_BEGIN_NAMESPACE +Q_DECLARE_LOGGING_CATEGORY(lcTransient) + static const QQuickItemPrivate::ChangeTypes watchedChanges = QQuickItemPrivate::Geometry | QQuickItemPrivate::ImplicitWidth | QQuickItemPrivate::ImplicitHeight; QQuickLoaderPrivate::QQuickLoaderPrivate() - : item(0), object(0), component(0), itemContext(0), incubator(0), updatingSize(false), + : item(nullptr), object(nullptr), component(nullptr), itemContext(nullptr), incubator(nullptr), updatingSize(false), active(true), loadingFromSource(false), asynchronous(false) { } @@ -60,7 +62,7 @@ QQuickLoaderPrivate::QQuickLoaderPrivate() QQuickLoaderPrivate::~QQuickLoaderPrivate() { delete itemContext; - itemContext = 0; + itemContext = nullptr; delete incubator; disposeInitialPropertyValues(); } @@ -94,7 +96,13 @@ void QQuickLoaderPrivate::clear() incubator->clear(); delete itemContext; - itemContext = 0; + itemContext = nullptr; + + // Prevent any bindings from running while waiting for deletion. Without + // this we may get transient errors from use of 'parent', for example. + QQmlContext *context = qmlContext(object); + if (context) + QQmlContextData::get(context)->invalidate(); if (loadingFromSource && component) { // disconnect since we deleteLater @@ -103,7 +111,7 @@ void QQuickLoaderPrivate::clear() QObject::disconnect(component, SIGNAL(progressChanged(qreal)), q, SIGNAL(progressChanged())); component->deleteLater(); - component = 0; + component = nullptr; } componentStrongReference.clear(); source = QUrl(); @@ -114,13 +122,13 @@ void QQuickLoaderPrivate::clear() // We can't delete immediately because our item may have triggered // the Loader to load a different item. - item->setParentItem(0); + item->setParentItem(nullptr); item->setVisible(false); - item = 0; + item = nullptr; } if (object) { object->deleteLater(); - object = 0; + object = nullptr; } } @@ -348,22 +356,28 @@ void QQuickLoader::setActive(bool newVal) if (d->incubator) { d->incubator->clear(); delete d->itemContext; - d->itemContext = 0; + d->itemContext = nullptr; } + // Prevent any bindings from running while waiting for deletion. Without + // this we may get transient errors from use of 'parent', for example. + QQmlContext *context = qmlContext(d->object); + if (context) + QQmlContextData::get(context)->invalidate(); + if (d->item) { QQuickItemPrivate *p = QQuickItemPrivate::get(d->item); p->removeItemChangeListener(d, watchedChanges); // We can't delete immediately because our item may have triggered // the Loader to load a different item. - d->item->setParentItem(0); + d->item->setParentItem(nullptr); d->item->setVisible(false); - d->item = 0; + d->item = nullptr; } if (d->object) { d->object->deleteLater(); - d->object = 0; + d->object = nullptr; emit itemChanged(); } emit statusChanged(); @@ -485,7 +499,7 @@ void QQuickLoader::setSourceComponent(QQmlComponent *comp) void QQuickLoader::resetSourceComponent() { - setSourceComponent(0); + setSourceComponent(nullptr); } void QQuickLoader::loadFromSourceComponent() @@ -642,7 +656,7 @@ void QQuickLoaderPrivate::setInitialState(QObject *obj) if (obj) { QQml_setParent_noEvent(itemContext, obj); QQml_setParent_noEvent(obj, q); - itemContext = 0; + itemContext = nullptr; } if (initialPropertyValues.isUndefined()) @@ -650,7 +664,7 @@ void QQuickLoaderPrivate::setInitialState(QObject *obj) QQmlComponentPrivate *d = QQmlComponentPrivate::get(component); Q_ASSERT(d && d->engine); - QV4::ExecutionEngine *v4 = QV8Engine::getV4(d->engine); + QV4::ExecutionEngine *v4 = d->engine->handle(); Q_ASSERT(v4); QV4::Scope scope(v4); QV4::ScopedValue ipv(scope, initialPropertyValues.value()); @@ -672,6 +686,13 @@ void QQuickLoaderPrivate::incubatorStateChanged(QQmlIncubator::Status status) if (status == QQmlIncubator::Ready) { object = incubator->object(); item = qmlobject_cast<QQuickItem*>(object); + if (!item) { + QQuickWindow *window = qmlobject_cast<QQuickWindow*>(object); + if (window) { + qCDebug(lcTransient) << window << "is transient for" << q->window(); + window->setTransientParent(q->window()); + } + } emit q->itemChanged(); initResize(); incubator->clear(); @@ -679,7 +700,7 @@ void QQuickLoaderPrivate::incubatorStateChanged(QQmlIncubator::Status status) if (!incubator->errors().isEmpty()) QQmlEnginePrivate::warning(qmlEngine(q), incubator->errors()); delete itemContext; - itemContext = 0; + itemContext = nullptr; delete incubator->object(); source = QUrl(); emit q->itemChanged(); @@ -816,6 +837,18 @@ void QQuickLoader::componentComplete() } } +void QQuickLoader::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value) +{ + if (change == ItemSceneChange) { + QQuickWindow *loadedWindow = qmlobject_cast<QQuickWindow *>(item()); + if (loadedWindow) { + qCDebug(lcTransient) << loadedWindow << "is transient for" << value.window; + loadedWindow->setTransientParent(value.window); + } + } + QQuickItem::itemChange(change, value); +} + /*! \qmlsignal QtQuick::Loader::loaded() diff --git a/src/quick/items/qquickloader_p.h b/src/quick/items/qquickloader_p.h index 27e5d1ec8b..de1dfa9da5 100644 --- a/src/quick/items/qquickloader_p.h +++ b/src/quick/items/qquickloader_p.h @@ -69,7 +69,7 @@ class Q_AUTOTEST_EXPORT QQuickLoader : public QQuickImplicitSizeItem Q_PROPERTY(bool asynchronous READ asynchronous WRITE setAsynchronous NOTIFY asynchronousChanged) public: - QQuickLoader(QQuickItem *parent = 0); + QQuickLoader(QQuickItem *parent = nullptr); virtual ~QQuickLoader(); bool active() const; @@ -107,6 +107,7 @@ Q_SIGNALS: protected: void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override; void componentComplete() override; + void itemChange(ItemChange change, const ItemChangeData &value) override; private: void setSource(const QUrl &sourceUrl, bool needsClear); diff --git a/src/quick/items/qquickmousearea.cpp b/src/quick/items/qquickmousearea.cpp index 96f34ef276..052da9fe82 100644 --- a/src/quick/items/qquickmousearea.cpp +++ b/src/quick/items/qquickmousearea.cpp @@ -60,13 +60,13 @@ Q_DECLARE_LOGGING_CATEGORY(DBG_HOVER_TRACE) QQuickMouseAreaPrivate::QQuickMouseAreaPrivate() : enabled(true), scrollGestureEnabled(true), hovered(false), longPress(false), moved(false), stealMouse(false), doubleClick(false), preventStealing(false), - propagateComposedEvents(false), overThreshold(false), pressed(0), + propagateComposedEvents(false), overThreshold(false), pressed(nullptr), pressAndHoldInterval(-1) #if QT_CONFIG(draganddrop) - , drag(0) + , drag(nullptr) #endif #if QT_CONFIG(cursor) - , cursor(0) + , cursor(nullptr) #endif { } @@ -99,6 +99,7 @@ void QQuickMouseAreaPrivate::saveEvent(QMouseEvent *event) lastButton = event->button(); lastButtons = event->buttons(); lastModifiers = event->modifiers(); + lastFlags = event->flags(); } bool QQuickMouseAreaPrivate::isPressAndHoldConnected() @@ -784,7 +785,7 @@ void QQuickMouseArea::mouseMoveEvent(QMouseEvent *event) #endif QQuickMouseEvent &me = d->quickMouseEvent; - me.reset(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, false, d->longPress); + me.reset(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, false, d->longPress, event->flags()); me.setSource(event->source()); emit mouseXChanged(&me); me.setPosition(d->lastPos); @@ -827,7 +828,8 @@ void QQuickMouseArea::mouseDoubleClickEvent(QMouseEvent *event) if (d->enabled) { d->saveEvent(event); QQuickMouseEvent &me = d->quickMouseEvent; - me.reset(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, true, false); + me.reset(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, true, + false, event->flags()); me.setSource(event->source()); me.setAccepted(d->isDoubleClickConnected()); emit this->doubleClicked(&me); @@ -908,7 +910,7 @@ void QQuickMouseArea::ungrabMouse() if (d->pressed) { // if our mouse grab has been removed (probably by Flickable), fix our // state - d->pressed = 0; + d->pressed = nullptr; d->stealMouse = false; d->doubleClick = false; d->overThreshold = false; @@ -942,7 +944,7 @@ bool QQuickMouseArea::sendMouseEvent(QMouseEvent *event) QPointF localPos = mapFromScene(event->windowPos()); QQuickWindow *c = window(); - QQuickItem *grabber = c ? c->mouseGrabberItem() : 0; + QQuickItem *grabber = c ? c->mouseGrabberItem() : nullptr; bool stealThisEvent = d->stealMouse; if ((stealThisEvent || contains(localPos)) && (!grabber || !grabber->keepMouseGrab())) { QMouseEvent mouseEvent(event->type(), localPos, event->windowPos(), event->screenPos(), @@ -963,7 +965,7 @@ bool QQuickMouseArea::sendMouseEvent(QMouseEvent *event) default: break; } - grabber = c ? c->mouseGrabberItem() : 0; + grabber = c ? c->mouseGrabberItem() : nullptr; if (grabber && stealThisEvent && !grabber->keepMouseGrab() && grabber != this) grabMouse(); @@ -1028,7 +1030,7 @@ void QQuickMouseArea::timerEvent(QTimerEvent *event) if (d->pressed && dragged == false && d->hovered == true) { d->longPress = true; QQuickMouseEvent &me = d->quickMouseEvent; - me.reset(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, false, d->longPress); + me.reset(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, false, d->longPress, d->lastFlags); me.setSource(Qt::MouseEventSynthesizedByQt); me.setAccepted(d->isPressAndHoldConnected()); emit pressAndHold(&me); @@ -1207,7 +1209,7 @@ bool QQuickMouseArea::setPressed(Qt::MouseButton button, bool p, Qt::MouseEventS if (wasPressed != p) { QQuickMouseEvent &me = d->quickMouseEvent; - me.reset(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, isclick, d->longPress); + me.reset(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, isclick, d->longPress, d->lastFlags); me.setSource(source); if (p) { d->pressed |= button; @@ -1418,7 +1420,7 @@ QSGNode *QQuickMouseArea::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData Q_D(QQuickMouseArea); if (!qmlVisualTouchDebugging()) - return 0; + return nullptr; QSGInternalRectangleNode *rectangle = static_cast<QSGInternalRectangleNode *>(oldNode); if (!rectangle) rectangle = d->sceneGraphContext()->createInternalRectangleNode(); diff --git a/src/quick/items/qquickmousearea_p.h b/src/quick/items/qquickmousearea_p.h index ae6c56726e..0a8449957f 100644 --- a/src/quick/items/qquickmousearea_p.h +++ b/src/quick/items/qquickmousearea_p.h @@ -87,7 +87,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickMouseArea : public QQuickItem Q_PROPERTY(int pressAndHoldInterval READ pressAndHoldInterval WRITE setPressAndHoldInterval NOTIFY pressAndHoldIntervalChanged RESET resetPressAndHoldInterval REVISION 9) public: - QQuickMouseArea(QQuickItem *parent=0); + QQuickMouseArea(QQuickItem *parent=nullptr); ~QQuickMouseArea(); qreal mouseX() const; diff --git a/src/quick/items/qquickmousearea_p_p.h b/src/quick/items/qquickmousearea_p_p.h index 2fa5f7cd44..0dd2690d43 100644 --- a/src/quick/items/qquickmousearea_p_p.h +++ b/src/quick/items/qquickmousearea_p_p.h @@ -61,6 +61,7 @@ QT_BEGIN_NAMESPACE class QQuickMouseEvent; class QQuickMouseArea; +class QQuickPointerMask; class QQuickMouseAreaPrivate : public QQuickItemPrivate { Q_DECLARE_PUBLIC(QQuickMouseArea) @@ -99,6 +100,7 @@ public: #if QT_CONFIG(draganddrop) QQuickDrag *drag; #endif + QPointer<QQuickPointerMask> mask; QPointF startScene; QPointF targetStartPos; QPointF lastPos; @@ -112,6 +114,7 @@ public: #endif QQuickMouseEvent quickMouseEvent; QQuickWheelEvent quickWheelEvent; + Qt::MouseEventFlags lastFlags; }; QT_END_NAMESPACE diff --git a/src/quick/items/qquickmultipointtoucharea.cpp b/src/quick/items/qquickmultipointtoucharea.cpp index bdf30469ce..dc168073e4 100644 --- a/src/quick/items/qquickmultipointtoucharea.cpp +++ b/src/quick/items/qquickmultipointtoucharea.cpp @@ -285,6 +285,43 @@ void QQuickTouchPoint::setUniqueId(const QPointingDeviceUniqueId &id) emit uniqueIdChanged(); } + +/*! + \qmltype GestureEvent + \instantiates QQuickGrabGestureEvent + \inqmlmodule QtQuick + \ingroup qtquick-input-events + \brief The parameter given with the gestureStarted signal + + The GestureEvent object has the current touch points, which you may choose + to interpret as a gesture, and an invokable method to grab the involved + points exclusively. +*/ + +/*! + \qmlproperty real QtQuick::GestureEvent::dragThreshold + + This property holds the system setting for the distance a finger must move + before it is interpreted as a drag. It comes from + QStyleHints::startDragDistance(). +*/ + +/*! + \qmlproperty list<TouchPoint> QtQuick::GestureEvent::touchPoints + + This property holds the set of current touch points. +*/ + +/*! + \qmlmethod QtQuick::GestureEvent::grab() + + Acquires an exclusive grab of the mouse and all the \l touchPoints, and + calls \l {QQuickItem::setKeepTouchGrab()}{setKeepTouchGrab()} and + \l {QQuickItem::setKeepMouseGrab()}{setKeepMouseGrab()} so that any + parent Item that \l {QQuickItem::filtersChildMouseEvents()}{filters} its + children's events will not be allowed to take over the grabs. +*/ + /*! \qmltype MultiPointTouchArea \instantiates QQuickMultiPointTouchArea @@ -504,7 +541,7 @@ void QQuickMultiPointTouchArea::touchEvent(QTouchEvent *event) case QEvent::TouchEnd: { //if e.g. a parent Flickable has the mouse grab, don't process the touch events QQuickWindow *c = window(); - QQuickItem *grabber = c ? c->mouseGrabberItem() : 0; + QQuickItem *grabber = c ? c->mouseGrabberItem() : nullptr; if (grabber && grabber != this && grabber->keepMouseGrab() && grabber->isEnabled()) { QQuickItem *item = this; while ((item = item->parentItem())) { @@ -682,7 +719,7 @@ void QQuickMultiPointTouchArea::clearTouchLists() void QQuickMultiPointTouchArea::addTouchPoint(const QTouchEvent::TouchPoint *p) { - QQuickTouchPoint *dtp = 0; + QQuickTouchPoint *dtp = nullptr; for (QQuickTouchPoint* tp : qAsConst(_touchPrototypes)) { if (!tp->inUse()) { tp->setInUse(true); @@ -691,7 +728,7 @@ void QQuickMultiPointTouchArea::addTouchPoint(const QTouchEvent::TouchPoint *p) } } - if (dtp == 0) + if (dtp == nullptr) dtp = new QQuickTouchPoint(false); dtp->setPointId(p->id()); updateTouchPoint(dtp,p); @@ -702,7 +739,7 @@ void QQuickMultiPointTouchArea::addTouchPoint(const QTouchEvent::TouchPoint *p) void QQuickMultiPointTouchArea::addTouchPoint(const QMouseEvent *e) { - QQuickTouchPoint *dtp = 0; + QQuickTouchPoint *dtp = nullptr; for (QQuickTouchPoint *tp : qAsConst(_touchPrototypes)) if (!tp->inUse()) { tp->setInUse(true); @@ -710,7 +747,7 @@ void QQuickMultiPointTouchArea::addTouchPoint(const QMouseEvent *e) break; } - if (dtp == 0) + if (dtp == nullptr) dtp = new QQuickTouchPoint(false); updateTouchPoint(dtp, e); dtp->setPressed(true); @@ -883,7 +920,7 @@ bool QQuickMultiPointTouchArea::sendMouseEvent(QMouseEvent *event) QPointF localPos = mapFromScene(event->windowPos()); QQuickWindow *c = window(); - QQuickItem *grabber = c ? c->mouseGrabberItem() : 0; + QQuickItem *grabber = c ? c->mouseGrabberItem() : nullptr; bool stealThisEvent = _stealMouse; if ((stealThisEvent || contains(localPos)) && (!grabber || !grabber->keepMouseGrab())) { QMouseEvent mouseEvent(event->type(), localPos, event->windowPos(), event->screenPos(), @@ -907,7 +944,7 @@ bool QQuickMultiPointTouchArea::sendMouseEvent(QMouseEvent *event) default: break; } - grabber = c ? c->mouseGrabberItem() : 0; + grabber = c ? c->mouseGrabberItem() : nullptr; if (grabber && stealThisEvent && !grabber->keepMouseGrab() && grabber != this) grabMouse(); @@ -954,7 +991,7 @@ bool QQuickMultiPointTouchArea::childMouseEventFilter(QQuickItem *receiver, QEve bool QQuickMultiPointTouchArea::shouldFilter(QEvent *event) { QQuickWindow *c = window(); - QQuickItem *grabber = c ? c->mouseGrabberItem() : 0; + QQuickItem *grabber = c ? c->mouseGrabberItem() : nullptr; bool disabledItem = grabber && !grabber->isEnabled(); bool stealThisEvent = _stealMouse; bool containsPoint = false; @@ -995,7 +1032,7 @@ QSGNode *QQuickMultiPointTouchArea::updatePaintNode(QSGNode *oldNode, UpdatePain Q_UNUSED(data); if (!qmlVisualTouchDebugging()) - return 0; + return nullptr; QSGInternalRectangleNode *rectangle = static_cast<QSGInternalRectangleNode *>(oldNode); if (!rectangle) rectangle = QQuickItemPrivate::get(this)->sceneGraphContext()->createInternalRectangleNode(); diff --git a/src/quick/items/qquickmultipointtoucharea_p.h b/src/quick/items/qquickmultipointtoucharea_p.h index 64fe81563d..f1550b4ac6 100644 --- a/src/quick/items/qquickmultipointtoucharea_p.h +++ b/src/quick/items/qquickmultipointtoucharea_p.h @@ -86,16 +86,7 @@ class Q_AUTOTEST_EXPORT QQuickTouchPoint : public QObject public: QQuickTouchPoint(bool qmlDefined = true) - : _id(0), - _x(0.0), _y(0.0), - _pressure(0.0), - _rotation(0), - _qmlDefined(qmlDefined), - _inUse(false), - _pressed(false), - _startX(0.0), _startY(0.0), - _previousX(0.0), _previousY(0.0), - _sceneX(0.0), _sceneY(0.0) + : _qmlDefined(qmlDefined) {} int pointId() const { return _id; } @@ -171,23 +162,23 @@ Q_SIGNALS: private: friend class QQuickMultiPointTouchArea; - int _id; - qreal _x; - qreal _y; - qreal _pressure; - qreal _rotation; + int _id = 0; + qreal _x = 0.0; + qreal _y = 0.0; + qreal _pressure = 0.0; + qreal _rotation = 0; QSizeF _ellipseDiameters; QVector2D _velocity; QRectF _area; bool _qmlDefined; - bool _inUse; //whether the point is currently in use (only valid when _qmlDefined == true) - bool _pressed; - qreal _startX; - qreal _startY; - qreal _previousX; - qreal _previousY; - qreal _sceneX; - qreal _sceneY; + bool _inUse = false; //whether the point is currently in use (only valid when _qmlDefined == true) + bool _pressed = false; + qreal _startX = 0.0; + qreal _startY = 0.0; + qreal _previousX = 0.0; + qreal _previousY = 0.0; + qreal _sceneX = 0.0; + qreal _sceneY = 0.0; QPointingDeviceUniqueId _uniqueId; }; @@ -197,7 +188,7 @@ class QQuickGrabGestureEvent : public QObject Q_PROPERTY(QQmlListProperty<QObject> touchPoints READ touchPoints) Q_PROPERTY(qreal dragThreshold READ dragThreshold) public: - QQuickGrabGestureEvent() : _grab(false), _dragThreshold(QGuiApplication::styleHints()->startDragDistance()) {} + QQuickGrabGestureEvent() : _dragThreshold(QGuiApplication::styleHints()->startDragDistance()) {} Q_INVOKABLE void grab() { _grab = true; } bool wantsGrab() const { return _grab; } @@ -209,7 +200,7 @@ public: private: friend class QQuickMultiPointTouchArea; - bool _grab; + bool _grab = false; qreal _dragThreshold; QList<QObject*> _touchPoints; }; @@ -224,7 +215,7 @@ class Q_AUTOTEST_EXPORT QQuickMultiPointTouchArea : public QQuickItem Q_PROPERTY(bool mouseEnabled READ mouseEnabled WRITE setMouseEnabled NOTIFY mouseEnabledChanged) public: - QQuickMultiPointTouchArea(QQuickItem *parent=0); + QQuickMultiPointTouchArea(QQuickItem *parent=nullptr); ~QQuickMultiPointTouchArea(); int minimumTouchPoints() const; @@ -235,7 +226,7 @@ public: void setMouseEnabled(bool arg); QQmlListProperty<QQuickTouchPoint> touchPoints() { - return QQmlListProperty<QQuickTouchPoint>(this, 0, QQuickMultiPointTouchArea::touchPoint_append, QQuickMultiPointTouchArea::touchPoint_count, QQuickMultiPointTouchArea::touchPoint_at, 0); + return QQmlListProperty<QQuickTouchPoint>(this, nullptr, QQuickMultiPointTouchArea::touchPoint_append, QQuickMultiPointTouchArea::touchPoint_count, QQuickMultiPointTouchArea::touchPoint_at, nullptr); } static void touchPoint_append(QQmlListProperty<QQuickTouchPoint> *list, QQuickTouchPoint* touch) { diff --git a/src/quick/items/qquickopenglinfo.cpp b/src/quick/items/qquickopenglinfo.cpp index 7f5364031a..73f9c85e94 100644 --- a/src/quick/items/qquickopenglinfo.cpp +++ b/src/quick/items/qquickopenglinfo.cpp @@ -69,7 +69,7 @@ QT_BEGIN_NAMESPACE */ QQuickOpenGLInfo::QQuickOpenGLInfo(QQuickItem *item) : QObject(item) - , m_window(0) + , m_window(nullptr) , m_majorVersion(2) , m_minorVersion(0) , m_profile(NoProfile) @@ -150,12 +150,12 @@ QQuickOpenGLInfo *QQuickOpenGLInfo::qmlAttachedProperties(QObject *object) { if (QQuickItem *item = qobject_cast<QQuickItem *>(object)) return new QQuickOpenGLInfo(item); - return 0; + return nullptr; } void QQuickOpenGLInfo::updateFormat() { - QOpenGLContext *context = 0; + QOpenGLContext *context = nullptr; if (m_window) context = m_window->openglContext(); QSurfaceFormat format = context ? context->format() : QSurfaceFormat::defaultFormat(); diff --git a/src/quick/items/qquickopenglshadereffect.cpp b/src/quick/items/qquickopenglshadereffect.cpp index c3e0ba05bd..cad598d2c0 100644 --- a/src/quick/items/qquickopenglshadereffect.cpp +++ b/src/quick/items/qquickopenglshadereffect.cpp @@ -139,7 +139,7 @@ namespace { expected = TypeIdentifier; break; } - // Fall through. + Q_FALLTHROUGH(); case TypeIdentifier: typeIndex = idIndex; typeLength = idLength; @@ -422,8 +422,9 @@ void QQuickOpenGLShaderEffectCommon::updateShader(QQuickItem *item, d.specialType = UniformData::Opacity; uniformData[Key::FragmentShader].append(d); signalMappers[Key::FragmentShader].append(0); - const int mappedId = 1 | (Key::FragmentShader << 16); - auto mapper = new QtPrivate::MappedSlotObject([this, mappedId](){mappedPropertyChanged(mappedId);}); + auto mapper = new QtPrivate::MappedSlotObject([this](){ + mappedPropertyChanged(1 | (Key::FragmentShader << 16)); + }); const char *sourceName = "source"; d.name = sourceName; d.setValueFromProperty(item, itemMetaObject); @@ -483,7 +484,7 @@ void QQuickOpenGLShaderEffectCommon::updateMaterial(QQuickOpenGLShaderEffectNode if (d.specialType != UniformData::Sampler && d.specialType != UniformData::SamplerExternal) continue; QSGTextureProvider *oldProvider = material->textureProviders.at(index); - QSGTextureProvider *newProvider = 0; + QSGTextureProvider *newProvider = nullptr; QQuickItem *source = qobject_cast<QQuickItem *>(qvariant_cast<QObject *>(d.value)); if (source && source->isTextureProvider()) newProvider = source->textureProvider(); @@ -623,7 +624,7 @@ QQuickOpenGLShaderEffect::QQuickOpenGLShaderEffect(QQuickShaderEffect *item, QOb , m_item(item) , m_itemMetaObject(nullptr) , m_meshResolution(1, 1) - , m_mesh(0) + , m_mesh(nullptr) , m_cullMode(QQuickShaderEffect::NoCulling) , m_status(QQuickShaderEffect::Uncompiled) , m_common(this, [this](int mappedId){this->propertyChanged(mappedId);}) @@ -712,7 +713,7 @@ void QQuickOpenGLShaderEffect::setMesh(const QVariant &mesh) if (newMesh && newMesh == m_mesh) return; if (m_mesh) - disconnect(m_mesh, SIGNAL(geometryChanged()), this, 0); + disconnect(m_mesh, SIGNAL(geometryChanged()), this, nullptr); m_mesh = newMesh; if (m_mesh) { connect(m_mesh, SIGNAL(geometryChanged()), this, SLOT(updateGeometry())); @@ -765,7 +766,7 @@ QString QQuickOpenGLShaderEffect::parseLog() maybeUpdateShaders(true); if (m_dirtyParseLog) { - m_common.updateParseLog(m_mesh != 0); + m_common.updateParseLog(m_mesh != nullptr); m_dirtyParseLog = false; } return m_common.parseLog; @@ -837,7 +838,7 @@ QSGNode *QQuickOpenGLShaderEffect::handleUpdatePaintNode(QSGNode *oldNode, QQuic if (m_common.attributes.isEmpty() || m_item->width() <= 0 || m_item->height() <= 0) { if (node) delete node; - return 0; + return nullptr; } if (!node) { @@ -896,7 +897,7 @@ QSGNode *QQuickOpenGLShaderEffect::handleUpdatePaintNode(QSGNode *oldNode, QQuic bool geometryUsesTextureSubRect = false; if (m_supportsAtlasTextures && material->textureProviders.size() == 1) { QSGTextureProvider *provider = material->textureProviders.at(0); - if (provider->texture()) { + if (provider && provider->texture()) { srcRect = provider->texture()->normalizedTextureSubRect(); geometryUsesTextureSubRect = true; } @@ -913,7 +914,7 @@ QSGNode *QQuickOpenGLShaderEffect::handleUpdatePaintNode(QSGNode *oldNode, QQuic } if (m_dirtyMesh) { - node->setGeometry(0); + node->setGeometry(nullptr); m_dirtyMesh = false; m_dirtyGeometry = true; } @@ -934,7 +935,7 @@ QSGNode *QQuickOpenGLShaderEffect::handleUpdatePaintNode(QSGNode *oldNode, QQuic emit m_item->statusChanged(); } delete node; - return 0; + return nullptr; } geometry = mesh->updateGeometry(geometry, m_common.attributes.count(), posIndex, srcRect, rect); diff --git a/src/quick/items/qquickopenglshadereffect_p.h b/src/quick/items/qquickopenglshadereffect_p.h index f602bd8b8e..a15d85bff3 100644 --- a/src/quick/items/qquickopenglshadereffect_p.h +++ b/src/quick/items/qquickopenglshadereffect_p.h @@ -120,8 +120,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickOpenGLShaderEffect : public QObject Q_OBJECT public: - QQuickOpenGLShaderEffect(QQuickShaderEffect *item, QObject *parent = 0); - ~QQuickOpenGLShaderEffect(); + QQuickOpenGLShaderEffect(QQuickShaderEffect *item, QObject *parent = nullptr); + ~QQuickOpenGLShaderEffect() override; QByteArray fragmentShader() const { return m_common.source.sourceCode[Key::FragmentShader]; } void setFragmentShader(const QByteArray &code); diff --git a/src/quick/items/qquickopenglshadereffectnode.cpp b/src/quick/items/qquickopenglshadereffectnode.cpp index a6431135eb..d51419a275 100644 --- a/src/quick/items/qquickopenglshadereffectnode.cpp +++ b/src/quick/items/qquickopenglshadereffectnode.cpp @@ -111,7 +111,7 @@ void QQuickCustomMaterialShader::updateState(const RenderState &state, QSGMateri { typedef QQuickOpenGLShaderEffectMaterial::UniformData UniformData; - Q_ASSERT(newEffect != 0); + Q_ASSERT(newEffect != nullptr); QQuickOpenGLShaderEffectMaterial *material = static_cast<QQuickOpenGLShaderEffectMaterial *>(newEffect); if (!material->m_emittedLogChanged && material->m_node) { @@ -239,7 +239,7 @@ void QQuickCustomMaterialShader::updateState(const RenderState &state, QSGMateri functions->glActiveTexture(GL_TEXTURE0); const QQuickOpenGLShaderEffectMaterial *oldMaterial = static_cast<const QQuickOpenGLShaderEffectMaterial *>(oldEffect); - if (oldEffect == 0 || material->cullMode != oldMaterial->cullMode) { + if (oldEffect == nullptr || material->cullMode != oldMaterial->cullMode) { switch (material->cullMode) { case QQuickShaderEffect::FrontFaceCulling: functions->glEnable(GL_CULL_FACE); diff --git a/src/quick/items/qquickopenglshadereffectnode_p.h b/src/quick/items/qquickopenglshadereffectnode_p.h index 68eece7660..7c75bb3126 100644 --- a/src/quick/items/qquickopenglshadereffectnode_p.h +++ b/src/quick/items/qquickopenglshadereffectnode_p.h @@ -109,7 +109,7 @@ public: } }; - explicit QQuickOpenGLShaderEffectMaterial(QQuickOpenGLShaderEffectNode *node = 0); + explicit QQuickOpenGLShaderEffectMaterial(QQuickOpenGLShaderEffectNode *node = nullptr); QSGMaterialType *type() const override; QSGMaterialShader *createShader() const override; int compare(const QSGMaterial *other) const override; @@ -149,7 +149,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickOpenGLShaderEffectNode : public QObject, publ Q_OBJECT public: QQuickOpenGLShaderEffectNode(); - virtual ~QQuickOpenGLShaderEffectNode(); + ~QQuickOpenGLShaderEffectNode() override; void preprocess() override; diff --git a/src/quick/items/qquickpainteditem.cpp b/src/quick/items/qquickpainteditem.cpp index 34d71f00e8..57848919f3 100644 --- a/src/quick/items/qquickpainteditem.cpp +++ b/src/quick/items/qquickpainteditem.cpp @@ -53,7 +53,7 @@ class QQuickPaintedItemTextureProvider : public QSGTextureProvider { public: QSGPainterNode *node; - QSGTexture *texture() const override { return node ? node->texture() : 0; } + QSGTexture *texture() const override { return node ? node->texture() : nullptr; } void fireTextureChanged() { emit textureChanged(); } }; @@ -133,12 +133,12 @@ QQuickPaintedItemPrivate::QQuickPaintedItemPrivate() , contentsScale(1.0) , fillColor(Qt::transparent) , renderTarget(QQuickPaintedItem::Image) - , performanceHints(0) + , performanceHints(nullptr) , opaquePainting(false) , antialiasing(false) , mipmap(false) - , textureProvider(0) - , node(0) + , textureProvider(nullptr) + , node(nullptr) { } @@ -566,10 +566,10 @@ QSGNode *QQuickPaintedItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeDat if (width() <= 0 || height() <= 0) { delete oldNode; if (d->textureProvider) { - d->textureProvider->node = 0; + d->textureProvider->node = nullptr; d->textureProvider->fireTextureChanged(); } - return 0; + return nullptr; } QSGPainterNode *node = static_cast<QSGPainterNode *>(oldNode); @@ -628,17 +628,17 @@ void QQuickPaintedItem::releaseResources() Q_D(QQuickPaintedItem); if (d->textureProvider) { QQuickWindowQObjectCleanupJob::schedule(window(), d->textureProvider); - d->textureProvider = 0; + d->textureProvider = nullptr; } - d->node = 0; // Managed by the scene graph, just clear the pointer. + d->node = nullptr; // Managed by the scene graph, just clear the pointer. } void QQuickPaintedItem::invalidateSceneGraph() { Q_D(QQuickPaintedItem); delete d->textureProvider; - d->textureProvider = 0; - d->node = 0; // Managed by the scene graph, just clear the pointer + d->textureProvider = nullptr; + d->node = nullptr; // Managed by the scene graph, just clear the pointer } /*! @@ -666,7 +666,7 @@ QSGTextureProvider *QQuickPaintedItem::textureProvider() const QQuickWindow *w = window(); if (!w || !w->openglContext() || QThread::currentThread() != w->openglContext()->thread()) { qWarning("QQuickPaintedItem::textureProvider: can only be queried on the rendering thread of an exposed window"); - return 0; + return nullptr; } #endif if (!d->textureProvider) @@ -675,6 +675,10 @@ QSGTextureProvider *QQuickPaintedItem::textureProvider() const return d->textureProvider; } + +/*! + \reimp +*/ void QQuickPaintedItem::itemChange(ItemChange change, const ItemChangeData &value) { if (change == ItemDevicePixelRatioHasChanged) diff --git a/src/quick/items/qquickpainteditem.h b/src/quick/items/qquickpainteditem.h index 66a0ea83c9..b057f4295d 100644 --- a/src/quick/items/qquickpainteditem.h +++ b/src/quick/items/qquickpainteditem.h @@ -58,7 +58,7 @@ class Q_QUICK_EXPORT QQuickPaintedItem : public QQuickItem public: explicit QQuickPaintedItem(QQuickItem *parent = nullptr); - virtual ~QQuickPaintedItem(); + ~QQuickPaintedItem() override; enum RenderTarget { Image, diff --git a/src/quick/items/qquickpathview.cpp b/src/quick/items/qquickpathview.cpp index aac2b0296a..be94cdef42 100644 --- a/src/quick/items/qquickpathview.cpp +++ b/src/quick/items/qquickpathview.cpp @@ -66,7 +66,7 @@ const qreal MinimumFlickVelocity = 75.0; static QQmlOpenMetaObjectType *qPathViewAttachedType = nullptr; QQuickPathViewAttached::QQuickPathViewAttached(QObject *parent) -: QObject(parent), m_percent(-1), m_view(0), m_onPath(false), m_isCurrent(false) +: QObject(parent), m_percent(-1), m_view(nullptr), m_onPath(false), m_isCurrent(false) { if (qPathViewAttachedType) { m_metaobject = new QQmlOpenMetaObject(this, qPathViewAttachedType); @@ -129,7 +129,7 @@ QQuickItem *QQuickPathViewPrivate::getItem(int modelIndex, qreal z, bool async) requestedIndex = modelIndex; requestedZ = z; inRequest = true; - QObject *object = model->object(modelIndex, async); + QObject *object = model->object(modelIndex, async ? QQmlIncubator::Asynchronous : QQmlIncubator::AsynchronousIfNested); QQuickItem *item = qmlobject_cast<QQuickItem*>(object); if (!item) { if (object) { diff --git a/src/quick/items/qquickpincharea.cpp b/src/quick/items/qquickpincharea.cpp index 476acd3a3e..7ae0f9b7e3 100644 --- a/src/quick/items/qquickpincharea.cpp +++ b/src/quick/items/qquickpincharea.cpp @@ -151,7 +151,7 @@ QT_BEGIN_NAMESPACE */ QQuickPinch::QQuickPinch() - : m_target(0), m_minScale(1.0), m_maxScale(1.0) + : m_target(nullptr), m_minScale(1.0), m_maxScale(1.0) , m_minRotation(0.0), m_maxRotation(0.0) , m_axis(NoDrag), m_xmin(-FLT_MAX), m_xmax(FLT_MAX) , m_ymin(-FLT_MAX), m_ymax(FLT_MAX), m_active(false) @@ -644,7 +644,8 @@ bool QQuickPinchArea::childMouseEventFilter(QQuickItem *i, QEvent *e) return QQuickItem::childMouseEventFilter(i, e); switch (e->type()) { case QEvent::TouchBegin: - clearPinch(); // fall through + clearPinch(); + Q_FALLTHROUGH(); case QEvent::TouchUpdate: { QTouchEvent *touch = static_cast<QTouchEvent*>(e); d->touchPoints.clear(); diff --git a/src/quick/items/qquickpincharea_p.h b/src/quick/items/qquickpincharea_p.h index 2363f1e2d4..8eff53e6dc 100644 --- a/src/quick/items/qquickpincharea_p.h +++ b/src/quick/items/qquickpincharea_p.h @@ -84,7 +84,7 @@ public: void resetTarget() { if (!m_target) return; - m_target = 0; + m_target = nullptr; Q_EMIT targetChanged(); } @@ -270,7 +270,7 @@ class Q_AUTOTEST_EXPORT QQuickPinchArea : public QQuickItem Q_PROPERTY(QQuickPinch *pinch READ pinch CONSTANT) public: - QQuickPinchArea(QQuickItem *parent=0); + QQuickPinchArea(QQuickItem *parent=nullptr); ~QQuickPinchArea(); bool isEnabled() const; diff --git a/src/quick/items/qquickpositioners.cpp b/src/quick/items/qquickpositioners.cpp index e752e2538f..493db51666 100644 --- a/src/quick/items/qquickpositioners.cpp +++ b/src/quick/items/qquickpositioners.cpp @@ -69,7 +69,7 @@ void QQuickBasePositionerPrivate::unwatchChanges(QQuickItem* other) QQuickBasePositioner::PositionedItem::PositionedItem(QQuickItem *i) : item(i) - , transitionableItem(0) + , transitionableItem(nullptr) , index(-1) , isNew(false) , isVisible(true) @@ -203,7 +203,7 @@ void QQuickBasePositioner::setSpacing(qreal s) QQuickTransition *QQuickBasePositioner::populate() const { Q_D(const QQuickBasePositioner); - return d->transitioner ? d->transitioner->populateTransition : 0; + return d->transitioner ? d->transitioner->populateTransition : nullptr; } void QQuickBasePositioner::setPopulate(QQuickTransition *transition) @@ -220,7 +220,7 @@ void QQuickBasePositioner::setPopulate(QQuickTransition *transition) QQuickTransition *QQuickBasePositioner::move() const { Q_D(const QQuickBasePositioner); - return d->transitioner ? d->transitioner->displacedTransition : 0; + return d->transitioner ? d->transitioner->displacedTransition : nullptr; } void QQuickBasePositioner::setMove(QQuickTransition *mt) @@ -238,7 +238,7 @@ void QQuickBasePositioner::setMove(QQuickTransition *mt) QQuickTransition *QQuickBasePositioner::add() const { Q_D(const QQuickBasePositioner); - return d->transitioner ? d->transitioner->addTransition : 0; + return d->transitioner ? d->transitioner->addTransition : nullptr; } void QQuickBasePositioner::setAdd(QQuickTransition *add) @@ -460,15 +460,15 @@ void QQuickBasePositioner::updateAttachedProperties(QQuickPositionerAttached *sp // be changed to run only when there are attached properties present. This // could be a flag in the positioner that is set by the attached property // constructor. - QQuickPositionerAttached *prevLastProperty = 0; - QQuickPositionerAttached *lastProperty = 0; + QQuickPositionerAttached *prevLastProperty = nullptr; + QQuickPositionerAttached *lastProperty = nullptr; for (int ii = 0; ii < positionedItems.count(); ++ii) { const PositionedItem &child = positionedItems.at(ii); if (!child.item) continue; - QQuickPositionerAttached *property = 0; + QQuickPositionerAttached *property = nullptr; if (specificProperty) { if (specificPropertyOwner == child.item) { @@ -503,7 +503,7 @@ void QQuickBasePositioner::updateAttachedProperties(QQuickPositionerAttached *sp if (!child.item) continue; - QQuickPositionerAttached *property = 0; + QQuickPositionerAttached *property = nullptr; if (specificProperty) { if (specificPropertyOwner == child.item) { diff --git a/src/quick/items/qquickpositioners_p.h b/src/quick/items/qquickpositioners_p.h index ce583aefe8..94a737e1f1 100644 --- a/src/quick/items/qquickpositioners_p.h +++ b/src/quick/items/qquickpositioners_p.h @@ -132,7 +132,7 @@ public: static QQuickPositionerAttached *qmlAttachedProperties(QObject *obj); - void updateAttachedProperties(QQuickPositionerAttached *specificProperty = 0, QQuickItem *specificPropertyOwner = 0) const; + void updateAttachedProperties(QQuickPositionerAttached *specificProperty = nullptr, QQuickItem *specificPropertyOwner = nullptr) const; qreal padding() const; void setPadding(qreal padding); @@ -231,7 +231,7 @@ class Q_AUTOTEST_EXPORT QQuickColumn : public QQuickBasePositioner { Q_OBJECT public: - QQuickColumn(QQuickItem *parent=0); + QQuickColumn(QQuickItem *parent=nullptr); protected: void doPositioning(QSizeF *contentSize) override; @@ -247,7 +247,7 @@ class Q_AUTOTEST_EXPORT QQuickRow: public QQuickBasePositioner Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection NOTIFY layoutDirectionChanged) Q_PROPERTY(Qt::LayoutDirection effectiveLayoutDirection READ effectiveLayoutDirection NOTIFY effectiveLayoutDirectionChanged) public: - QQuickRow(QQuickItem *parent=0); + QQuickRow(QQuickItem *parent=nullptr); Qt::LayoutDirection layoutDirection() const; void setLayoutDirection (Qt::LayoutDirection); @@ -281,7 +281,7 @@ class Q_AUTOTEST_EXPORT QQuickGrid : public QQuickBasePositioner Q_PROPERTY(VAlignment verticalItemAlignment READ vItemAlign WRITE setVItemAlign NOTIFY verticalAlignmentChanged REVISION 1) public: - QQuickGrid(QQuickItem *parent=0); + QQuickGrid(QQuickItem *parent=nullptr); int rows() const { return m_rows; } void setRows(const int rows); @@ -360,7 +360,7 @@ class Q_AUTOTEST_EXPORT QQuickFlow: public QQuickBasePositioner Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection NOTIFY layoutDirectionChanged) Q_PROPERTY(Qt::LayoutDirection effectiveLayoutDirection READ effectiveLayoutDirection NOTIFY effectiveLayoutDirectionChanged) public: - QQuickFlow(QQuickItem *parent=0); + QQuickFlow(QQuickItem *parent=nullptr); enum Flow { LeftToRight, TopToBottom }; Q_ENUM(Flow) diff --git a/src/quick/items/qquickrectangle.cpp b/src/quick/items/qquickrectangle.cpp index 9308553a79..3895f59ae1 100644 --- a/src/quick/items/qquickrectangle.cpp +++ b/src/quick/items/qquickrectangle.cpp @@ -414,7 +414,7 @@ void QQuickRectangle::setGradient(QQuickGradient *gradient) void QQuickRectangle::resetGradient() { - setGradient(0); + setGradient(nullptr); } /*! @@ -489,7 +489,7 @@ QSGNode *QQuickRectangle::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData if (width() <= 0 || height() <= 0 || (d->color.alpha() == 0 && (!d->pen || d->pen->width() == 0 || d->pen->color().alpha() == 0))) { delete oldNode; - return 0; + return nullptr; } QSGInternalRectangleNode *rectangle = static_cast<QSGInternalRectangleNode *>(oldNode); diff --git a/src/quick/items/qquickrectangle_p.h b/src/quick/items/qquickrectangle_p.h index 52f0bc975b..c07ad835fb 100644 --- a/src/quick/items/qquickrectangle_p.h +++ b/src/quick/items/qquickrectangle_p.h @@ -67,7 +67,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPen : public QObject Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY penChanged) Q_PROPERTY(bool pixelAligned READ pixelAligned WRITE setPixelAligned NOTIFY penChanged) public: - QQuickPen(QObject *parent=0); + QQuickPen(QObject *parent=nullptr); qreal width() const; void setWidth(qreal w); @@ -98,7 +98,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickGradientStop : public QObject Q_PROPERTY(QColor color READ color WRITE setColor) public: - QQuickGradientStop(QObject *parent=0); + QQuickGradientStop(QObject *parent=nullptr); qreal position() const; void setPosition(qreal position); @@ -122,8 +122,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickGradient : public QObject Q_CLASSINFO("DefaultProperty", "stops") public: - QQuickGradient(QObject *parent=0); - ~QQuickGradient(); + QQuickGradient(QObject *parent=nullptr); + ~QQuickGradient() override; QQmlListProperty<QQuickGradientStop> stops(); @@ -151,7 +151,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickRectangle : public QQuickItem Q_PROPERTY(QQuickPen * border READ border CONSTANT) Q_PROPERTY(qreal radius READ radius WRITE setRadius NOTIFY radiusChanged) public: - QQuickRectangle(QQuickItem *parent=0); + QQuickRectangle(QQuickItem *parent=nullptr); QColor color() const; void setColor(const QColor &); diff --git a/src/quick/items/qquickrendercontrol.cpp b/src/quick/items/qquickrendercontrol.cpp index 58b76fa862..49568db552 100644 --- a/src/quick/items/qquickrendercontrol.cpp +++ b/src/quick/items/qquickrendercontrol.cpp @@ -133,11 +133,11 @@ extern Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_ \inmodule QtQuick */ -QSGContext *QQuickRenderControlPrivate::sg = 0; +QSGContext *QQuickRenderControlPrivate::sg = nullptr; QQuickRenderControlPrivate::QQuickRenderControlPrivate() : initialized(0), - window(0) + window(nullptr) { if (!sg) { qAddPostRoutine(cleanup); @@ -149,7 +149,7 @@ QQuickRenderControlPrivate::QQuickRenderControlPrivate() void QQuickRenderControlPrivate::cleanup() { delete sg; - sg = 0; + sg = nullptr; } /*! @@ -173,7 +173,7 @@ QQuickRenderControl::~QQuickRenderControl() invalidate(); if (d->window) - QQuickWindowPrivate::get(d->window)->renderControl = 0; + QQuickWindowPrivate::get(d->window)->renderControl = nullptr; // It is likely that the cleanup in windowDestroyed() is not called since // the standard pattern is to destroy the rendercontrol before the QQuickWindow. @@ -187,16 +187,16 @@ void QQuickRenderControlPrivate::windowDestroyed() { if (window) { rc->invalidate(); - QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); + QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete); delete QQuickWindowPrivate::get(window)->animationController; - QQuickWindowPrivate::get(window)->animationController = 0; + QQuickWindowPrivate::get(window)->animationController = nullptr; #if QT_CONFIG(quick_shadereffect) && QT_CONFIG(opengl) QQuickOpenGLShaderEffectMaterial::cleanupMaterialCache(); #endif - window = 0; + window = nullptr; } } @@ -452,11 +452,11 @@ void QQuickRenderControlPrivate::maybeUpdate() QWindow *QQuickRenderControl::renderWindowFor(QQuickWindow *win, QPoint *offset) { if (!win) - return 0; + return nullptr; QQuickRenderControl *rc = QQuickWindowPrivate::get(win)->renderControl; if (rc) return rc->renderWindow(offset); - return 0; + return nullptr; } QT_END_NAMESPACE diff --git a/src/quick/items/qquickrendercontrol.h b/src/quick/items/qquickrendercontrol.h index a626216f84..8ec9b8aafc 100644 --- a/src/quick/items/qquickrendercontrol.h +++ b/src/quick/items/qquickrendercontrol.h @@ -56,7 +56,7 @@ class Q_QUICK_EXPORT QQuickRenderControl : public QObject public: explicit QQuickRenderControl(QObject *parent = nullptr); - ~QQuickRenderControl(); + ~QQuickRenderControl() override; void prepareThread(QThread *targetThread); void initialize(QOpenGLContext *gl); diff --git a/src/quick/items/qquickrepeater.cpp b/src/quick/items/qquickrepeater.cpp index 6fc4c0553a..b95fa3c410 100644 --- a/src/quick/items/qquickrepeater.cpp +++ b/src/quick/items/qquickrepeater.cpp @@ -50,7 +50,7 @@ QT_BEGIN_NAMESPACE QQuickRepeaterPrivate::QQuickRepeaterPrivate() - : model(0) + : model(nullptr) , ownModel(false) , dataSourceIsObject(false) , delegateValidated(false) @@ -216,8 +216,8 @@ void QQuickRepeater::setModel(const QVariant &m) d->dataSource = model; QObject *object = qvariant_cast<QObject*>(model); d->dataSourceAsObject = object; - d->dataSourceIsObject = object != 0; - QQmlInstanceModel *vim = 0; + d->dataSourceIsObject = object != nullptr; + QQmlInstanceModel *vim = nullptr; if (object && (vim = qobject_cast<QQmlInstanceModel *>(object))) { if (d->ownModel) { delete d->model; @@ -288,7 +288,7 @@ QQmlComponent *QQuickRepeater::delegate() const return dataModel->delegate(); } - return 0; + return nullptr; } void QQuickRepeater::setDelegate(QQmlComponent *delegate) @@ -339,7 +339,7 @@ QQuickItem *QQuickRepeater::itemAt(int index) const Q_D(const QQuickRepeater); if (index >= 0 && index < d->deletables.count()) return d->deletables[index]; - return 0; + return nullptr; } void QQuickRepeater::componentComplete() @@ -374,9 +374,12 @@ void QQuickRepeater::clear() if (complete) emit itemRemoved(i, item); d->model->release(item); - item->setParentItem(0); } } + for (QQuickItem *item : qAsConst(d->deletables)) { + if (item) + item->setParentItem(nullptr); + } } d->deletables.clear(); d->itemCount = 0; @@ -401,7 +404,7 @@ void QQuickRepeater::regenerate() void QQuickRepeaterPrivate::requestItems() { for (int i = 0; i < itemCount; i++) { - QObject *object = model->object(i, false); + QObject *object = model->object(i, QQmlIncubator::AsynchronousIfNested); if (object) model->release(object); } @@ -410,7 +413,7 @@ void QQuickRepeaterPrivate::requestItems() void QQuickRepeater::createdItem(int index, QObject *) { Q_D(QQuickRepeater); - QObject *object = d->model->object(index, false); + QObject *object = d->model->object(index, QQmlIncubator::AsynchronousIfNested); QQuickItem *item = qmlobject_cast<QQuickItem*>(object); emit itemAdded(index, item); } @@ -479,7 +482,7 @@ void QQuickRepeater::modelUpdated(const QQmlChangeSet &changeSet, bool reset) emit itemRemoved(index, item); if (item) { d->model->release(item); - item->setParentItem(0); + item->setParentItem(nullptr); } --d->itemCount; } @@ -495,13 +498,20 @@ void QQuickRepeater::modelUpdated(const QQmlChangeSet &changeSet, bool reset) QQuickItem *stackBefore = index + items.count() < d->deletables.count() ? d->deletables.at(index + items.count()) : this; - for (int i = index; i < index + items.count(); ++i) - d->deletables.at(i)->stackBefore(stackBefore); + if (stackBefore) { + for (int i = index; i < index + items.count(); ++i) { + if (i < d->deletables.count()) { + QPointer<QQuickItem> item = d->deletables.at(i); + if (item) + item->stackBefore(stackBefore); + } + } + } } else for (int i = 0; i < insert.count; ++i) { int modelIndex = index + i; ++d->itemCount; - d->deletables.insert(modelIndex, 0); - QObject *object = d->model->object(modelIndex, false); + d->deletables.insert(modelIndex, nullptr); + QObject *object = d->model->object(modelIndex, QQmlIncubator::AsynchronousIfNested); if (object) d->model->release(object); } diff --git a/src/quick/items/qquickrepeater_p.h b/src/quick/items/qquickrepeater_p.h index b630999547..dbe3cd0c55 100644 --- a/src/quick/items/qquickrepeater_p.h +++ b/src/quick/items/qquickrepeater_p.h @@ -53,6 +53,10 @@ #include "qquickitem.h" +#include <private/qtquickglobal_p.h> + +QT_REQUIRE_CONFIG(quick_repeater); + QT_BEGIN_NAMESPACE class QQmlChangeSet; @@ -68,7 +72,7 @@ class Q_AUTOTEST_EXPORT QQuickRepeater : public QQuickItem Q_CLASSINFO("DefaultProperty", "delegate") public: - QQuickRepeater(QQuickItem *parent=0); + QQuickRepeater(QQuickItem *parent=nullptr); virtual ~QQuickRepeater(); QVariant model() const; diff --git a/src/quick/items/qquickrepeater_p_p.h b/src/quick/items/qquickrepeater_p_p.h index 64380688c9..942f428904 100644 --- a/src/quick/items/qquickrepeater_p_p.h +++ b/src/quick/items/qquickrepeater_p_p.h @@ -56,6 +56,8 @@ #include <QtCore/qpointer.h> +QT_REQUIRE_CONFIG(quick_repeater); + QT_BEGIN_NAMESPACE class QQmlContext; diff --git a/src/quick/items/qquickscalegrid_p_p.h b/src/quick/items/qquickscalegrid_p_p.h index 7f6a31a7bd..5752f61e3f 100644 --- a/src/quick/items/qquickscalegrid_p_p.h +++ b/src/quick/items/qquickscalegrid_p_p.h @@ -71,7 +71,7 @@ class Q_AUTOTEST_EXPORT QQuickScaleGrid : public QObject Q_PROPERTY(int bottom READ bottom WRITE setBottom NOTIFY borderChanged) public: - QQuickScaleGrid(QObject *parent=0); + QQuickScaleGrid(QObject *parent=nullptr); ~QQuickScaleGrid(); bool isNull() const; diff --git a/src/quick/items/qquickscreen.cpp b/src/quick/items/qquickscreen.cpp index 6a3eab957e..aea7e44a65 100644 --- a/src/quick/items/qquickscreen.cpp +++ b/src/quick/items/qquickscreen.cpp @@ -423,8 +423,8 @@ QScreen *QQuickScreenInfo::wrappedScreen() const QQuickScreenAttached::QQuickScreenAttached(QObject* attachee) : QQuickScreenInfo(attachee) - , m_window(NULL) - , m_updateMask(0) + , m_window(nullptr) + , m_updateMask(nullptr) , m_updateMaskSet(false) { m_attachee = qobject_cast<QQuickItem*>(attachee); @@ -475,7 +475,7 @@ void QQuickScreenAttached::windowChanged(QQuickWindow* c) if (m_window) disconnect(m_window, SIGNAL(screenChanged(QScreen*)), this, SLOT(screenChanged(QScreen*))); m_window = c; - screenChanged(c ? c->screen() : NULL); + screenChanged(c ? c->screen() : nullptr); if (c) connect(c, SIGNAL(screenChanged(QScreen*)), this, SLOT(screenChanged(QScreen*))); } diff --git a/src/quick/items/qquickshadereffect_p.h b/src/quick/items/qquickshadereffect_p.h index 30bd018098..cabad930fc 100644 --- a/src/quick/items/qquickshadereffect_p.h +++ b/src/quick/items/qquickshadereffect_p.h @@ -91,7 +91,7 @@ public: }; Q_ENUM(Status) - QQuickShaderEffect(QQuickItem *parent = 0); + QQuickShaderEffect(QQuickItem *parent = nullptr); QByteArray fragmentShader() const; void setFragmentShader(const QByteArray &code); diff --git a/src/quick/items/qquickshadereffectmesh_p.h b/src/quick/items/qquickshadereffectmesh_p.h index f3ac956f60..5d6641429a 100644 --- a/src/quick/items/qquickshadereffectmesh_p.h +++ b/src/quick/items/qquickshadereffectmesh_p.h @@ -76,7 +76,7 @@ class QQuickShaderEffectMesh : public QObject { Q_OBJECT public: - QQuickShaderEffectMesh(QObject *parent = 0); + QQuickShaderEffectMesh(QObject *parent = nullptr); virtual bool validateAttributes(const QVector<QByteArray> &attributes, int *posIndex) = 0; // If 'geometry' != 0, 'attrCount' is the same as last time the function was called. virtual QSGGeometry *updateGeometry(QSGGeometry *geometry, int attrCount, int posIndex, @@ -94,7 +94,7 @@ class QQuickGridMesh : public QQuickShaderEffectMesh Q_OBJECT Q_PROPERTY(QSize resolution READ resolution WRITE setResolution NOTIFY resolutionChanged) public: - QQuickGridMesh(QObject *parent = 0); + QQuickGridMesh(QObject *parent = nullptr); bool validateAttributes(const QVector<QByteArray> &attributes, int *posIndex) override; QSGGeometry *updateGeometry(QSGGeometry *geometry, int attrCount, int posIndex, const QRectF &srcRect, const QRectF &rect) override; @@ -121,7 +121,7 @@ class QQuickBorderImageMesh : public QQuickShaderEffectMesh Q_PROPERTY(TileMode horizontalTileMode READ horizontalTileMode WRITE setHorizontalTileMode NOTIFY horizontalTileModeChanged) Q_PROPERTY(TileMode verticalTileMode READ verticalTileMode WRITE setVerticalTileMode NOTIFY verticalTileModeChanged) public: - QQuickBorderImageMesh(QObject *parent = 0); + QQuickBorderImageMesh(QObject *parent = nullptr); bool validateAttributes(const QVector<QByteArray> &attributes, int *posIndex) override; QSGGeometry *updateGeometry(QSGGeometry *geometry, int attrCount, int posIndex, diff --git a/src/quick/items/qquickshadereffectsource.cpp b/src/quick/items/qquickshadereffectsource.cpp index b4a45431c5..4782672858 100644 --- a/src/quick/items/qquickshadereffectsource.cpp +++ b/src/quick/items/qquickshadereffectsource.cpp @@ -56,7 +56,7 @@ class QQuickShaderEffectSourceTextureProvider : public QSGTextureProvider Q_OBJECT public: QQuickShaderEffectSourceTextureProvider() - : sourceTexture(0) + : sourceTexture(nullptr) , mipmapFiltering(QSGTexture::None) , filtering(QSGTexture::Nearest) , horizontalWrap(QSGTexture::ClampToEdge) @@ -183,10 +183,10 @@ public: QQuickShaderEffectSource::QQuickShaderEffectSource(QQuickItem *parent) : QQuickItem(parent) - , m_provider(0) - , m_texture(0) + , m_provider(nullptr) + , m_texture(nullptr) , m_wrapMode(ClampToEdge) - , m_sourceItem(0) + , m_sourceItem(nullptr) , m_textureSize(0, 0) , m_format(RGBA) , m_samples(0) @@ -246,7 +246,7 @@ QSGTextureProvider *QQuickShaderEffectSource::textureProvider() const const QQuickItemPrivate *d = QQuickItemPrivate::get(this); if (!d->window || !d->sceneGraphRenderContext() || QThread::currentThread() != d->sceneGraphRenderContext()->thread()) { qWarning("QQuickShaderEffectSource::textureProvider: can only be queried on the rendering thread of an exposed window"); - return 0; + return nullptr; } if (!m_provider) { @@ -334,8 +334,8 @@ void QQuickShaderEffectSource::setSourceItem(QQuickItem *item) if (m_sourceItem) { if (window() == m_sourceItem->window() - || (window() == 0 && m_sourceItem->window()) - || (m_sourceItem->window() == 0 && window())) { + || (window() == nullptr && m_sourceItem->window()) + || (m_sourceItem->window() == nullptr && window())) { QQuickItemPrivate *d = QQuickItemPrivate::get(item); // 'item' needs a window to get a scene graph node. It usually gets one through its // parent, but if the source item is "inline" rather than a reference -- i.e. @@ -350,7 +350,7 @@ void QQuickShaderEffectSource::setSourceItem(QQuickItem *item) connect(m_sourceItem, SIGNAL(destroyed(QObject*)), this, SLOT(sourceItemDestroyed(QObject*))); } else { qWarning("ShaderEffectSource: sourceItem and ShaderEffectSource must both be children of the same window."); - m_sourceItem = 0; + m_sourceItem = nullptr; } } update(); @@ -361,7 +361,7 @@ void QQuickShaderEffectSource::sourceItemDestroyed(QObject *item) { Q_ASSERT(item == m_sourceItem); Q_UNUSED(item); - m_sourceItem = 0; + m_sourceItem = nullptr; update(); emit sourceItemChanged(); } @@ -662,8 +662,8 @@ void QQuickShaderEffectSource::releaseResources() if (m_texture || m_provider) { window()->scheduleRenderJob(new QQuickShaderEffectSourceCleanup(m_texture, m_provider), QQuickWindow::AfterSynchronizingStage); - m_texture = 0; - m_provider = 0; + m_texture = nullptr; + m_provider = nullptr; } } @@ -684,9 +684,9 @@ QSGNode *QQuickShaderEffectSource::updatePaintNode(QSGNode *oldNode, UpdatePaint { if (!m_sourceItem || m_sourceItem->width() <= 0 || m_sourceItem->height() <= 0) { if (m_texture) - m_texture->setItem(0); + m_texture->setItem(nullptr); delete oldNode; - return 0; + return nullptr; } ensureTexture(); @@ -745,7 +745,7 @@ QSGNode *QQuickShaderEffectSource::updatePaintNode(QSGNode *oldNode, UpdatePaint // Don't create the paint node if we're not spanning any area if (width() <= 0 || height() <= 0) { delete oldNode; - return 0; + return nullptr; } QSGInternalImageNode *node = static_cast<QSGInternalImageNode *>(oldNode); @@ -779,8 +779,8 @@ void QQuickShaderEffectSource::invalidateSceneGraph() delete m_texture; if (m_provider) delete m_provider; - m_texture = 0; - m_provider = 0; + m_texture = nullptr; + m_provider = nullptr; } void QQuickShaderEffectSource::itemChange(ItemChange change, const ItemChangeData &value) diff --git a/src/quick/items/qquickshadereffectsource_p.h b/src/quick/items/qquickshadereffectsource_p.h index 185c5179b6..d5bb33902a 100644 --- a/src/quick/items/qquickshadereffectsource_p.h +++ b/src/quick/items/qquickshadereffectsource_p.h @@ -113,8 +113,8 @@ public: }; Q_ENUM(TextureMirroring) - QQuickShaderEffectSource(QQuickItem *parent = 0); - ~QQuickShaderEffectSource(); + QQuickShaderEffectSource(QQuickItem *parent = nullptr); + ~QQuickShaderEffectSource() override; WrapMode wrapMode() const; void setWrapMode(WrapMode mode); diff --git a/src/quick/items/qquicksprite.cpp b/src/quick/items/qquicksprite.cpp index 8013c57938..99b1b1f430 100644 --- a/src/quick/items/qquicksprite.cpp +++ b/src/quick/items/qquicksprite.cpp @@ -100,7 +100,7 @@ QT_BEGIN_NAMESPACE /*! \qmlproperty int QtQuick::Sprite::frameDuration - Duration of each frame of the animation. Values below 0 are invalid. + Duration of each frame of the animation in milliseconds. Values below 0 are invalid. If frameRate is valid then it will be used to calculate the duration of the frames. If not, and frameDuration is valid, then frameDuration will be used. Otherwise duration is used. @@ -237,12 +237,12 @@ int QQuickSprite::variedDuration() const //Deals with precedence when multiple d if (m_frameRate != unsetDuration) { qreal fpms = (m_frameRate - + (m_frameRateVariation * QRandomGenerator::getReal() * 2) + + (m_frameRateVariation * QRandomGenerator::global()->generateDouble() * 2) - m_frameRateVariation) / 1000.0; return qMax(qreal(0.0) , m_frames / fpms); } else if (m_frameDuration != unsetDuration) { int mspf = m_frameDuration - + (m_frameDurationVariation * QRandomGenerator::getReal() * 2) + + (m_frameDurationVariation * QRandomGenerator::global()->generateDouble() * 2) - m_frameDurationVariation; return qMax(0, m_frames * mspf); } else if (duration() >= 0) { diff --git a/src/quick/items/qquicksprite_p.h b/src/quick/items/qquicksprite_p.h index 2f7f6da5c0..8e119a80a9 100644 --- a/src/quick/items/qquicksprite_p.h +++ b/src/quick/items/qquicksprite_p.h @@ -88,8 +88,8 @@ class Q_QUICK_EXPORT QQuickSprite : public QQuickStochasticState Q_PROPERTY(int frameDurationVariation READ frameDurationVariation WRITE setFrameDurationVariation NOTIFY frameDurationVariationChanged) public: - explicit QQuickSprite(QObject *parent = 0); - ~QQuickSprite(); + explicit QQuickSprite(QObject *parent = nullptr); + ~QQuickSprite() override; QUrl source() const { diff --git a/src/quick/items/qquickspriteengine.cpp b/src/quick/items/qquickspriteengine.cpp index 9deb223957..1fd15e61e3 100644 --- a/src/quick/items/qquickspriteengine.cpp +++ b/src/quick/items/qquickspriteengine.cpp @@ -544,7 +544,7 @@ void QQuickStochasticEngine::restart(int index) if (m_addAdvance) m_startTimes[index] += m_advanceTime.elapsed(); if (randomStart) - m_startTimes[index] -= QRandomGenerator::bounded(m_duration.at(index)); + m_startTimes[index] -= QRandomGenerator::global()->bounded(m_duration.at(index)); int time = m_duration.at(index) + m_startTimes.at(index); for (int i=0; i<m_stateUpdates.count(); i++) m_stateUpdates[i].second.removeAll(index); @@ -558,13 +558,13 @@ void QQuickSpriteEngine::restart(int index) //Reimplemented to recognize and han if (m_loaded && m_sprites.at(m_things.at(index))->frameSync()) {//Manually advanced m_startTimes[index] = 0; if (randomStart && m_sprites.at(m_things.at(index))->m_generatedCount) - m_startTimes[index] += QRandomGenerator::bounded(m_sprites.at(m_things.at(index))->m_generatedCount); + m_startTimes[index] += QRandomGenerator::global()->bounded(m_sprites.at(m_things.at(index))->m_generatedCount); } else { m_startTimes[index] = m_timeOffset; if (m_addAdvance) m_startTimes[index] += m_advanceTime.elapsed(); if (randomStart) - m_startTimes[index] -= QRandomGenerator::bounded(m_duration.at(index)); + m_startTimes[index] -= QRandomGenerator::global()->bounded(m_duration.at(index)); int time = spriteDuration(index) + m_startTimes.at(index); if (randomStart) { int curTime = m_timeOffset + (m_addAdvance ? m_advanceTime.elapsed() : 0); @@ -630,7 +630,7 @@ int QQuickStochasticEngine::nextState(int curState, int curThing) int nextIdx = -1; int goalPath = goalSeek(curState, curThing); if (goalPath == -1){//Random - qreal r = QRandomGenerator::getReal(); + qreal r = QRandomGenerator::global()->generateDouble(); qreal total = 0.0; for (QVariantMap::const_iterator iter=m_states.at(curState)->m_to.constBegin(); iter!=m_states.at(curState)->m_to.constEnd(); ++iter) @@ -720,7 +720,7 @@ int QQuickStochasticEngine::goalSeek(int curIdx, int spriteIdx, int dist) if (options.count()==1) return *(options.begin()); int option = -1; - qreal r = QRandomGenerator::getReal(); + qreal r = QRandomGenerator::global()->generateDouble(); qreal total = 0; for (QSet<int>::const_iterator iter=options.constBegin(); iter!=options.constEnd(); ++iter) diff --git a/src/quick/items/qquickspriteengine_p.h b/src/quick/items/qquickspriteengine_p.h index a1c156fa94..da917683b6 100644 --- a/src/quick/items/qquickspriteengine_p.h +++ b/src/quick/items/qquickspriteengine_p.h @@ -81,11 +81,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickStochasticState : public QObject //Currently Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) public: - QQuickStochasticState(QObject* parent = 0) + QQuickStochasticState(QObject* parent = nullptr) : QObject(parent) - , m_duration(-1) - , m_durationVariation(0) - , m_randomStart(false) { } @@ -113,7 +110,7 @@ public: virtual int variedDuration() const { return qMax(qreal(0.0) , m_duration - + (m_durationVariation * QRandomGenerator::bounded(2.0)) + + (m_durationVariation * QRandomGenerator::global()->bounded(2.0)) - m_durationVariation); } @@ -179,11 +176,11 @@ public Q_SLOTS: private: QString m_name; QVariantMap m_to; - int m_duration; - int m_durationVariation; + int m_duration = -1; + int m_durationVariation = 0; friend class QQuickStochasticEngine; - bool m_randomStart; + bool m_randomStart = false; }; class Q_QUICK_PRIVATE_EXPORT QQuickStochasticEngine : public QObject @@ -193,9 +190,9 @@ class Q_QUICK_PRIVATE_EXPORT QQuickStochasticEngine : public QObject Q_PROPERTY(QString globalGoal READ globalGoal WRITE setGlobalGoal NOTIFY globalGoalChanged) Q_PROPERTY(QQmlListProperty<QQuickStochasticState> states READ states) public: - explicit QQuickStochasticEngine(QObject *parent = 0); - QQuickStochasticEngine(const QList<QQuickStochasticState*> &states, QObject *parent = 0); - ~QQuickStochasticEngine(); + explicit QQuickStochasticEngine(QObject *parent = nullptr); + QQuickStochasticEngine(const QList<QQuickStochasticState*> &states, QObject *parent = nullptr); + ~QQuickStochasticEngine() override; QQmlListProperty<QQuickStochasticState> states() { @@ -270,9 +267,9 @@ class Q_QUICK_PRIVATE_EXPORT QQuickSpriteEngine : public QQuickStochasticEngine Q_OBJECT Q_PROPERTY(QQmlListProperty<QQuickSprite> sprites READ sprites) public: - explicit QQuickSpriteEngine(QObject *parent = 0); - QQuickSpriteEngine(const QList<QQuickSprite*> &sprites, QObject *parent = 0); - ~QQuickSpriteEngine(); + explicit QQuickSpriteEngine(QObject *parent = nullptr); + QQuickSpriteEngine(const QList<QQuickSprite*> &sprites, QObject *parent = nullptr); + ~QQuickSpriteEngine() override; QQmlListProperty<QQuickSprite> sprites() { return QQmlListProperty<QQuickSprite>(this, m_sprites); @@ -303,7 +300,7 @@ public: QImage assembledImage(int maxSize = 2048); private: - int pseudospriteProgress(int, int, int *rd = 0) const; + int pseudospriteProgress(int, int, int *rd = nullptr) const; QList<QQuickSprite*> m_sprites; bool m_startedImageAssembly; bool m_loaded; diff --git a/src/quick/items/qquickspritesequence.cpp b/src/quick/items/qquickspritesequence.cpp index ae466aa482..0a39c09ebc 100644 --- a/src/quick/items/qquickspritesequence.cpp +++ b/src/quick/items/qquickspritesequence.cpp @@ -199,7 +199,7 @@ void QQuickSpriteSequence::createEngine() if (!d->m_goalState.isEmpty()) d->m_spriteEngine->setGoal(d->m_spriteEngine->stateIndex(d->m_goalState)); } else { - d->m_spriteEngine = 0; + d->m_spriteEngine = nullptr; } reset(); } diff --git a/src/quick/items/qquickspritesequence_p.h b/src/quick/items/qquickspritesequence_p.h index ffcefecaec..899ce79e0e 100644 --- a/src/quick/items/qquickspritesequence_p.h +++ b/src/quick/items/qquickspritesequence_p.h @@ -77,7 +77,7 @@ class Q_AUTOTEST_EXPORT QQuickSpriteSequence : public QQuickItem Q_CLASSINFO("DefaultProperty", "sprites") public: - explicit QQuickSpriteSequence(QQuickItem *parent = 0); + explicit QQuickSpriteSequence(QQuickItem *parent = nullptr); QQmlListProperty<QQuickSprite> sprites(); diff --git a/src/quick/items/qquickstateoperations.cpp b/src/quick/items/qquickstateoperations.cpp index 386bb058b5..a85b9663d3 100644 --- a/src/quick/items/qquickstateoperations.cpp +++ b/src/quick/items/qquickstateoperations.cpp @@ -51,8 +51,8 @@ class QQuickParentChangePrivate : public QQuickStateOperationPrivate { Q_DECLARE_PUBLIC(QQuickParentChange) public: - QQuickParentChangePrivate() : target(0), parent(0), origParent(0), origStackBefore(0), - rewindParent(0), rewindStackBefore(0) {} + QQuickParentChangePrivate() : target(nullptr), parent(nullptr), origParent(nullptr), origStackBefore(nullptr), + rewindParent(nullptr), rewindStackBefore(nullptr) {} QQuickItem *target; QPointer<QQuickItem> parent; @@ -68,7 +68,7 @@ public: QQmlNullableValue<QQmlScriptString> scaleString; QQmlNullableValue<QQmlScriptString> rotationString; - void doChange(QQuickItem *targetParent, QQuickItem *stackBefore = 0); + void doChange(QQuickItem *targetParent, QQuickItem *stackBefore = nullptr); }; void QQuickParentChangePrivate::doChange(QQuickItem *targetParent, QQuickItem *stackBefore) @@ -524,13 +524,13 @@ void QQuickParentChange::saveCurrentValues() { Q_D(QQuickParentChange); if (!d->target) { - d->rewindParent = 0; - d->rewindStackBefore = 0; + d->rewindParent = nullptr; + d->rewindStackBefore = nullptr; return; } d->rewindParent = d->target->parentItem(); - d->rewindStackBefore = 0; + d->rewindStackBefore = nullptr; if (!d->rewindParent) return; @@ -588,7 +588,7 @@ class QQuickAnchorSetPrivate : public QObjectPrivate Q_DECLARE_PUBLIC(QQuickAnchorSet) public: QQuickAnchorSetPrivate() - : usedAnchors(0), resetAnchors(0) + : usedAnchors(nullptr), resetAnchors(nullptr) { } @@ -771,7 +771,7 @@ class QQuickAnchorChangesPrivate : public QQuickStateOperationPrivate { public: QQuickAnchorChangesPrivate() - : target(0), anchorSet(new QQuickAnchorSet) + : target(nullptr), anchorSet(new QQuickAnchorSet) { } @@ -855,7 +855,7 @@ QQuickAnchorChanges::ActionList QQuickAnchorChanges::actions() Q_D(QQuickAnchorChanges); //### ASSERT these are all 0? d->leftBinding = d->rightBinding = d->hCenterBinding = d->topBinding - = d->bottomBinding = d->vCenterBinding = d->baselineBinding = 0; + = d->bottomBinding = d->vCenterBinding = d->baselineBinding = nullptr; d->leftProp = QQmlProperty(d->target, QLatin1String("anchors.left")); d->rightProp = QQmlProperty(d->target, QLatin1String("anchors.right")); @@ -1236,20 +1236,20 @@ void QQuickAnchorChanges::copyOriginals(QQuickStateActionEvent *other) //clear old values from other //### could this be generalized for all QQuickStateActionEvents, and called after copyOriginals? - acp->leftBinding = 0; - acp->rightBinding = 0; - acp->hCenterBinding = 0; - acp->topBinding = 0; - acp->bottomBinding = 0; - acp->vCenterBinding = 0; - acp->baselineBinding = 0; - acp->origLeftBinding = 0; - acp->origRightBinding = 0; - acp->origHCenterBinding = 0; - acp->origTopBinding = 0; - acp->origBottomBinding = 0; - acp->origVCenterBinding = 0; - acp->origBaselineBinding = 0; + acp->leftBinding = nullptr; + acp->rightBinding = nullptr; + acp->hCenterBinding = nullptr; + acp->topBinding = nullptr; + acp->bottomBinding = nullptr; + acp->vCenterBinding = nullptr; + acp->baselineBinding = nullptr; + acp->origLeftBinding = nullptr; + acp->origRightBinding = nullptr; + acp->origHCenterBinding = nullptr; + acp->origTopBinding = nullptr; + acp->origBottomBinding = nullptr; + acp->origVCenterBinding = nullptr; + acp->origBaselineBinding = nullptr; saveCurrentValues(); } diff --git a/src/quick/items/qquickstateoperations_p.h b/src/quick/items/qquickstateoperations_p.h index d61ed294cb..e947b2213f 100644 --- a/src/quick/items/qquickstateoperations_p.h +++ b/src/quick/items/qquickstateoperations_p.h @@ -75,7 +75,7 @@ class Q_AUTOTEST_EXPORT QQuickParentChange : public QQuickStateOperation, public Q_PROPERTY(QQmlScriptString scale READ scale WRITE setScale) Q_PROPERTY(QQmlScriptString rotation READ rotation WRITE setRotation) public: - QQuickParentChange(QObject *parent=0); + QQuickParentChange(QObject *parent=nullptr); ~QQuickParentChange(); QQuickItem *object() const; @@ -138,7 +138,7 @@ class Q_AUTOTEST_EXPORT QQuickAnchorSet : public QObject Q_PROPERTY(QQmlScriptString baseline READ baseline WRITE setBaseline RESET resetBaseline) public: - QQuickAnchorSet(QObject *parent=0); + QQuickAnchorSet(QObject *parent=nullptr); virtual ~QQuickAnchorSet(); QQmlScriptString left() const; @@ -187,7 +187,7 @@ class Q_AUTOTEST_EXPORT QQuickAnchorChanges : public QQuickStateOperation, publi Q_PROPERTY(QQuickAnchorSet *anchors READ anchors CONSTANT) public: - QQuickAnchorChanges(QObject *parent=0); + QQuickAnchorChanges(QObject *parent=nullptr); ~QQuickAnchorChanges(); ActionList actions() override; diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp index 5f58f0cdde..383aa2b821 100644 --- a/src/quick/items/qquicktext.cpp +++ b/src/quick/items/qquicktext.cpp @@ -74,7 +74,7 @@ Q_DECLARE_LOGGING_CATEGORY(DBG_HOVER_TRACE) const QChar QQuickTextPrivate::elideChar = QChar(0x2026); QQuickTextPrivate::QQuickTextPrivate() - : fontInfo(font), elideLayout(0), textLine(0), lineWidth(0) + : fontInfo(font), elideLayout(nullptr), textLine(nullptr), lineWidth(0) , color(0xFF000000), linkColor(0xFF0000FF), styleColor(0xFF000000) , lineCount(1), multilengthEos(-1) , elideMode(QQuickText::ElideNone), hAlign(QQuickText::AlignLeft), vAlign(QQuickText::AlignTop) @@ -103,7 +103,7 @@ QQuickTextPrivate::ExtraData::ExtraData() , explicitRightPadding(false) , explicitBottomPadding(false) , lineHeight(1.0) - , doc(0) + , doc(nullptr) , minimumPixelSize(12) , minimumPointSize(12) , nbActiveDownloads(0) @@ -124,7 +124,7 @@ void QQuickTextPrivate::init() QQuickTextPrivate::~QQuickTextPrivate() { delete elideLayout; - delete textLine; textLine = 0; + delete textLine; textLine = nullptr; if (extra.isAllocated()) { qDeleteAll(extra->imgTags); @@ -478,7 +478,7 @@ void QQuickTextPrivate::updateSize() } QQuickTextLine::QQuickTextLine() - : QObject(), m_line(0), m_height(0), m_lineOffset(0) + : QObject(), m_line(nullptr), m_height(0), m_lineOffset(0) { } @@ -1110,7 +1110,7 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const baseline) layout.clearLayout(); } else { delete elideLayout; - elideLayout = 0; + elideLayout = nullptr; } QTextLine firstLine = visibleCount == 1 && elideLayout @@ -1507,9 +1507,9 @@ QQuickText::~QQuickText() \qmlproperty bool QtQuick::Text::font.kerning \since 5.10 - Enables or disables the kerning OpenType feature when shaping the text. This may improve performance - when creating or changing the text, at the expense of some cosmetic features. The default value - is true. + Enables or disables the kerning OpenType feature when shaping the text. Disabling this may + improve performance when creating or changing the text, at the expense of some cosmetic + features. The default value is true. \qml Text { text: "OATS FLAVOUR WAY"; font.kerning: false } @@ -2363,10 +2363,10 @@ QSGNode *QQuickText::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data if (d->text.isEmpty()) { delete oldNode; - return 0; + return nullptr; } - if (d->updateType != QQuickTextPrivate::UpdatePaintNode && oldNode != 0) { + if (d->updateType != QQuickTextPrivate::UpdatePaintNode && oldNode != nullptr) { // Update done in preprocess() in the nodes d->updateType = QQuickTextPrivate::UpdateNone; return oldNode; @@ -2376,7 +2376,7 @@ QSGNode *QQuickText::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data const qreal dy = QQuickTextUtil::alignedY(d->layedOutTextRect.height() + d->lineHeightOffset(), d->availableHeight(), d->vAlign) + topPadding(); - QQuickTextNode *node = 0; + QQuickTextNode *node = nullptr; if (!oldNode) node = new QQuickTextNode(this); else @@ -2918,14 +2918,14 @@ void QQuickText::invalidateFontCaches() { Q_D(QQuickText); - if (d->richText && d->extra.isAllocated() && d->extra->doc != 0) { + if (d->richText && d->extra.isAllocated() && d->extra->doc != nullptr) { QTextBlock block; for (block = d->extra->doc->firstBlock(); block.isValid(); block = block.next()) { - if (block.layout() != 0 && block.layout()->engine() != 0) + if (block.layout() != nullptr && block.layout()->engine() != nullptr) block.layout()->engine()->resetFontEngineCache(); } } else { - if (d->layout.engine() != 0) + if (d->layout.engine() != nullptr) d->layout.engine()->resetFontEngineCache(); } } diff --git a/src/quick/items/qquicktext_p.h b/src/quick/items/qquicktext_p.h index 6c48dd86a9..15e989c13d 100644 --- a/src/quick/items/qquicktext_p.h +++ b/src/quick/items/qquicktext_p.h @@ -102,8 +102,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickText : public QQuickImplicitSizeItem Q_PROPERTY(QSizeF advance READ advance NOTIFY contentSizeChanged REVISION 10) public: - QQuickText(QQuickItem *parent=0); - ~QQuickText(); + QQuickText(QQuickItem *parent=nullptr); + ~QQuickText() override; enum HAlignment { AlignLeft = Qt::AlignLeft, AlignRight = Qt::AlignRight, @@ -289,7 +289,7 @@ Q_SIGNALS: Q_REVISION(9) void fontInfoChanged(); protected: - QQuickText(QQuickTextPrivate &dd, QQuickItem *parent = 0); + QQuickText(QQuickTextPrivate &dd, QQuickItem *parent = nullptr); void mousePressEvent(QMouseEvent *event) override; void mouseReleaseEvent(QMouseEvent *event) override; diff --git a/src/quick/items/qquicktext_p_p.h b/src/quick/items/qquicktext_p_p.h index 6fd0876a5f..b0b1492d57 100644 --- a/src/quick/items/qquicktext_p_p.h +++ b/src/quick/items/qquicktext_p_p.h @@ -83,7 +83,7 @@ public: void setLineGeometry(QTextLine &line, qreal lineWidth, qreal &height); int lineHeightOffset() const; - QString elidedText(qreal lineWidth, const QTextLine &line, QTextLine *nextLine = 0) const; + QString elidedText(qreal lineWidth, const QTextLine &line, QTextLine *nextLine = nullptr) const; void elideFormats(int start, int length, int offset, QVector<QTextLayout::FormatRange> *elidedFormats); void clearFormats(); diff --git a/src/quick/items/qquicktextcontrol.cpp b/src/quick/items/qquicktextcontrol.cpp index 874c02fc99..e3080dfe48 100644 --- a/src/quick/items/qquicktextcontrol.cpp +++ b/src/quick/items/qquicktextcontrol.cpp @@ -95,7 +95,7 @@ static QTextLine currentTextLine(const QTextCursor &cursor) } QQuickTextControlPrivate::QQuickTextControlPrivate() - : doc(0), + : doc(nullptr), #if QT_CONFIG(im) preeditCursor(0), #endif diff --git a/src/quick/items/qquicktextcontrol_p.h b/src/quick/items/qquicktextcontrol_p.h index 862a81af28..c99736a874 100644 --- a/src/quick/items/qquicktextcontrol_p.h +++ b/src/quick/items/qquicktextcontrol_p.h @@ -77,7 +77,7 @@ class Q_AUTOTEST_EXPORT QQuickTextControl : public QInputControl Q_OBJECT Q_DECLARE_PRIVATE(QQuickTextControl) public: - explicit QQuickTextControl(QTextDocument *doc, QObject *parent = 0); + explicit QQuickTextControl(QTextDocument *doc, QObject *parent = nullptr); virtual ~QQuickTextControl(); QTextDocument *document() const; diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp index 8f3a8998f5..352fc48970 100644 --- a/src/quick/items/qquicktextedit.cpp +++ b/src/quick/items/qquicktextedit.cpp @@ -139,7 +139,7 @@ namespace { class RootNode : public QSGTransformNode { public: - RootNode() : cursorNode(0), frameDecorationsNode(0) + RootNode() : cursorNode(nullptr), frameDecorationsNode(nullptr) { } void resetFrameDecorations(QQuickTextNode* newNode) @@ -358,9 +358,9 @@ QString QQuickTextEdit::text() const \qmlproperty bool QtQuick::TextEdit::font.kerning \since 5.10 - Enables or disables the kerning OpenType feature when shaping the text. This may improve performance - when creating or changing the text, at the expense of some cosmetic features. The default value - is true. + Enables or disables the kerning OpenType feature when shaping the text. Disabling this may + improve performance when creating or changing the text, at the expense of some cosmetic + features. The default value is true. \qml TextEdit { text: "OATS FLAVOUR WAY"; kerning: font.false } @@ -1968,12 +1968,11 @@ void QQuickTextEdit::triggerPreprocess() } typedef QQuickTextEditPrivate::Node TextNode; -typedef QList<TextNode*>::iterator TextNodeIterator; +using TextNodeIterator = QQuickTextEditPrivate::TextNodeIterator; - -static bool comesBefore(TextNode* n1, TextNode* n2) +static inline bool operator<(const TextNode &n1, const TextNode &n2) { - return n1->startPos() < n2->startPos(); + return n1.startPos() < n2.startPos(); } static inline void updateNodeTransform(QQuickTextNode* node, const QPointF &topLeft) @@ -1992,12 +1991,12 @@ static inline void updateNodeTransform(QQuickTextNode* node, const QPointF &topL void QQuickTextEdit::invalidateFontCaches() { Q_D(QQuickTextEdit); - if (d->document == 0) + if (d->document == nullptr) return; QTextBlock block; for (block = d->document->firstBlock(); block.isValid(); block = block.next()) { - if (block.layout() != 0 && block.layout()->engine() != 0) + if (block.layout() != nullptr && block.layout()->engine() != nullptr) block.layout()->engine()->resetFontEngineCache(); } } @@ -2015,7 +2014,7 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData * Q_UNUSED(updatePaintNodeData); Q_D(QQuickTextEdit); - if (d->updateType != QQuickTextEditPrivate::UpdatePaintNode && oldNode != 0) { + if (d->updateType != QQuickTextEditPrivate::UpdatePaintNode && oldNode != nullptr) { // Update done in preprocess() in the nodes d->updateType = QQuickTextEditPrivate::UpdateNone; return oldNode; @@ -2026,13 +2025,12 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData * if (!oldNode) { // If we had any QQuickTextNode node references, they were deleted along with the root node // But here we must delete the Node structures in textNodeMap - qDeleteAll(d->textNodeMap); d->textNodeMap.clear(); } RootNode *rootNode = static_cast<RootNode *>(oldNode); TextNodeIterator nodeIterator = d->textNodeMap.begin(); - while (nodeIterator != d->textNodeMap.end() && !(*nodeIterator)->dirty()) + while (nodeIterator != d->textNodeMap.end() && !nodeIterator->dirty()) ++nodeIterator; QQuickTextNodeEngine engine; @@ -2045,20 +2043,19 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData * int firstDirtyPos = 0; if (nodeIterator != d->textNodeMap.end()) { - firstDirtyPos = (*nodeIterator)->startPos(); + firstDirtyPos = nodeIterator->startPos(); do { - rootNode->removeChildNode((*nodeIterator)->textNode()); - delete (*nodeIterator)->textNode(); - delete *nodeIterator; + rootNode->removeChildNode(nodeIterator->textNode()); + delete nodeIterator->textNode(); nodeIterator = d->textNodeMap.erase(nodeIterator); - } while (nodeIterator != d->textNodeMap.end() && (*nodeIterator)->dirty()); + } while (nodeIterator != d->textNodeMap.end() && nodeIterator->dirty()); } // FIXME: the text decorations could probably be handled separately (only updated for affected textFrames) rootNode->resetFrameDecorations(d->createTextNode()); resetEngine(&frameDecorationsEngine, d->color, d->selectedTextColor, d->selectionColor); - QQuickTextNode *node = 0; + QQuickTextNode *node = nullptr; int currentNodeSize = 0; int nodeStart = firstDirtyPos; @@ -2068,7 +2065,8 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData * rootNode->setMatrix(basePositionMatrix); QPointF nodeOffset; - TextNode *firstCleanNode = (nodeIterator != d->textNodeMap.end()) ? *nodeIterator : 0; + const TextNode firstCleanNode = (nodeIterator != d->textNodeMap.end()) ? *nodeIterator + : TextNode(); QList<QTextFrame *> frames; frames.append(d->document->rootFrame()); @@ -2078,7 +2076,8 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData * frames.append(textFrame->childFrames()); frameDecorationsEngine.addFrameDecorations(d->document, textFrame); - if (textFrame->lastPosition() < firstDirtyPos || (firstCleanNode && textFrame->firstPosition() >= firstCleanNode->startPos())) + if (textFrame->lastPosition() < firstDirtyPos + || textFrame->firstPosition() >= firstCleanNode.startPos()) continue; node = d->createTextNode(); resetEngine(&engine, d->color, d->selectedTextColor, d->selectionColor); @@ -2118,8 +2117,8 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData * engine.addTextBlock(d->document, block, -nodeOffset, d->color, QColor(), selectionStart(), selectionEnd() - 1); currentNodeSize += block.length(); - if ((it.atEnd()) || (firstCleanNode && block.next().position() >= firstCleanNode->startPos())) // last node that needed replacing or last block of the frame - break; + if ((it.atEnd()) || block.next().position() >= firstCleanNode.startPos()) + break; // last node that needed replacing or last block of the frame QList<int>::const_iterator lowerBound = std::lower_bound(frameBoundaries.constBegin(), frameBoundaries.constEnd(), block.next().position()); if (currentNodeSize > nodeBreakingSize || lowerBound == frameBoundaries.constEnd() || *lowerBound > nodeStart) { @@ -2137,16 +2136,19 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData * // Now prepend the frame decorations since we want them rendered first, with the text nodes and cursor in front. rootNode->prependChildNode(rootNode->frameDecorationsNode); - Q_ASSERT(nodeIterator == d->textNodeMap.end() || (*nodeIterator) == firstCleanNode); + Q_ASSERT(nodeIterator == d->textNodeMap.end() + || (nodeIterator->textNode() == firstCleanNode.textNode() + && nodeIterator->startPos() == firstCleanNode.startPos())); // Update the position of the subsequent text blocks. - if (firstCleanNode) { - QPointF oldOffset = firstCleanNode->textNode()->matrix().map(QPointF(0,0)); - QPointF currentOffset = d->document->documentLayout()->blockBoundingRect(d->document->findBlock(firstCleanNode->startPos())).topLeft(); + if (firstCleanNode.textNode() != nullptr) { + QPointF oldOffset = firstCleanNode.textNode()->matrix().map(QPointF(0,0)); + QPointF currentOffset = d->document->documentLayout()->blockBoundingRect( + d->document->findBlock(firstCleanNode.startPos())).topLeft(); QPointF delta = currentOffset - oldOffset; while (nodeIterator != d->textNodeMap.end()) { - QMatrix4x4 transformMatrix = (*nodeIterator)->textNode()->matrix(); + QMatrix4x4 transformMatrix = nodeIterator->textNode()->matrix(); transformMatrix.translate(delta.x(), delta.y()); - (*nodeIterator)->textNode()->setMatrix(transformMatrix); + nodeIterator->textNode()->setMatrix(transformMatrix); ++nodeIterator; } @@ -2154,11 +2156,11 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData * // Since we iterate over blocks from different text frames that are potentially not sorted // we need to ensure that our list of nodes is sorted again: - std::sort(d->textNodeMap.begin(), d->textNodeMap.end(), &comesBefore); + std::sort(d->textNodeMap.begin(), d->textNodeMap.end()); } - if (d->cursorComponent == 0) { - QSGInternalRectangleNode* cursor = 0; + if (d->cursorComponent == nullptr) { + QSGInternalRectangleNode* cursor = nullptr; if (!isReadOnly() && d->cursorVisible && d->control->cursorOn()) cursor = d->sceneGraphContext()->createInternalRectangleNode(d->control->cursorRect(), d->color); rootNode->resetCursorNode(cursor); @@ -2333,22 +2335,26 @@ void QQuickTextEdit::markDirtyNodesForRange(int start, int end, int charDelta) if (start == end) return; - TextNode dummyNode(start, 0); - TextNodeIterator it = std::lower_bound(d->textNodeMap.begin(), d->textNodeMap.end(), &dummyNode, &comesBefore); + TextNode dummyNode(start); + + const TextNodeIterator textNodeMapBegin = d->textNodeMap.begin(); + const TextNodeIterator textNodeMapEnd = d->textNodeMap.end(); + + TextNodeIterator it = std::lower_bound(textNodeMapBegin, textNodeMapEnd, dummyNode); // qLowerBound gives us the first node past the start of the affected portion, rewind to the first node // that starts at the last position before the edit position. (there might be several because of images) - if (it != d->textNodeMap.begin()) { + if (it != textNodeMapBegin) { --it; - TextNode otherDummy((*it)->startPos(), 0); - it = std::lower_bound(d->textNodeMap.begin(), d->textNodeMap.end(), &otherDummy, &comesBefore); + TextNode otherDummy(it->startPos()); + it = std::lower_bound(textNodeMapBegin, textNodeMapEnd, otherDummy); } // mark the affected nodes as dirty - while (it != d->textNodeMap.end()) { - if ((*it)->startPos() <= end) - (*it)->setDirty(); + while (it != textNodeMapEnd) { + if (it->startPos() <= end) + it->setDirty(); else if (charDelta) - (*it)->moveStartPos(charDelta); + it->moveStartPos(charDelta); else return; ++it; @@ -2533,8 +2539,8 @@ void QQuickTextEdit::updateWholeDocument() { Q_D(QQuickTextEdit); if (!d->textNodeMap.isEmpty()) { - for (TextNode* node : qAsConst(d->textNodeMap)) - node->setDirty(); + for (TextNode &node : d->textNodeMap) + node.setDirty(); } polish(); @@ -2678,7 +2684,7 @@ void QQuickTextEditPrivate::handleFocusEvent(QFocusEvent *event) void QQuickTextEditPrivate::addCurrentTextNodeToRoot(QQuickTextNodeEngine *engine, QSGTransformNode *root, QQuickTextNode *node, TextNodeIterator &it, int startPos) { engine->addToSceneGraph(node, QQuickText::Normal, QColor()); - it = textNodeMap.insert(it, new TextNode(startPos, node)); + it = textNodeMap.insert(it, TextNode(startPos, node)); ++it; root->appendChildNode(node); } diff --git a/src/quick/items/qquicktextedit_p.h b/src/quick/items/qquicktextedit_p.h index c883e39168..7a847ffeae 100644 --- a/src/quick/items/qquicktextedit_p.h +++ b/src/quick/items/qquicktextedit_p.h @@ -114,7 +114,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickTextEdit : public QQuickImplicitSizeItem Q_PROPERTY(qreal tabStopDistance READ tabStopDistance WRITE setTabStopDistance NOTIFY tabStopDistanceChanged REVISION 10) public: - QQuickTextEdit(QQuickItem *parent=0); + QQuickTextEdit(QQuickItem *parent=nullptr); enum HAlignment { AlignLeft = Qt::AlignLeft, @@ -384,7 +384,7 @@ private: void invalidateFontCaches(); protected: - QQuickTextEdit(QQuickTextEditPrivate &dd, QQuickItem *parent = 0); + QQuickTextEdit(QQuickTextEditPrivate &dd, QQuickItem *parent = nullptr); void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override; diff --git a/src/quick/items/qquicktextedit_p_p.h b/src/quick/items/qquicktextedit_p_p.h index 09718cb49a..46d3d5ff6b 100644 --- a/src/quick/items/qquicktextedit_p_p.h +++ b/src/quick/items/qquicktextedit_p_p.h @@ -59,6 +59,8 @@ #include <QtCore/qlist.h> #include <private/qlazilyallocated_p.h> +#include <limits> + QT_BEGIN_NAMESPACE class QTextLayout; class QQuickTextDocumentWithImageResources; @@ -74,7 +76,8 @@ public: typedef QQuickTextEdit Public; struct Node { - explicit Node(int startPos, QQuickTextNode* node) + explicit Node(int startPos = std::numeric_limits<int>::max(), + QQuickTextNode *node = nullptr) : m_startPos(startPos), m_node(node), m_dirty(false) { } QQuickTextNode* textNode() const { return m_node; } void moveStartPos(int delta) { Q_ASSERT(m_startPos + delta > 0); m_startPos += delta; } @@ -87,7 +90,7 @@ public: QQuickTextNode* m_node; bool m_dirty; }; - typedef QList<Node*>::iterator TextNodeIterator; + typedef QList<Node>::iterator TextNodeIterator; struct ExtraData { ExtraData(); @@ -109,8 +112,8 @@ public: QQuickTextEditPrivate() : color(QRgb(0xFF000000)), selectionColor(QRgb(0xFF000080)), selectedTextColor(QRgb(0xFFFFFFFF)) , textMargin(0.0), xoff(0), yoff(0) - , font(sourceFont), cursorComponent(0), cursorItem(0), document(0), control(0) - , quickDocument(0), lastSelectionStart(0), lastSelectionEnd(0), lineCount(0) + , font(sourceFont), cursorComponent(nullptr), cursorItem(nullptr), document(nullptr), control(nullptr) + , quickDocument(nullptr), lastSelectionStart(0), lastSelectionEnd(0), lineCount(0) , hAlign(QQuickTextEdit::AlignLeft), vAlign(QQuickTextEdit::AlignTop) , format(QQuickTextEdit::PlainText), wrapMode(QQuickTextEdit::NoWrap) , renderType(QQuickTextUtil::textRenderType<QQuickTextEdit>()) @@ -128,11 +131,6 @@ public: { } - ~QQuickTextEditPrivate() - { - qDeleteAll(textNodeMap); - } - static QQuickTextEditPrivate *get(QQuickTextEdit *item) { return static_cast<QQuickTextEditPrivate *>(QObjectPrivate::get(item)); } @@ -186,7 +184,7 @@ public: QQuickTextDocumentWithImageResources *document; QQuickTextControl *control; QQuickTextDocument *quickDocument; - QList<Node*> textNodeMap; + QList<Node> textNodeMap; int lastSelectionStart; int lastSelectionEnd; diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp index d516b6f30c..b19c13c5ee 100644 --- a/src/quick/items/qquicktextinput.cpp +++ b/src/quick/items/qquicktextinput.cpp @@ -384,9 +384,9 @@ QString QQuickTextInputPrivate::realText() const \qmlproperty bool QtQuick::TextInput::font.kerning \since 5.10 - Enables or disables the kerning OpenType feature when shaping the text. This may improve performance - when creating or changing the text, at the expense of some cosmetic features. The default value - is true. + Enables or disables the kerning OpenType feature when shaping the text. Disabling this may + improve performance when creating or changing the text, at the expense of some cosmetic + features. The default value is true. \qml TextInput { text: "OATS FLAVOUR WAY"; font.kerning: false } @@ -1108,7 +1108,8 @@ void QQuickTextInputPrivate::checkIsValid() Q_Q(QQuickTextInput); ValidatorState state = hasAcceptableInput(m_text); - m_validInput = state != InvalidInput; + if (!m_maskData) + m_validInput = state != InvalidInput; if (state != AcceptableInput) { if (m_acceptableInput) { m_acceptableInput = false; @@ -1862,7 +1863,7 @@ void QQuickTextInput::invalidateFontCaches() { Q_D(QQuickTextInput); - if (d->m_textLayout.engine() != 0) + if (d->m_textLayout.engine() != nullptr) d->m_textLayout.engine()->resetFontEngineCache(); } @@ -1885,7 +1886,7 @@ QSGNode *QQuickTextInput::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData Q_UNUSED(data); Q_D(QQuickTextInput); - if (d->updateType != QQuickTextInputPrivate::UpdatePaintNode && oldNode != 0) { + if (d->updateType != QQuickTextInputPrivate::UpdatePaintNode && oldNode != nullptr) { // Update done in preprocess() in the nodes d->updateType = QQuickTextInputPrivate::UpdateNone; return oldNode; @@ -1894,13 +1895,13 @@ QSGNode *QQuickTextInput::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData d->updateType = QQuickTextInputPrivate::UpdateNone; QQuickTextNode *node = static_cast<QQuickTextNode *>(oldNode); - if (node == 0) + if (node == nullptr) node = new QQuickTextNode(this); d->textNode = node; - const bool showCursor = !isReadOnly() && d->cursorItem == 0 && d->cursorVisible && d->m_blinkStatus; + const bool showCursor = !isReadOnly() && d->cursorItem == nullptr && d->cursorVisible && d->m_blinkStatus; - if (!d->textLayoutDirty && oldNode != 0) { + if (!d->textLayoutDirty && oldNode != nullptr) { if (showCursor) node->setCursor(cursorRectangle(), d->color); else @@ -3561,11 +3562,15 @@ bool QQuickTextInputPrivate::finishChange(int validateFromState, bool update, bo #if QT_CONFIG(validator) if (m_validator) { QString textCopy = m_text; + if (m_maskData) + textCopy = maskString(0, m_text, true); int cursorCopy = m_cursor; QValidator::State state = m_validator->validate(textCopy, cursorCopy); + if (m_maskData) + textCopy = m_text; m_validInput = state != QValidator::Invalid; m_acceptableInput = state == QValidator::Acceptable; - if (m_validInput) { + if (m_validInput && !m_maskData) { if (m_text != textCopy) { internalSetText(textCopy, cursorCopy); return true; @@ -3574,31 +3579,8 @@ bool QQuickTextInputPrivate::finishChange(int validateFromState, bool update, bo } } #endif - - if (m_maskData) { - m_validInput = true; - if (m_text.length() != m_maxLength) { - m_validInput = false; - m_acceptableInput = false; - } else { - for (int i = 0; i < m_maxLength; ++i) { - if (m_maskData[i].separator) { - if (m_text.at(i) != m_maskData[i].maskChar) { - m_validInput = false; - m_acceptableInput = false; - break; - } - } else { - if (!isValidInput(m_text.at(i), m_maskData[i].maskChar)) { - m_acceptableInput = false; - if (m_text.at(i) != m_blank) - m_validInput = false; - break; - } - } - } - } - } + if (m_maskData) + checkIsValid(); if (validateFromState >= 0 && wasValidInput && !m_validInput) { if (m_transactions.count()) @@ -3846,7 +3828,7 @@ void QQuickTextInputPrivate::parseInputMask(const QString &maskFields) if (maskFields.isEmpty() || delimiter == 0) { if (m_maskData) { delete [] m_maskData; - m_maskData = 0; + m_maskData = nullptr; m_maxLength = 32767; internalSetText(QString()); } diff --git a/src/quick/items/qquicktextinput_p.h b/src/quick/items/qquicktextinput_p.h index b7d3fb00fa..c46a2f8128 100644 --- a/src/quick/items/qquicktextinput_p.h +++ b/src/quick/items/qquicktextinput_p.h @@ -115,7 +115,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickTextInput : public QQuickImplicitSizeItem Q_PROPERTY(qreal bottomPadding READ bottomPadding WRITE setBottomPadding RESET resetBottomPadding NOTIFY bottomPaddingChanged REVISION 6) public: - QQuickTextInput(QQuickItem * parent=0); + QQuickTextInput(QQuickItem * parent=nullptr); ~QQuickTextInput(); void componentComplete() override; @@ -363,7 +363,7 @@ private: void ensureActiveFocus(); protected: - QQuickTextInput(QQuickTextInputPrivate &dd, QQuickItem *parent = 0); + QQuickTextInput(QQuickTextInputPrivate &dd, QQuickItem *parent = nullptr); void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override; diff --git a/src/quick/items/qquicktextinput_p_p.h b/src/quick/items/qquicktextinput_p_p.h index c795aebfa9..a2e2f0f66d 100644 --- a/src/quick/items/qquicktextinput_p_p.h +++ b/src/quick/items/qquicktextinput_p_p.h @@ -99,9 +99,9 @@ public: QQuickTextInputPrivate() : hscroll(0) , vscroll(0) - , cursorItem(0) - , textNode(0) - , m_maskData(0) + , cursorItem(nullptr) + , textNode(nullptr) + , m_maskData(nullptr) , color(QRgb(0xFF000000)) , selectionColor(QRgb(0xFF000080)) , selectedTextColor(QRgb(0xFFFFFFFF)) diff --git a/src/quick/items/qquicktextnode.cpp b/src/quick/items/qquicktextnode.cpp index cf4e71adf5..13a8219cbd 100644 --- a/src/quick/items/qquicktextnode.cpp +++ b/src/quick/items/qquicktextnode.cpp @@ -78,7 +78,7 @@ namespace { Creates an empty QQuickTextNode */ QQuickTextNode::QQuickTextNode(QQuickItem *ownerElement) - : m_cursorNode(0), m_ownerElement(ownerElement), m_useNativeRenderer(false) + : m_cursorNode(nullptr), m_ownerElement(ownerElement), m_useNativeRenderer(false) { #ifdef QSG_RUNTIME_DESCRIPTION qsgnode_set_description(this, QLatin1String("text")); @@ -125,7 +125,7 @@ QSGGlyphNode *QQuickTextNode::addGlyphs(const QPointF &position, const QGlyphRun node->geometry()->setIndexDataPattern(QSGGeometry::StaticPattern); node->geometry()->setVertexDataPattern(QSGGeometry::StaticPattern); - if (parentNode == 0) + if (parentNode == nullptr) parentNode = this; parentNode->appendChildNode(node); @@ -134,7 +134,7 @@ QSGGlyphNode *QQuickTextNode::addGlyphs(const QPointF &position, const QGlyphRun void QQuickTextNode::setCursor(const QRectF &rect, const QColor &color) { - if (m_cursorNode != 0) + if (m_cursorNode != nullptr) delete m_cursorNode; QSGRenderContext *sg = QQuickItemPrivate::get(m_ownerElement)->sceneGraphRenderContext(); @@ -147,7 +147,7 @@ void QQuickTextNode::clearCursor() if (m_cursorNode) removeChildNode(m_cursorNode); delete m_cursorNode; - m_cursorNode = 0; + m_cursorNode = nullptr; } void QQuickTextNode::addRectangleNode(const QRectF &rect, const QColor &color) @@ -273,9 +273,9 @@ void QQuickTextNode::addTextLayout(const QPointF &position, QTextLayout *textLay void QQuickTextNode::deleteContent() { - while (firstChild() != 0) + while (firstChild() != nullptr) delete firstChild(); - m_cursorNode = 0; + m_cursorNode = nullptr; qDeleteAll(m_textures); m_textures.clear(); } diff --git a/src/quick/items/qquicktextnodeengine.cpp b/src/quick/items/qquicktextnodeengine.cpp index c179ab7163..a53ca2a2a4 100644 --- a/src/quick/items/qquicktextnodeengine.cpp +++ b/src/quick/items/qquicktextnodeengine.cpp @@ -75,7 +75,7 @@ QQuickTextNodeEngine::BinaryTreeNode::BinaryTreeNode(const QGlyphRun &g, : glyphRun(g) , boundingRect(brect) , selectionState(selState) - , clipNode(0) + , clipNode(nullptr) , decorations(decs) , color(c) , backgroundColor(bc) @@ -256,10 +256,10 @@ void QQuickTextNodeEngine::processCurrentLine() QVarLengthArray<TextDecoration> pendingOverlines; QVarLengthArray<TextDecoration> pendingStrikeOuts; if (!sortedIndexes.isEmpty()) { - QQuickDefaultClipNode *currentClipNode = m_hasSelection ? new QQuickDefaultClipNode(QRectF()) : 0; + QQuickDefaultClipNode *currentClipNode = m_hasSelection ? new QQuickDefaultClipNode(QRectF()) : nullptr; bool currentClipNodeUsed = false; for (int i=0; i<=sortedIndexes.size(); ++i) { - BinaryTreeNode *node = 0; + BinaryTreeNode *node = nullptr; if (i < sortedIndexes.size()) { int sortedIndex = sortedIndexes.at(i); Q_ASSERT(sortedIndex < m_currentLineTree.size()); @@ -275,7 +275,7 @@ void QQuickTextNodeEngine::processCurrentLine() decorationRect.setY(m_position.y() + m_currentLine.y()); decorationRect.setHeight(m_currentLine.height()); - if (node != 0) + if (node != nullptr) decorationRect.setRight(node->boundingRect.left()); TextDecoration textDecoration(currentSelectionState, decorationRect, lastColor); @@ -295,14 +295,14 @@ void QQuickTextNodeEngine::processCurrentLine() // If we've reached an unselected node from a selected node, we add the // selection rect to the graph, and we add decoration every time the // selection state changes, because that means the text color changes - if (node == 0 || node->selectionState != currentSelectionState) { + if (node == nullptr || node->selectionState != currentSelectionState) { currentRect.setY(m_position.y() + m_currentLine.y()); currentRect.setHeight(m_currentLine.height()); if (currentSelectionState == Selected) m_selectionRects.append(currentRect); - if (currentClipNode != 0) { + if (currentClipNode != nullptr) { if (!currentClipNodeUsed) { delete currentClipNode; } else { @@ -312,13 +312,13 @@ void QQuickTextNodeEngine::processCurrentLine() } } - if (node != 0 && m_hasSelection) + if (node != nullptr && m_hasSelection) currentClipNode = new QQuickDefaultClipNode(QRectF()); else - currentClipNode = 0; + currentClipNode = nullptr; currentClipNodeUsed = false; - if (node != 0) { + if (node != nullptr) { currentSelectionState = node->selectionState; currentRect = node->boundingRect; @@ -333,7 +333,7 @@ void QQuickTextNodeEngine::processCurrentLine() currentRect = currentRect.united(node->boundingRect); } - if (node != 0) { + if (node != nullptr) { if (node->selectionState == Selected) { node->clipNode = currentClipNode; currentClipNodeUsed = true; @@ -449,7 +449,7 @@ void QQuickTextNodeEngine::addTextObject(const QPointF &position, const QTextCha QTextFrameFormat::Position layoutPosition) { QTextObjectInterface *handler = textDocument->documentLayout()->handlerForObject(format.objectType()); - if (handler != 0) { + if (handler != nullptr) { QImage image; QSizeF size = handler->intrinsicSize(textDocument, pos, format); @@ -651,7 +651,7 @@ void QQuickTextNodeEngine::addFrameDecorations(QTextDocument *document, QTextFra QTextFrameFormat frameFormat = frame->format().toFrameFormat(); QTextTable *table = qobject_cast<QTextTable *>(frame); - QRectF boundingRect = table == 0 + QRectF boundingRect = table == nullptr ? documentLayout->frameBoundingRect(frame) : documentLayout->tableBoundingRect(table); @@ -674,7 +674,7 @@ void QQuickTextNodeEngine::addFrameDecorations(QTextDocument *document, QTextFra addBorder(boundingRect.adjusted(frameFormat.leftMargin(), frameFormat.topMargin(), -frameFormat.rightMargin(), -frameFormat.bottomMargin()), borderWidth, borderStyle, borderBrush); - if (table != 0) { + if (table != nullptr) { int rows = table->rows(); int columns = table->columns(); @@ -781,7 +781,7 @@ void QQuickTextNodeEngine::addToSceneGraph(QQuickTextNode *parentNode, // Add all text with unselected color first for (int i = 0; i < nodes.size(); ++i) { const BinaryTreeNode *node = nodes.at(i); - parentNode->addGlyphs(node->position, node->glyphRun, node->color, style, styleColor, 0); + parentNode->addGlyphs(node->position, node->glyphRun, node->color, style, styleColor, nullptr); } for (int i = 0; i < imageNodes.size(); ++i) { @@ -812,7 +812,7 @@ void QQuickTextNodeEngine::addToSceneGraph(QQuickTextNode *parentNode, for (int i = 0; i < nodes.size(); ++i) { const BinaryTreeNode *node = nodes.at(i); QQuickDefaultClipNode *clipNode = node->clipNode; - if (clipNode != 0 && clipNode->parent() == 0) + if (clipNode != nullptr && clipNode->parent() == nullptr) parentNode->appendChildNode(clipNode); if (node->selectionState == Selected) { @@ -820,26 +820,26 @@ void QQuickTextNodeEngine::addToSceneGraph(QQuickTextNode *parentNode, int previousNodeIndex = i - 1; int nextNodeIndex = i + 1; const BinaryTreeNode *previousNode = previousNodeIndex < 0 ? 0 : nodes.at(previousNodeIndex); - while (previousNode != 0 && qFuzzyCompare(previousNode->boundingRect.left(), node->boundingRect.left())) + while (previousNode != nullptr && qFuzzyCompare(previousNode->boundingRect.left(), node->boundingRect.left())) previousNode = --previousNodeIndex < 0 ? 0 : nodes.at(previousNodeIndex); const BinaryTreeNode *nextNode = nextNodeIndex == nodes.size() ? 0 : nodes.at(nextNodeIndex); - if (previousNode != 0 && previousNode->selectionState == Unselected) + if (previousNode != nullptr && previousNode->selectionState == Unselected) parentNode->addGlyphs(previousNode->position, previousNode->glyphRun, color, style, styleColor, clipNode); - if (nextNode != 0 && nextNode->selectionState == Unselected) + if (nextNode != nullptr && nextNode->selectionState == Unselected) parentNode->addGlyphs(nextNode->position, nextNode->glyphRun, color, style, styleColor, clipNode); // If the previous or next node completely overlaps this one, then we have already drawn the glyphs of // this node bool drawCurrent = false; - if (previousNode != 0 || nextNode != 0) { + if (previousNode != nullptr || nextNode != nullptr) { for (int i = 0; i < node->ranges.size(); ++i) { const QPair<int, int> &range = node->ranges.at(i); int rangeLength = range.second - range.first + 1; - if (previousNode != 0) { + if (previousNode != nullptr) { for (int j = 0; j < previousNode->ranges.size(); ++j) { const QPair<int, int> &otherRange = previousNode->ranges.at(j); @@ -853,7 +853,7 @@ void QQuickTextNodeEngine::addToSceneGraph(QQuickTextNode *parentNode, } } - if (nextNode != 0 && rangeLength > 0) { + if (nextNode != nullptr && rangeLength > 0) { for (int j = 0; j < nextNode->ranges.size(); ++j) { const QPair<int, int> &otherRange = nextNode->ranges.at(j); @@ -896,8 +896,8 @@ void QQuickTextNodeEngine::addToSceneGraph(QQuickTextNode *parentNode, void QQuickTextNodeEngine::mergeFormats(QTextLayout *textLayout, QVarLengthArray<QTextLayout::FormatRange> *mergedFormats) { - Q_ASSERT(mergedFormats != 0); - if (textLayout == 0) + Q_ASSERT(mergedFormats != nullptr); + if (textLayout == nullptr) return; QVector<QTextLayout::FormatRange> additionalFormats = textLayout->formats(); @@ -911,7 +911,7 @@ void QQuickTextNodeEngine::mergeFormats(QTextLayout *textLayout, QVarLengthArray QTextLayout::FormatRange *lastFormat = mergedFormats->data() + mergedFormats->size() - 1; if (additionalFormat.start < lastFormat->start + lastFormat->length) { - QTextLayout::FormatRange *mergedRange = 0; + QTextLayout::FormatRange *mergedRange = nullptr; int length = additionalFormat.length; if (additionalFormat.start > lastFormat->start) { diff --git a/src/quick/items/qquicktextutil.cpp b/src/quick/items/qquicktextutil.cpp index 6aa6c5cb4b..eb356a9c48 100644 --- a/src/quick/items/qquicktextutil.cpp +++ b/src/quick/items/qquicktextutil.cpp @@ -48,7 +48,7 @@ QT_BEGIN_NAMESPACE QQuickItem *QQuickTextUtil::createCursor( QQmlComponent *component, QQuickItem *parent, const QRectF &rectangle, const char *className) { - QQuickItem *item = 0; + QQuickItem *item = nullptr; if (component->isReady()) { QQmlContext *creationContext = component->creationContext(); diff --git a/src/quick/items/qquicktranslate_p.h b/src/quick/items/qquicktranslate_p.h index b0199cef40..b6ea43342c 100644 --- a/src/quick/items/qquicktranslate_p.h +++ b/src/quick/items/qquicktranslate_p.h @@ -66,7 +66,7 @@ class Q_AUTOTEST_EXPORT QQuickTranslate : public QQuickTransform Q_PROPERTY(qreal y READ y WRITE setY NOTIFY yChanged) public: - QQuickTranslate(QObject *parent = 0); + QQuickTranslate(QObject *parent = nullptr); ~QQuickTranslate(); qreal x() const; @@ -96,7 +96,7 @@ class Q_AUTOTEST_EXPORT QQuickScale : public QQuickTransform Q_PROPERTY(qreal yScale READ yScale WRITE setYScale NOTIFY yScaleChanged) Q_PROPERTY(qreal zScale READ zScale WRITE setZScale NOTIFY zScaleChanged) public: - QQuickScale(QObject *parent = 0); + QQuickScale(QObject *parent = nullptr); ~QQuickScale(); QVector3D origin() const; @@ -133,7 +133,7 @@ class Q_AUTOTEST_EXPORT QQuickRotation : public QQuickTransform Q_PROPERTY(qreal angle READ angle WRITE setAngle NOTIFY angleChanged) Q_PROPERTY(QVector3D axis READ axis WRITE setAxis NOTIFY axisChanged) public: - QQuickRotation(QObject *parent = 0); + QQuickRotation(QObject *parent = nullptr); ~QQuickRotation(); QVector3D origin() const; @@ -164,7 +164,7 @@ class Q_AUTOTEST_EXPORT QQuickMatrix4x4 : public QQuickTransform Q_PROPERTY(QMatrix4x4 matrix READ matrix WRITE setMatrix NOTIFY matrixChanged) public: - QQuickMatrix4x4(QObject *parent = 0); + QQuickMatrix4x4(QObject *parent = nullptr); ~QQuickMatrix4x4(); QMatrix4x4 matrix() const; diff --git a/src/quick/items/qquickview.cpp b/src/quick/items/qquickview.cpp index 954ea5553a..17f6539974 100644 --- a/src/quick/items/qquickview.cpp +++ b/src/quick/items/qquickview.cpp @@ -70,13 +70,13 @@ void QQuickViewPrivate::init(QQmlEngine* e) { // The content item has CppOwnership policy (set in QQuickWindow). Ensure the presence of a JS // wrapper so that the garbage collector can see the policy. - QV4::ExecutionEngine *v4 = QQmlEnginePrivate::getV4Engine(engine.data()); + QV4::ExecutionEngine *v4 = engine.data()->handle(); QV4::QObjectWrapper::wrap(v4, contentItem); } } QQuickViewPrivate::QQuickViewPrivate() - : root(0), component(0), resizeMode(QQuickView::SizeViewToRootObject), initialSize(0,0) + : root(nullptr), component(nullptr), resizeMode(QQuickView::SizeViewToRootObject), initialSize(0,0) { } @@ -94,11 +94,11 @@ void QQuickViewPrivate::execute() if (root) { delete root; - root = 0; + root = nullptr; } if (component) { delete component; - component = 0; + component = nullptr; } if (!source.isEmpty()) { QML_MEMORY_SCOPE_URL(engine.data()->baseUrl().resolved(source)); @@ -202,6 +202,16 @@ QQuickView::QQuickView(QQmlEngine* engine, QWindow *parent) } /*! + \internal +*/ +QQuickView::QQuickView(const QUrl &source, QQuickRenderControl *control) + : QQuickWindow(*(new QQuickViewPrivate), control) +{ + d_func()->init(); + setSource(source); +} + +/*! Destroys the QQuickView. */ QQuickView::~QQuickView() @@ -210,7 +220,7 @@ QQuickView::~QQuickView() // be a child of the QQuickViewPrivate, and will be destroyed by its dtor Q_D(QQuickView); delete d->root; - d->root = 0; + d->root = nullptr; } /*! @@ -254,7 +264,7 @@ void QQuickView::setContent(const QUrl& url, QQmlComponent *component, QObject* if (d->component && d->component->isError()) { const QList<QQmlError> errorList = d->component->errors(); for (const QQmlError &error : errorList) { - QMessageLogger(error.url().toString().toLatin1().constData(), error.line(), 0).warning() + QMessageLogger(error.url().toString().toLatin1().constData(), error.line(), nullptr).warning() << error; } emit statusChanged(status()); @@ -283,7 +293,7 @@ QUrl QQuickView::source() const QQmlEngine* QQuickView::engine() const { Q_D(const QQuickView); - return d->engine ? const_cast<QQmlEngine *>(d->engine.data()) : 0; + return d->engine ? const_cast<QQmlEngine *>(d->engine.data()) : nullptr; } /*! @@ -296,7 +306,7 @@ QQmlEngine* QQuickView::engine() const QQmlContext* QQuickView::rootContext() const { Q_D(const QQuickView); - return d->engine ? d->engine.data()->rootContext() : 0; + return d->engine ? d->engine.data()->rootContext() : nullptr; } /*! @@ -465,7 +475,7 @@ void QQuickView::continueExecute() if (d->component->isError()) { const QList<QQmlError> errorList = d->component->errors(); for (const QQmlError &error : errorList) { - QMessageLogger(error.url().toString().toLatin1().constData(), error.line(), 0).warning() + QMessageLogger(error.url().toString().toLatin1().constData(), error.line(), nullptr).warning() << error; } emit statusChanged(status()); @@ -477,7 +487,7 @@ void QQuickView::continueExecute() if (d->component->isError()) { const QList<QQmlError> errorList = d->component->errors(); for (const QQmlError &error : errorList) { - QMessageLogger(error.url().toString().toLatin1().constData(), error.line(), 0).warning() + QMessageLogger(error.url().toString().toLatin1().constData(), error.line(), nullptr).warning() << error; } emit statusChanged(status()); @@ -511,7 +521,7 @@ void QQuickViewPrivate::setRootObject(QObject *obj) << "Ensure your QML code is written for QtQuick 2, and uses a root that is or" << endl << "inherits from QtQuick's Item (not a Timer, QtObject, etc)." << endl; delete obj; - root = 0; + root = nullptr; } if (root) { initialSize = rootObjectSize(); diff --git a/src/quick/items/qquickview.h b/src/quick/items/qquickview.h index 014d02e7f5..ecae25e90b 100644 --- a/src/quick/items/qquickview.h +++ b/src/quick/items/qquickview.h @@ -62,7 +62,8 @@ public: explicit QQuickView(QWindow *parent = nullptr); QQuickView(QQmlEngine* engine, QWindow *parent); explicit QQuickView(const QUrl &source, QWindow *parent = nullptr); - virtual ~QQuickView(); + QQuickView(const QUrl &source, QQuickRenderControl *renderControl); + ~QQuickView() override; QUrl source() const; diff --git a/src/quick/items/qquickview_p.h b/src/quick/items/qquickview_p.h index f92d4b95d6..3f284c0519 100644 --- a/src/quick/items/qquickview_p.h +++ b/src/quick/items/qquickview_p.h @@ -93,7 +93,7 @@ public: void updateSize(); void setRootObject(QObject *); - void init(QQmlEngine* e = 0); + void init(QQmlEngine* e = nullptr); QSize rootObjectSize() const; diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index 462790e1b1..26b97d452a 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtQuick module of the Qt Toolkit. @@ -78,6 +78,9 @@ # include <private/qopenglvertexarrayobject_p.h> # include <private/qsgdefaultrendercontext_p.h> #endif +#ifndef QT_NO_DEBUG_STREAM +#include <private/qdebug_p.h> +#endif QT_BEGIN_NAMESPACE @@ -88,6 +91,7 @@ Q_LOGGING_CATEGORY(DBG_MOUSE_TARGET, "qt.quick.mouse.target") Q_LOGGING_CATEGORY(DBG_HOVER_TRACE, "qt.quick.hover.trace") Q_LOGGING_CATEGORY(DBG_FOCUS, "qt.quick.focus") Q_LOGGING_CATEGORY(DBG_DIRTY, "qt.quick.dirty") +Q_LOGGING_CATEGORY(lcTransient, "qt.quick.window.transient") extern Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha); @@ -481,25 +485,25 @@ void QQuickWindowPrivate::renderSceneGraph(const QSize &size) } QQuickWindowPrivate::QQuickWindowPrivate() - : contentItem(0) - , activeFocusItem(0) + : contentItem(nullptr) + , activeFocusItem(nullptr) #if QT_CONFIG(cursor) - , cursorItem(0) + , cursorItem(nullptr) #endif #if QT_CONFIG(draganddrop) - , dragGrabber(0) + , dragGrabber(nullptr) #endif , touchMouseId(-1) , touchMouseDevice(nullptr) , touchMousePressTimestamp(0) - , dirtyItemList(0) + , dirtyItemList(nullptr) , devicePixelRatio(0) - , context(0) - , renderer(0) - , windowManager(0) - , renderControl(0) + , context(nullptr) + , renderer(nullptr) + , windowManager(nullptr) + , renderControl(nullptr) , pointerEventRecursionGuard(0) - , customRenderStage(0) + , customRenderStage(nullptr) , clearColor(Qt::white) , clearBeforeRendering(true) , persistentGLContext(true) @@ -509,10 +513,10 @@ QQuickWindowPrivate::QQuickWindowPrivate() , allowChildEventFiltering(true) , allowDoubleClick(true) , lastFocusReason(Qt::OtherFocusReason) - , renderTarget(0) + , renderTarget(nullptr) , renderTargetId(0) - , vaoHelper(0) - , incubationController(0) + , vaoHelper(nullptr) + , incubationController(nullptr) { #if QT_CONFIG(draganddrop) dragGrabber = new QQuickDragGrabber; @@ -578,13 +582,21 @@ void QQuickWindowPrivate::init(QQuickWindow *c, QQuickRenderControl *control) QObject::connect(q, SIGNAL(focusObjectChanged(QObject*)), q, SIGNAL(activeFocusItemChanged())); QObject::connect(q, SIGNAL(screenChanged(QScreen*)), q, SLOT(handleScreenChanged(QScreen*))); - + QObject::connect(qApp, SIGNAL(applicationStateChanged(Qt::ApplicationState)), + q, SLOT(handleApplicationStateChanged(Qt::ApplicationState))); QObject::connect(q, SIGNAL(frameSwapped()), q, SLOT(runJobsAfterSwap()), Qt::DirectConnection); if (QQmlInspectorService *service = QQmlDebugConnector::service<QQmlInspectorService>()) service->addWindow(q); } +void QQuickWindow::handleApplicationStateChanged(Qt::ApplicationState state) +{ + Q_D(QQuickWindow); + if (state != Qt::ApplicationActive && d->contentItem) + d->contentItem->windowDeactivateEvent(); +} + /*! \property QQuickWindow::data \internal @@ -592,7 +604,7 @@ void QQuickWindowPrivate::init(QQuickWindow *c, QQuickRenderControl *control) QQmlListProperty<QObject> QQuickWindowPrivate::data() { - return QQmlListProperty<QObject>(q_func(), 0, QQuickWindowPrivate::data_append, + return QQmlListProperty<QObject>(q_func(), nullptr, QQuickWindowPrivate::data_append, QQuickWindowPrivate::data_count, QQuickWindowPrivate::data_at, QQuickWindowPrivate::data_clear); @@ -749,45 +761,6 @@ bool QQuickWindowPrivate::deliverTouchAsMouse(QQuickItem *item, QQuickPointerEve return false; } -void QQuickWindowPrivate::setMouseGrabber(QQuickItem *grabber) -{ - Q_Q(QQuickWindow); - if (q->mouseGrabberItem() == grabber) - return; - - QQuickItem *oldGrabber = q->mouseGrabberItem(); - qCDebug(DBG_MOUSE_TARGET) << "grabber" << oldGrabber << "->" << grabber; - - if (grabber && touchMouseId != -1 && touchMouseDevice) { - // update the touch item for mouse touch id to the new grabber - qCDebug(DBG_TOUCH_TARGET) << "TP (mouse)" << hex << touchMouseId << "->" << q->mouseGrabberItem(); - auto point = pointerEventInstance(touchMouseDevice)->pointById(touchMouseId); - if (point) { - auto originalEvent = pointerEventInstance(point->pointerEvent()->device()); - for (int i = 0; i < originalEvent->pointCount(); ++i) - originalEvent->point(i)->cancelExclusiveGrab(); - point->setGrabberItem(grabber); - for (auto handler : point->passiveGrabbers()) - point->cancelPassiveGrab(handler); - } - } else { - QQuickPointerEvent *event = pointerEventInstance(QQuickPointerDevice::genericMouseDevice()); - Q_ASSERT(event->pointCount() == 1); - auto point = event->point(0); - point->setGrabberItem(grabber); - for (auto handler : point->passiveGrabbers()) - point->cancelPassiveGrab(handler); - } - - - if (oldGrabber) { - QEvent e(QEvent::UngrabMouse); - hasFiltered.clear(); - if (!sendFilteredMouseEvent(&e, oldGrabber, oldGrabber->parentItem())) - oldGrabber->mouseUngrabEvent(); - } -} - void QQuickWindowPrivate::grabTouchPoints(QObject *grabber, const QVector<int> &ids) { for (int i = 0; i < ids.count(); ++i) { @@ -835,18 +808,25 @@ void QQuickWindowPrivate::removeGrabber(QQuickItem *grabber, bool mouse, bool to { Q_Q(QQuickWindow); if (Q_LIKELY(mouse) && q->mouseGrabberItem() == grabber) { - qCDebug(DBG_MOUSE_TARGET) << "removeGrabber" << q->mouseGrabberItem() << "-> null"; - setMouseGrabber(nullptr); + bool fromTouch = isDeliveringTouchAsMouse(); + auto point = fromTouch ? + pointerEventInstance(touchMouseDevice)->pointById(touchMouseId) : + pointerEventInstance(QQuickPointerDevice::genericMouseDevice())->point(0); + QQuickItem *oldGrabber = point->grabberItem(); + qCDebug(DBG_MOUSE_TARGET) << "removeGrabber" << oldGrabber << "-> null"; + point->setGrabberItem(nullptr); + sendUngrabEvent(oldGrabber, fromTouch); } if (Q_LIKELY(touch)) { bool ungrab = false; const auto touchDevices = QQuickPointerDevice::touchDevices(); for (auto device : touchDevices) { - auto pointerEvent = pointerEventInstance(device); - for (int i = 0; i < pointerEvent->pointCount(); ++i) { - if (pointerEvent->point(i)->exclusiveGrabber() == grabber) { - pointerEvent->point(i)->setGrabberItem(nullptr); - ungrab = true; + if (auto pointerEvent = queryPointerEventInstance(device)) { + for (int i = 0; i < pointerEvent->pointCount(); ++i) { + if (pointerEvent->point(i)->exclusiveGrabber() == grabber) { + pointerEvent->point(i)->setGrabberItem(nullptr); + ungrab = true; + } } } } @@ -855,6 +835,19 @@ void QQuickWindowPrivate::removeGrabber(QQuickItem *grabber, bool mouse, bool to } } +void QQuickWindowPrivate::sendUngrabEvent(QQuickItem *grabber, bool touch) +{ + if (!grabber) + return; + QEvent e(QEvent::UngrabMouse); + hasFiltered.clear(); + if (!sendFilteredMouseEvent(&e, grabber, grabber->parentItem())) { + grabber->mouseUngrabEvent(); + if (touch) + grabber->touchUngrabEvent(); + } +} + /*! Translates the data in \a touchEvent to this window. This method leaves the item local positions in \a touchEvent untouched (these are filled in later). @@ -898,12 +891,12 @@ void QQuickWindowPrivate::setFocusInScope(QQuickItem *scope, QQuickItem *item, Q qCDebug(DBG_FOCUS) << " item:" << (QObject *)item; qCDebug(DBG_FOCUS) << " activeFocusItem:" << (QObject *)activeFocusItem; - QQuickItemPrivate *scopePrivate = scope ? QQuickItemPrivate::get(scope) : 0; + QQuickItemPrivate *scopePrivate = scope ? QQuickItemPrivate::get(scope) : nullptr; QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item); - QQuickItem *oldActiveFocusItem = 0; + QQuickItem *oldActiveFocusItem = nullptr; QQuickItem *currentActiveFocusItem = activeFocusItem; - QQuickItem *newActiveFocusItem = 0; + QQuickItem *newActiveFocusItem = nullptr; bool sendFocusIn = false; lastFocusReason = reason; @@ -929,7 +922,7 @@ void QQuickWindowPrivate::setFocusInScope(QQuickItem *scope, QQuickItem *item, Q QGuiApplication::inputMethod()->commit(); #endif - activeFocusItem = 0; + activeFocusItem = nullptr; QQuickItem *afi = oldActiveFocusItem; while (afi && afi != scope) { @@ -1009,7 +1002,7 @@ void QQuickWindowPrivate::clearFocusInScope(QQuickItem *scope, QQuickItem *item, qCDebug(DBG_FOCUS) << " item:" << (QObject *)item; qCDebug(DBG_FOCUS) << " activeFocusItem:" << (QObject *)activeFocusItem; - QQuickItemPrivate *scopePrivate = 0; + QQuickItemPrivate *scopePrivate = nullptr; if (scope) { scopePrivate = QQuickItemPrivate::get(scope); if ( !scopePrivate->subFocusItem ) @@ -1017,8 +1010,8 @@ void QQuickWindowPrivate::clearFocusInScope(QQuickItem *scope, QQuickItem *item, } QQuickItem *currentActiveFocusItem = activeFocusItem; - QQuickItem *oldActiveFocusItem = 0; - QQuickItem *newActiveFocusItem = 0; + QQuickItem *oldActiveFocusItem = nullptr; + QQuickItem *newActiveFocusItem = nullptr; lastFocusReason = reason; @@ -1035,7 +1028,7 @@ void QQuickWindowPrivate::clearFocusInScope(QQuickItem *scope, QQuickItem *item, QGuiApplication::inputMethod()->commit(); #endif - activeFocusItem = 0; + activeFocusItem = nullptr; if (oldActiveFocusItem) { QQuickItem *afi = oldActiveFocusItem; @@ -1284,13 +1277,21 @@ QQuickWindow::QQuickWindow(QQuickWindowPrivate &dd, QWindow *parent) \internal */ QQuickWindow::QQuickWindow(QQuickRenderControl *control) - : QWindow(*(new QQuickWindowPrivate), 0) + : QWindow(*(new QQuickWindowPrivate), nullptr) { Q_D(QQuickWindow); d->init(this, control); } - +/*! + \internal +*/ +QQuickWindow::QQuickWindow(QQuickWindowPrivate &dd, QQuickRenderControl *control) + : QWindow(dd, nullptr) +{ + Q_D(QQuickWindow); + d->init(this, control); +} /*! Destroys the window. @@ -1306,11 +1307,13 @@ QQuickWindow::~QQuickWindow() d->windowManager->windowDestroyed(this); } - delete d->incubationController; d->incubationController = 0; + delete d->incubationController; d->incubationController = nullptr; #if QT_CONFIG(draganddrop) - delete d->dragGrabber; d->dragGrabber = 0; + delete d->dragGrabber; d->dragGrabber = nullptr; #endif - delete d->contentItem; d->contentItem = 0; + delete d->contentItem; d->contentItem = nullptr; + qDeleteAll(d->pointerEventInstances); + d->pointerEventInstances.clear(); d->renderJobMutex.lock(); qDeleteAll(d->beforeSynchronizingJobs); @@ -1511,15 +1514,16 @@ QQuickItem *QQuickWindow::mouseGrabberItem() const { Q_D(const QQuickWindow); - if (d->touchMouseId != -1 && d->touchMouseDevice) { - QQuickPointerEvent *event = d->pointerEventInstance(d->touchMouseDevice); - auto point = event->pointById(d->touchMouseId); - return point ? point->grabberItem() : nullptr; + if (d->isDeliveringTouchAsMouse()) { + if (QQuickPointerEvent *event = d->queryPointerEventInstance(d->touchMouseDevice)) { + auto point = event->pointById(d->touchMouseId); + return point ? point->grabberItem() : nullptr; + } + } else if (QQuickPointerEvent *event = d->queryPointerEventInstance(QQuickPointerDevice::genericMouseDevice())) { + Q_ASSERT(event->pointCount()); + return event->point(0)->grabberItem(); } - - QQuickPointerEvent *event = d->pointerEventInstance(QQuickPointerDevice::genericMouseDevice()); - Q_ASSERT(event->pointCount()); - return event->point(0)->grabberItem(); + return nullptr; } @@ -1693,8 +1697,10 @@ void QQuickWindowPrivate::deliverToPassiveGrabbers(const QVector<QPointer <QQuic alreadyFiltered = sendFilteredPointerEvent(pointerEvent, par); sendFilteredPointerEventResult << qMakePair<QQuickItem*, bool>(par, alreadyFiltered); } - if (!alreadyFiltered) + if (!alreadyFiltered) { + pointerEvent->localize(handler->parentItem()); handler->handlePointerEvent(pointerEvent); + } } } } @@ -1709,28 +1715,31 @@ void QQuickWindowPrivate::deliverMouseEvent(QQuickPointerMouseEvent *pointerEven if (point->exclusiveGrabber()) { if (auto grabber = point->grabberItem()) { + bool handled = false; if (sendFilteredPointerEvent(pointerEvent, grabber)) - return; + handled = true; // if the grabber is an Item: // if the update consists of changing button state, don't accept it unless // the button is one in which the grabber is interested Qt::MouseButtons acceptedButtons = grabber->acceptedMouseButtons(); - if (pointerEvent->button() != Qt::NoButton && acceptedButtons + if (!handled && pointerEvent->button() != Qt::NoButton && acceptedButtons && !(acceptedButtons & pointerEvent->button())) { pointerEvent->setAccepted(false); - return; + handled = true; } // send update - QPointF localPos = grabber->mapFromScene(lastMousePosition); - auto me = pointerEvent->asMouseEvent(localPos); - me->accept(); - QCoreApplication::sendEvent(grabber, me); - point->setAccepted(me->isAccepted()); + if (!handled) { + QPointF localPos = grabber->mapFromScene(lastMousePosition); + auto me = pointerEvent->asMouseEvent(localPos); + me->accept(); + QCoreApplication::sendEvent(grabber, me); + point->setAccepted(me->isAccepted()); + } // release event: ungrab if no buttons are pressed anymore if (mouseIsReleased) - setMouseGrabber(nullptr); + removeGrabber(grabber, true, isDeliveringTouchAsMouse()); } else { // if the grabber is not an Item, it must be a PointerHandler auto handler = point->grabberPointerHandler(); @@ -1740,6 +1749,7 @@ void QQuickWindowPrivate::deliverMouseEvent(QQuickPointerMouseEvent *pointerEven if (mouseIsReleased) point->setGrabberPointerHandler(nullptr, true); } + deliverToPassiveGrabbers(point->passiveGrabbers(), pointerEvent); } else { bool delivered = false; if (pointerEvent->isPressEvent()) { @@ -1756,6 +1766,8 @@ void QQuickWindowPrivate::deliverMouseEvent(QQuickPointerMouseEvent *pointerEven QVector<QQuickItem *> targetItems = pointerTargets(contentItem, point->scenePosition(), false, false); for (QQuickItem *item : targetItems) { QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item); + if (!itemPrivate->extra.isAllocated() || itemPrivate->extra->pointerHandlers.isEmpty()) + continue; pointerEvent->localize(item); if (!sendFilteredPointerEvent(pointerEvent, item)) { if (itemPrivate->handlePointerEvent(pointerEvent, true)) // avoid re-delivering to grabbers @@ -1931,7 +1943,8 @@ bool QQuickWindowPrivate::deliverNativeGestureEvent(QQuickItem *item, QNativeGes { QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item); - if ((itemPrivate->flags & QQuickItem::ItemClipsChildrenToShape) && !item->contains(event->localPos())) + QPointF p = item->mapFromScene(event->windowPos()); + if ((itemPrivate->flags & QQuickItem::ItemClipsChildrenToShape) && !item->contains(p)) return false; QList<QQuickItem *> children = itemPrivate->paintOrderChildItems(); @@ -1954,7 +1967,6 @@ bool QQuickWindowPrivate::deliverNativeGestureEvent(QQuickItem *item, QNativeGes } // If still not accepted, try direct delivery to the item - QPointF p = item->mapFromScene(event->localPos()); if (item->contains(p)) { QNativeGestureEvent copy(event->gestureType(), event->device(), p, event->windowPos(), event->screenPos(), event->value(), 0L, 0L); // TODO can't copy things I can't access @@ -1975,15 +1987,16 @@ bool QQuickWindowPrivate::deliverTouchCancelEvent(QTouchEvent *event) qCDebug(DBG_TOUCH) << event; Q_Q(QQuickWindow); + if (q->mouseGrabberItem()) + q->mouseGrabberItem()->ungrabMouse(); + touchMouseId = -1; + touchMouseDevice = nullptr; + // A TouchCancel event will typically not contain any points. // Deliver it to all items and handlers that have active touches. QQuickPointerEvent *pointerEvent = pointerEventInstance(QQuickPointerDevice::touchDevice(event->device())); for (int i = 0; i < pointerEvent->pointCount(); ++i) pointerEvent->point(i)->cancelExclusiveGrabImpl(event); - touchMouseId = -1; - touchMouseDevice = nullptr; - if (q->mouseGrabberItem()) - q->mouseGrabberItem()->ungrabMouse(); // The next touch event can only be a TouchBegin, so clean up. pointerEvent->clearGrabbers(); @@ -2202,7 +2215,7 @@ void QQuickWindowPrivate::flushFrameSynchronousEvents() } } -QQuickPointerEvent *QQuickWindowPrivate::pointerEventInstance(QQuickPointerDevice *device, QEvent::Type eventType) const +QQuickPointerEvent *QQuickWindowPrivate::queryPointerEventInstance(QQuickPointerDevice *device, QEvent::Type eventType) const { // Search for a matching reusable event object. for (QQuickPointerEvent *e : pointerEventInstances) { @@ -2215,9 +2228,14 @@ QQuickPointerEvent *QQuickWindowPrivate::pointerEventInstance(QQuickPointerDevic if (e->device() == device) return e; } + return nullptr; +} - // Not found: we have to create a suitable event instance. - QQuickPointerEvent *ev = nullptr; +QQuickPointerEvent *QQuickWindowPrivate::pointerEventInstance(QQuickPointerDevice *device, QEvent::Type eventType) const +{ + QQuickPointerEvent *ev = queryPointerEventInstance(device, eventType); + if (ev) + return ev; QQuickWindow *q = const_cast<QQuickWindow*>(q_func()); switch (device->type()) { case QQuickPointerDevice::Mouse: @@ -2278,6 +2296,7 @@ QQuickPointerEvent *QQuickWindowPrivate::pointerEventInstance(QEvent *event) con void QQuickWindowPrivate::deliverPointerEvent(QQuickPointerEvent *event) { + Q_Q(QQuickWindow); // If users spin the eventloop as a result of event delivery, we disable // event compression and send events directly. This is because we consider // the usecase a bit evil, but we at least don't want to lose events. @@ -2287,8 +2306,10 @@ void QQuickWindowPrivate::deliverPointerEvent(QQuickPointerEvent *event) if (event->asPointerMouseEvent()) { deliverMouseEvent(event->asPointerMouseEvent()); // failsafe: never allow any kind of grab to persist after release - if (event->isReleaseEvent() && event->buttons() == Qt::NoButton) + if (event->isReleaseEvent() && event->buttons() == Qt::NoButton) { event->clearGrabbers(); + sendUngrabEvent(q->mouseGrabberItem(), false); + } } else if (event->asPointerTouchEvent()) { deliverTouchEvent(event->asPointerTouchEvent()); } else { @@ -2399,6 +2420,7 @@ void QQuickWindowPrivate::deliverTouchEvent(QQuickPointerTouchEvent *event) // Deliver touch points to existing grabbers void QQuickWindowPrivate::deliverUpdatedTouchPoints(QQuickPointerTouchEvent *event) { + bool done = false; const auto grabbers = event->exclusiveGrabbers(); for (auto grabber : grabbers) { // The grabber is guaranteed to be either an item or a handler. @@ -2408,52 +2430,50 @@ void QQuickWindowPrivate::deliverUpdatedTouchPoints(QQuickPointerTouchEvent *eve QQuickPointerHandler *handler = static_cast<QQuickPointerHandler *>(grabber); receiver = static_cast<QQuickPointerHandler *>(grabber)->parentItem(); if (sendFilteredPointerEvent(event, receiver)) - return; + done = true; event->localize(receiver); handler->handlePointerEvent(event); - if (event->allPointsAccepted()) - return; } + if (done) + break; // If the grabber is an item or the grabbing handler didn't handle it, // then deliver the event to the item (which may have multiple handlers). deliverMatchingPointsToItem(receiver, event); } - // If some points weren't grabbed, deliver only to non-grabber PointerHandlers - if (!event->allPointsGrabbed()) { - int pointCount = event->pointCount(); + // Deliver to each eventpoint's passive grabbers (but don't visit any handler more than once) + int pointCount = event->pointCount(); + for (int i = 0; i < pointCount; ++i) { + QQuickEventPoint *point = event->point(i); + deliverToPassiveGrabbers(point->passiveGrabbers(), event); + } - // Deliver to each eventpoint's passive grabbers (but don't visit any handler more than once) + if (done) + return; + + // If some points weren't grabbed, deliver only to non-grabber PointerHandlers in reverse paint order + if (!event->allPointsGrabbed()) { + QVector<QQuickItem *> targetItems; for (int i = 0; i < pointCount; ++i) { QQuickEventPoint *point = event->point(i); - deliverToPassiveGrabbers(point->passiveGrabbers(), event); - } - - // If some points weren't grabbed, deliver to non-grabber PointerHandlers in reverse paint order - if (!event->allPointsGrabbed()) { - QVector<QQuickItem *> targetItems; - for (int i = 0; i < pointCount; ++i) { - QQuickEventPoint *point = event->point(i); - if (point->state() == QQuickEventPoint::Pressed) - continue; // presses were delivered earlier; not the responsibility of deliverUpdatedTouchPoints - QVector<QQuickItem *> targetItemsForPoint = pointerTargets(contentItem, point->scenePosition(), false, false); - if (targetItems.count()) { - targetItems = mergePointerTargets(targetItems, targetItemsForPoint); - } else { - targetItems = targetItemsForPoint; - } - } - - for (QQuickItem *item: targetItems) { - if (grabbers.contains(item)) - continue; - QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item); - event->localize(item); - itemPrivate->handlePointerEvent(event, true); // avoid re-delivering to grabbers - if (event->allPointsGrabbed()) - break; + if (point->state() == QQuickEventPoint::Pressed) + continue; // presses were delivered earlier; not the responsibility of deliverUpdatedTouchPoints + QVector<QQuickItem *> targetItemsForPoint = pointerTargets(contentItem, point->scenePosition(), false, false); + if (targetItems.count()) { + targetItems = mergePointerTargets(targetItems, targetItemsForPoint); + } else { + targetItems = targetItemsForPoint; } } + for (QQuickItem *item : targetItems) { + if (grabbers.contains(item)) + continue; + QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item); + event->localize(item); + itemPrivate->handlePointerEvent(event, true); // avoid re-delivering to grabbers + if (event->allPointsGrabbed()) + break; + } } } @@ -2492,7 +2512,7 @@ bool QQuickWindowPrivate::deliverPressOrReleaseEvent(QQuickPointerEvent *event, continue; deliverMatchingPointsToItem(item, event, handlersOnly); if (event->allPointsAccepted()) - break; + handlersOnly = true; } return event->allPointsAccepted(); @@ -2507,13 +2527,12 @@ void QQuickWindowPrivate::deliverMatchingPointsToItem(QQuickItem *item, QQuickPo // Let the Item's handlers (if any) have the event first. // However, double click should never be delivered to handlers. if (!pointerEvent->isDoubleClickEvent()) { + bool wasAccepted = pointerEvent->allPointsAccepted(); itemPrivate->handlePointerEvent(pointerEvent); - allowDoubleClick = !(pointerEvent->asPointerMouseEvent() && pointerEvent->isPressEvent() && pointerEvent->allPointsAccepted()); + allowDoubleClick = wasAccepted || !(pointerEvent->asPointerMouseEvent() && pointerEvent->isPressEvent() && pointerEvent->allPointsAccepted()); } if (handlersOnly) return; - if (pointerEvent->allPointsAccepted() && !pointerEvent->isReleaseEvent()) - return; // If all points are released and the item is not the grabber, it doesn't get the event. // But if at least one point is still pressed, we might be in a potential gesture-takeover scenario. @@ -2525,8 +2544,6 @@ void QQuickWindowPrivate::deliverMatchingPointsToItem(QQuickItem *item, QQuickPo auto event = pointerEvent->asPointerMouseEvent(); if (event && item->acceptedMouseButtons() & event->button()) { auto point = event->point(0); - if (point->isAccepted()) - return; // The only reason to already have a mouse grabber here is // synthetic events - flickable sends one when setPressDelay is used. auto oldMouseGrabber = q->mouseGrabberItem(); @@ -2747,7 +2764,7 @@ QQuickItem *QQuickWindowPrivate::findCursorItem(QQuickItem *item, const QPointF if (itemPrivate->flags & QQuickItem::ItemClipsChildrenToShape) { QPointF p = item->mapFromScene(scenePos); if (!item->contains(p)) - return 0; + return nullptr; } if (itemPrivate->subtreeCursorEnabled) { @@ -2766,7 +2783,7 @@ QQuickItem *QQuickWindowPrivate::findCursorItem(QQuickItem *item, const QPointF if (item->contains(p)) return item; } - return 0; + return nullptr; } #endif @@ -2820,17 +2837,10 @@ bool QQuickWindowPrivate::sendFilteredPointerEventImpl(QQuickPointerEvent *event // get a touch event customized for delivery to filteringParent QScopedPointer<QTouchEvent> filteringParentTouchEvent(pte->touchEventForItem(receiver, true)); if (filteringParentTouchEvent) { - QVarLengthArray<QPair<QQuickPointerHandler *, QQuickEventPoint *>, 32> passiveGrabsToCancel; if (filteringParent->childMouseEventFilter(receiver, filteringParentTouchEvent.data())) { qCDebug(DBG_TOUCH) << "touch event intercepted by childMouseEventFilter of " << filteringParent; skipDelivery.append(filteringParent); for (auto point: qAsConst(filteringParentTouchEvent->touchPoints())) { - auto pointerEventPoint = pte->pointById(point.id()); - for (auto handler : pointerEventPoint->passiveGrabbers()) { - QPair<QQuickPointerHandler *, QQuickEventPoint *> grab(handler, pointerEventPoint); - if (!passiveGrabsToCancel.contains(grab)) - passiveGrabsToCancel.append(grab); - } QQuickEventPoint *pt = event->pointById(point.id()); pt->setAccepted(); pt->setGrabberItem(filteringParent); @@ -2876,12 +2886,6 @@ bool QQuickWindowPrivate::sendFilteredPointerEventImpl(QQuickPointerEvent *event touchMouseUnset = false; // We want to leave touchMouseId and touchMouseDevice set if (mouseEvent->isAccepted()) filteringParent->grabMouse(); - auto pointerEventPoint = pte->pointById(tp.id()); - for (auto handler : pointerEventPoint->passiveGrabbers()) { - QPair<QQuickPointerHandler *, QQuickEventPoint *> grab(handler, pointerEventPoint); - if (!passiveGrabsToCancel.contains(grab)) - passiveGrabsToCancel.append(grab); - } } filtered = true; } @@ -2897,8 +2901,6 @@ bool QQuickWindowPrivate::sendFilteredPointerEventImpl(QQuickPointerEvent *event } } } - for (auto grab : passiveGrabsToCancel) - grab.second->cancelPassiveGrab(grab.first); } } } @@ -2972,8 +2974,10 @@ void QQuickWindowPrivate::data_append(QQmlListProperty<QObject> *property, QObje if (!o) return; QQuickWindow *that = static_cast<QQuickWindow *>(property->object); - if (QQuickWindow *window = qmlobject_cast<QQuickWindow *>(o)) + if (QQuickWindow *window = qmlobject_cast<QQuickWindow *>(o)) { + qCDebug(lcTransient) << window << "is transient for" << that; window->setTransientParent(that); + } QQmlListProperty<QObject> itemProperty = QQuickItemPrivate::get(that->contentItem())->data(); itemProperty.append(&itemProperty, o); } @@ -3039,6 +3043,7 @@ void QQuickWindowPrivate::contextCreationFailureMessage(const QSurfaceFormat &fo #if QT_DEPRECATED_SINCE(5, 8) +// ### Qt6: remove /*! Propagates an event \a e to a QQuickItem \a item on the window. @@ -3048,7 +3053,6 @@ void QQuickWindowPrivate::contextCreationFailureMessage(const QSurfaceFormat &fo \deprecated */ -// ### Qt6: remove bool QQuickWindow::sendEvent(QQuickItem *item, QEvent *e) { Q_D(QQuickWindow); @@ -3105,15 +3109,15 @@ void QQuickWindowPrivate::cleanupNodesOnShutdown(QQuickItem *item) QQuickItemPrivate *p = QQuickItemPrivate::get(item); if (p->itemNodeInstance) { delete p->itemNodeInstance; - p->itemNodeInstance = 0; + p->itemNodeInstance = nullptr; if (p->extra.isAllocated()) { - p->extra->opacityNode = 0; - p->extra->clipNode = 0; - p->extra->rootNode = 0; + p->extra->opacityNode = nullptr; + p->extra->clipNode = nullptr; + p->extra->rootNode = nullptr; } - p->paintNode = 0; + p->paintNode = nullptr; p->dirty(QQuickItemPrivate::Window); } @@ -3125,7 +3129,7 @@ void QQuickWindowPrivate::cleanupNodesOnShutdown(QQuickItem *item) if (index >= 0) { const QMetaMethod &method = mo->method(index); // Skip functions named invalidateSceneGraph() in QML items. - if (strstr(method.enclosingMetaObject()->className(), "_QML_") == 0) + if (strstr(method.enclosingMetaObject()->className(), "_QML_") == nullptr) method.invoke(item, Qt::DirectConnection); } } @@ -3153,7 +3157,7 @@ void QQuickWindowPrivate::updateDirtyNodes() cleanupNodes(); QQuickItem *updateList = dirtyItemList; - dirtyItemList = 0; + dirtyItemList = nullptr; if (updateList) QQuickItemPrivate::get(updateList)->prevDirtyItem = &updateList; while (updateList) { @@ -3169,7 +3173,7 @@ void QQuickWindowPrivate::updateDirtyNodes() static inline QSGNode *qquickitem_before_paintNode(QQuickItemPrivate *d) { const QList<QQuickItem *> childItems = d->paintOrderChildItems(); - QQuickItem *before = 0; + QQuickItem *before = nullptr; for (int i=0; i<childItems.size(); ++i) { QQuickItemPrivate *dd = QQuickItemPrivate::get(childItems.at(i)); // Perform the same check as the in fetchNextNode below. @@ -3178,7 +3182,7 @@ static inline QSGNode *qquickitem_before_paintNode(QQuickItemPrivate *d) else break; } - return Q_UNLIKELY(before) ? QQuickItemPrivate::get(before)->itemNode() : 0; + return Q_UNLIKELY(before) ? QQuickItemPrivate::get(before)->itemNode() : nullptr; } static QSGNode *fetchNextNode(QQuickItemPrivate *itemPriv, int &ii, bool &returnedPaintNode) @@ -3210,7 +3214,7 @@ static QSGNode *fetchNextNode(QQuickItemPrivate *itemPriv, int &ii, bool &return return childPrivate->itemNode(); } - return 0; + return nullptr; } void QQuickWindowPrivate::updateDirtyNode(QQuickItem *item) @@ -3245,10 +3249,10 @@ void QQuickWindowPrivate::updateDirtyNode(QQuickItem *item) } bool clipEffectivelyChanged = (dirty & (QQuickItemPrivate::Clip | QQuickItemPrivate::Window)) && - ((item->clip() == false) != (itemPriv->clipNode() == 0)); + ((item->clip() == false) != (itemPriv->clipNode() == nullptr)); int effectRefCount = itemPriv->extra.isAllocated()?itemPriv->extra->effectRefCount:0; bool effectRefEffectivelyChanged = (dirty & (QQuickItemPrivate::EffectReference | QQuickItemPrivate::Window)) && - ((effectRefCount == 0) != (itemPriv->rootNode() == 0)); + ((effectRefCount == 0) != (itemPriv->rootNode() == nullptr)); if (clipEffectivelyChanged) { QSGNode *parent = itemPriv->opacityNode() ? (QSGNode *) itemPriv->opacityNode() : @@ -3256,7 +3260,7 @@ void QQuickWindowPrivate::updateDirtyNode(QQuickItem *item) QSGNode *child = itemPriv->rootNode(); if (item->clip()) { - Q_ASSERT(itemPriv->clipNode() == 0); + Q_ASSERT(itemPriv->clipNode() == nullptr); QQuickDefaultClipNode *clip = new QQuickDefaultClipNode(item->clipRect()); itemPriv->extra.value().clipNode = clip; clip->update(); @@ -3282,7 +3286,7 @@ void QQuickWindowPrivate::updateDirtyNode(QQuickItem *item) } delete itemPriv->clipNode(); - itemPriv->extra->clipNode = 0; + itemPriv->extra->clipNode = nullptr; } } @@ -3297,18 +3301,18 @@ void QQuickWindowPrivate::updateDirtyNode(QQuickItem *item) parent = itemPriv->itemNode(); if (itemPriv->extra.isAllocated() && itemPriv->extra->effectRefCount) { - Q_ASSERT(itemPriv->rootNode() == 0); + Q_ASSERT(itemPriv->rootNode() == nullptr); QSGRootNode *root = new QSGRootNode(); itemPriv->extra->rootNode = root; parent->reparentChildNodesTo(root); parent->appendChildNode(root); } else { - Q_ASSERT(itemPriv->rootNode() != 0); + Q_ASSERT(itemPriv->rootNode() != nullptr); QSGRootNode *root = itemPriv->rootNode(); parent->removeChildNode(root); root->reparentChildNodesTo(parent); delete itemPriv->rootNode(); - itemPriv->extra->rootNode = 0; + itemPriv->extra->rootNode = nullptr; } } @@ -3334,7 +3338,7 @@ void QQuickWindowPrivate::updateDirtyNode(QQuickItem *item) int added = 0; int removed = 0; int replaced = 0; - QSGNode *desiredNode = 0; + QSGNode *desiredNode = nullptr; while (currentNode && (desiredNode = fetchNextNode(itemPriv, ii, fetchedPaintNode))) { // uh oh... reality and our utopic paradise are diverging! @@ -3419,11 +3423,11 @@ void QQuickWindowPrivate::updateDirtyNode(QQuickItem *item) updatePaintNodeData.transformNode = itemPriv->itemNode(); itemPriv->paintNode = item->updatePaintNode(itemPriv->paintNode, &updatePaintNodeData); - Q_ASSERT(itemPriv->paintNode == 0 || - itemPriv->paintNode->parent() == 0 || + Q_ASSERT(itemPriv->paintNode == nullptr || + itemPriv->paintNode->parent() == nullptr || itemPriv->paintNode->parent() == itemPriv->childContainerNode()); - if (itemPriv->paintNode && itemPriv->paintNode->parent() == 0) { + if (itemPriv->paintNode && itemPriv->paintNode->parent() == nullptr) { QSGNode *before = qquickitem_before_paintNode(itemPriv); if (before && before->parent()) { Q_ASSERT(before->parent() == itemPriv->childContainerNode()); @@ -3434,7 +3438,7 @@ void QQuickWindowPrivate::updateDirtyNode(QQuickItem *item) } } else if (itemPriv->paintNode) { delete itemPriv->paintNode; - itemPriv->paintNode = 0; + itemPriv->paintNode = nullptr; } } @@ -3486,14 +3490,14 @@ void QQuickWindow::cleanupSceneGraph() Q_D(QQuickWindow); #if QT_CONFIG(opengl) delete d->vaoHelper; - d->vaoHelper = 0; + d->vaoHelper = nullptr; #endif if (!d->renderer) return; delete d->renderer->rootNode(); delete d->renderer; - d->renderer = 0; + d->renderer = nullptr; d->runAndClearJobs(&d->beforeSynchronizingJobs); d->runAndClearJobs(&d->afterSynchronizingJobs); @@ -3504,6 +3508,7 @@ void QQuickWindow::cleanupSceneGraph() void QQuickWindow::setTransientParent_helper(QQuickWindow *window) { + qCDebug(lcTransient) << this << "is transient for" << window; setTransientParent(window); disconnect(sender(), SIGNAL(windowChanged(QQuickWindow*)), this, SLOT(setTransientParent_helper(QQuickWindow*))); @@ -3542,7 +3547,7 @@ QOpenGLContext *QQuickWindow::openglContext() const bool QQuickWindow::isSceneGraphInitialized() const { Q_D(const QQuickWindow); - return d->context != 0 && d->context->isValid(); + return d->context != nullptr && d->context->isValid(); } /*! @@ -3720,7 +3725,7 @@ void QQuickWindow::setRenderTarget(uint fboId, const QSize &size) d->renderTargetSize = size; // Unset any previously set instance... - d->renderTarget = 0; + d->renderTarget = nullptr; } @@ -3834,7 +3839,7 @@ QQmlIncubationController *QQuickWindow::incubationController() const Q_D(const QQuickWindow); if (!d->windowManager) - return 0; // TODO: make sure that this is safe + return nullptr; // TODO: make sure that this is safe if (!d->incubationController) d->incubationController = new QQuickWindowIncubationController(d->windowManager); @@ -4078,7 +4083,7 @@ bool QQuickWindow::clearBeforeRendering() const QSGTexture *QQuickWindow::createTextureFromImage(const QImage &image) const { - return createTextureFromImage(image, 0); + return createTextureFromImage(image, nullptr); } @@ -4127,7 +4132,7 @@ QSGTexture *QQuickWindow::createTextureFromImage(const QImage &image, CreateText { Q_D(const QQuickWindow); if (!isSceneGraphInitialized()) // check both for d->context and d->context->isValid() - return 0; + return nullptr; uint flags = 0; if (options & TextureCanUseAtlas) flags |= QSGRenderContext::CreateTexture_Atlas; if (options & TextureHasMipmaps) flags |= QSGRenderContext::CreateTexture_Mipmap; @@ -4173,7 +4178,7 @@ QSGTexture *QQuickWindow::createTextureFromId(uint id, const QSize &size, Create Q_UNUSED(size) Q_UNUSED(options) #endif - return 0; + return nullptr; } /*! @@ -4287,7 +4292,7 @@ void QQuickWindow::resetOpenGLState() int maxAttribs; gl->glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxAttribs); for (int i=0; i<maxAttribs; ++i) { - gl->glVertexAttribPointer(i, 4, GL_FLOAT, GL_FALSE, 0, 0); + gl->glVertexAttribPointer(i, 4, GL_FLOAT, GL_FALSE, 0, nullptr); gl->glDisableVertexAttribArray(i); } } @@ -4946,6 +4951,37 @@ void QQuickWindow::setTextRenderType(QQuickWindow::TextRenderType renderType) QQuickWindowPrivate::textRenderType = renderType; } +#ifndef QT_NO_DEBUG_STREAM +QDebug operator<<(QDebug debug, const QQuickWindow *win) +{ + QDebugStateSaver saver(debug); + debug.nospace(); + if (!win) { + debug << "QQuickWindow(0)"; + return debug; + } + + debug << win->metaObject()->className() << '(' << static_cast<const void *>(win); + if (win->isActive()) + debug << " active"; + if (win->isExposed()) + debug << " exposed"; + debug << ", visibility=" << win->visibility() << ", flags=" << win->flags(); + if (!win->title().isEmpty()) + debug << ", title=" << win->title(); + if (!win->objectName().isEmpty()) + debug << ", name=" << win->objectName(); + if (win->parent()) + debug << ", parent=" << static_cast<const void *>(win->parent()); + if (win->transientParent()) + debug << ", transientParent=" << static_cast<const void *>(win->transientParent()); + debug << ", geometry="; + QtDebugUtils::formatQRect(debug, win->geometry()); + debug << ')'; + return debug; +} +#endif + #include "moc_qquickwindow.cpp" QT_END_NAMESPACE diff --git a/src/quick/items/qquickwindow.h b/src/quick/items/qquickwindow.h index e5b54c8fb9..817178fdac 100644 --- a/src/quick/items/qquickwindow.h +++ b/src/quick/items/qquickwindow.h @@ -110,7 +110,7 @@ public: explicit QQuickWindow(QWindow *parent = nullptr); explicit QQuickWindow(QQuickRenderControl *renderControl); - virtual ~QQuickWindow(); + ~QQuickWindow() override; QQuickItem *contentItem() const; @@ -204,6 +204,7 @@ public Q_SLOTS: protected: QQuickWindow(QQuickWindowPrivate &dd, QWindow *parent = nullptr); + QQuickWindow(QQuickWindowPrivate &dd, QQuickRenderControl *control); void exposeEvent(QExposeEvent *) override; void resizeEvent(QResizeEvent *) override; @@ -233,7 +234,7 @@ private Q_SLOTS: void handleScreenChanged(QScreen *screen); void setTransientParent_helper(QQuickWindow *window); void runJobsAfterSwap(); - + void handleApplicationStateChanged(Qt::ApplicationState state); private: friend class QQuickItem; friend class QQuickWidget; @@ -242,6 +243,10 @@ private: Q_DISABLE_COPY(QQuickWindow) }; +#ifndef QT_NO_DEBUG_STREAM +QDebug Q_QUICK_EXPORT operator<<(QDebug debug, const QQuickWindow *item); +#endif + QT_END_NAMESPACE Q_DECLARE_METATYPE(QQuickWindow *) diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h index 8ac6cdfa36..82c01e7f54 100644 --- a/src/quick/items/qquickwindow_p.h +++ b/src/quick/items/qquickwindow_p.h @@ -114,9 +114,9 @@ public: static inline QQuickWindowPrivate *get(QQuickWindow *c) { return c->d_func(); } QQuickWindowPrivate(); - virtual ~QQuickWindowPrivate(); + ~QQuickWindowPrivate() override; - void init(QQuickWindow *, QQuickRenderControl *control = 0); + void init(QQuickWindow *, QQuickRenderControl *control = nullptr); QQuickRootItem *contentItem; QSet<QQuickItem *> parentlessItems; @@ -141,11 +141,12 @@ public: // Mouse positions are saved in widget coordinates QPointF lastMousePosition; bool deliverTouchAsMouse(QQuickItem *item, QQuickPointerEvent *pointerEvent); + bool isDeliveringTouchAsMouse() const { return touchMouseId != -1 && touchMouseDevice; } void translateTouchEvent(QTouchEvent *touchEvent); - void setMouseGrabber(QQuickItem *grabber); void grabTouchPoints(QObject *grabber, const QVector<int> &ids); void removeGrabber(QQuickItem *grabber, bool mouse = true, bool touch = true); - static QMouseEvent *cloneMouseEvent(QMouseEvent *event, QPointF *transformedLocalPos = 0); + void sendUngrabEvent(QQuickItem *grabber, bool touch); + static QMouseEvent *cloneMouseEvent(QMouseEvent *event, QPointF *transformedLocalPos = nullptr); void deliverToPassiveGrabbers(const QVector<QPointer <QQuickPointerHandler> > &passiveGrabbers, QQuickPointerEvent *pointerEvent); void deliverMouseEvent(QQuickPointerMouseEvent *pointerEvent); bool sendFilteredMouseEvent(QEvent *event, QQuickItem *receiver, QQuickItem *filteringParent); @@ -167,6 +168,7 @@ public: // the device-specific event instances which are reused during event delivery mutable QVector<QQuickPointerEvent *> pointerEventInstances; + QQuickPointerEvent *queryPointerEventInstance(QQuickPointerDevice *device, QEvent::Type eventType = QEvent::None) const; QQuickPointerEvent *pointerEventInstance(QQuickPointerDevice *device, QEvent::Type eventType = QEvent::None) const; // delivery of pointer events: @@ -203,8 +205,8 @@ public: }; Q_DECLARE_FLAGS(FocusOptions, FocusOption) - void setFocusInScope(QQuickItem *scope, QQuickItem *item, Qt::FocusReason reason, FocusOptions = 0); - void clearFocusInScope(QQuickItem *scope, QQuickItem *item, Qt::FocusReason reason, FocusOptions = 0); + void setFocusInScope(QQuickItem *scope, QQuickItem *item, Qt::FocusReason reason, FocusOptions = nullptr); + void clearFocusInScope(QQuickItem *scope, QQuickItem *item, Qt::FocusReason reason, FocusOptions = nullptr); static void notifyFocusChangesRecur(QQuickItem **item, int remaining); void clearFocusObject() override; diff --git a/src/quick/items/qquickwindowattached.cpp b/src/quick/items/qquickwindowattached.cpp index d3835ed45c..37f0a812e7 100644 --- a/src/quick/items/qquickwindowattached.cpp +++ b/src/quick/items/qquickwindowattached.cpp @@ -47,7 +47,7 @@ QT_BEGIN_NAMESPACE QQuickWindowAttached::QQuickWindowAttached(QObject* attachee) : QObject(attachee) - , m_window(NULL) + , m_window(nullptr) { m_attachee = qobject_cast<QQuickItem*>(attachee); if (m_attachee && m_attachee->window()) // It might not be in a window yet diff --git a/src/quick/items/qquickwindowmodule.cpp b/src/quick/items/qquickwindowmodule.cpp index 45e3f0004d..ab3f49d5b6 100644 --- a/src/quick/items/qquickwindowmodule.cpp +++ b/src/quick/items/qquickwindowmodule.cpp @@ -52,6 +52,8 @@ QT_BEGIN_NAMESPACE +Q_DECLARE_LOGGING_CATEGORY(lcTransient) + class QQuickWindowQmlImplPrivate : public QQuickWindowPrivate { public: @@ -112,7 +114,7 @@ void QQuickWindowQmlImpl::classBegin() { // The content item has CppOwnership policy (set in QQuickWindow). Ensure the presence of a JS // wrapper so that the garbage collector can see the policy. - QV4::ExecutionEngine *v4 = QQmlEnginePrivate::getV4Engine(e); + QV4::ExecutionEngine *v4 = e->handle(); QV4::QObjectWrapper::wrap(v4, d->contentItem); } } @@ -121,7 +123,13 @@ void QQuickWindowQmlImpl::componentComplete() { Q_D(QQuickWindowQmlImpl); d->complete = true; - if (transientParent() && !transientParent()->isVisible()) { + QQuickItem *itemParent = qmlobject_cast<QQuickItem *>(QObject::parent()); + if (itemParent && !itemParent->window()) { + qCDebug(lcTransient) << "window" << title() << "has invisible Item parent" << itemParent << "transientParent" + << transientParent() << "declared visibility" << d->visibility << "; delaying show"; + connect(itemParent, &QQuickItem::windowChanged, this, + &QQuickWindowQmlImpl::setWindowVisibility, Qt::QueuedConnection); + } else if (transientParent() && !transientParent()->isVisible()) { connect(transientParent(), &QQuickWindow::visibleChanged, this, &QQuickWindowQmlImpl::setWindowVisibility, Qt::QueuedConnection); } else { @@ -135,9 +143,10 @@ void QQuickWindowQmlImpl::setWindowVisibility() if (transientParent() && !transientParent()->isVisible()) return; - if (sender()) { - disconnect(transientParent(), &QWindow::visibleChanged, this, - &QQuickWindowQmlImpl::setWindowVisibility); + if (QQuickItem *senderItem = qmlobject_cast<QQuickItem *>(sender())) { + disconnect(senderItem, &QQuickItem::windowChanged, this, &QQuickWindowQmlImpl::setWindowVisibility); + } else if (sender()) { + disconnect(transientParent(), &QWindow::visibleChanged, this, &QQuickWindowQmlImpl::setWindowVisibility); } // We have deferred window creation until we have the full picture of what diff --git a/src/quick/qtquick2.cpp b/src/quick/qtquick2.cpp index 00fc23645b..24467a3701 100644 --- a/src/quick/qtquick2.cpp +++ b/src/quick/qtquick2.cpp @@ -140,7 +140,7 @@ void QQmlQtQuick2DebugStatesDelegate::updateBinding(QQmlContext *context, if (state->isStateActive() && state->containsPropertyInRevertList(object, propertyName)) { *inBaseState = false; - QQmlBinding *newBinding = 0; + QQmlBinding *newBinding = nullptr; if (!isLiteralValue) { newBinding = QQmlBinding::create(&QQmlPropertyPrivate::get(property)->core, expression.toString(), object, diff --git a/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp b/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp index 02cf8209d1..d715d900ba 100644 --- a/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp @@ -193,6 +193,12 @@ QRegion QSGAbstractSoftwareRenderer::optimizeRenderList() } } + if (m_obscuredRegion.contains(m_background->rect().toAlignedRect())) { + m_isOpaque = true; + } else { + m_isOpaque = false; + } + // Empty dirtyRegion (for second pass) m_dirtyRegion = QRegion(); m_obscuredRegion = QRegion(); @@ -227,11 +233,11 @@ void QSGAbstractSoftwareRenderer::setBackgroundColor(const QColor &color) renderableNode(m_background)->markMaterialDirty(); } -void QSGAbstractSoftwareRenderer::setBackgroundSize(const QSize &size) +void QSGAbstractSoftwareRenderer::setBackgroundRect(const QRect &rect) { - if (m_background->rect().size().toSize() == size) + if (m_background->rect().toRect() == rect) return; - m_background->setRect(0.0f, 0.0f, size.width(), size.height()); + m_background->setRect(rect); renderableNode(m_background)->markGeometryDirty(); // Invalidate the whole scene when the background is resized markDirty(); @@ -242,21 +248,21 @@ QColor QSGAbstractSoftwareRenderer::backgroundColor() return m_background->color(); } -QSize QSGAbstractSoftwareRenderer::backgroundSize() +QRect QSGAbstractSoftwareRenderer::backgroundRect() { - return m_background->rect().size().toSize(); + return m_background->rect().toRect(); } void QSGAbstractSoftwareRenderer::nodeAdded(QSGNode *node) { - qCDebug(lc2DRender) << "nodeAdded" << (void*)node; + qCDebug(lc2DRender, "nodeAdded %p", (void*)node); m_nodeUpdater->updateNodes(node); } void QSGAbstractSoftwareRenderer::nodeRemoved(QSGNode *node) { - qCDebug(lc2DRender) << "nodeRemoved" << (void*)node; + qCDebug(lc2DRender, "nodeRemoved %p", (void*)node); auto renderable = renderableNode(node); // remove mapping @@ -280,7 +286,7 @@ void QSGAbstractSoftwareRenderer::nodeRemoved(QSGNode *node) void QSGAbstractSoftwareRenderer::nodeGeometryUpdated(QSGNode *node) { - qCDebug(lc2DRender) << "nodeGeometryUpdated"; + qCDebug(lc2DRender, "nodeGeometryUpdated"); // Mark node as dirty auto renderable = renderableNode(node); @@ -293,7 +299,7 @@ void QSGAbstractSoftwareRenderer::nodeGeometryUpdated(QSGNode *node) void QSGAbstractSoftwareRenderer::nodeMaterialUpdated(QSGNode *node) { - qCDebug(lc2DRender) << "nodeMaterialUpdated"; + qCDebug(lc2DRender, "nodeMaterialUpdated"); // Mark node as dirty auto renderable = renderableNode(node); @@ -306,7 +312,7 @@ void QSGAbstractSoftwareRenderer::nodeMaterialUpdated(QSGNode *node) void QSGAbstractSoftwareRenderer::nodeMatrixUpdated(QSGNode *node) { - qCDebug(lc2DRender) << "nodeMaterialUpdated"; + qCDebug(lc2DRender, "nodeMaterialUpdated"); // Update children nodes m_nodeUpdater->updateNodes(node); @@ -314,7 +320,7 @@ void QSGAbstractSoftwareRenderer::nodeMatrixUpdated(QSGNode *node) void QSGAbstractSoftwareRenderer::nodeOpacityUpdated(QSGNode *node) { - qCDebug(lc2DRender) << "nodeOpacityUpdated"; + qCDebug(lc2DRender, "nodeOpacityUpdated"); // Update children nodes m_nodeUpdater->updateNodes(node); diff --git a/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h b/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h index 04a17ea377..f6594d931a 100644 --- a/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h +++ b/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h @@ -83,9 +83,11 @@ protected: QRegion optimizeRenderList(); void setBackgroundColor(const QColor &color); - void setBackgroundSize(const QSize &size); + void setBackgroundRect(const QRect &rect); QColor backgroundColor(); - QSize backgroundSize(); + QRect backgroundRect(); + // only known after calling optimizeRenderList() + bool isOpaque() const { return m_isOpaque; } private: void nodeAdded(QSGNode *node); @@ -102,6 +104,7 @@ private: QRegion m_dirtyRegion; QRegion m_obscuredRegion; + bool m_isOpaque = false; QSGSoftwareRenderableNodeUpdater *m_nodeUpdater; }; diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwareadaptation.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwareadaptation.cpp index 92c02b4966..a8b5944974 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwareadaptation.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwareadaptation.cpp @@ -87,6 +87,6 @@ QSGRenderLoop *QSGSoftwareAdaptation::createWindowManager() return new QSGSoftwareRenderLoop(); } -QSGSoftwareContext *QSGSoftwareAdaptation::instance = 0; +QSGSoftwareContext *QSGSoftwareAdaptation::instance = nullptr; QT_END_NAMESPACE diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwareadaptation_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwareadaptation_p.h index ffe54b5d4b..8b2a545033 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwareadaptation_p.h +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwareadaptation_p.h @@ -62,7 +62,7 @@ class QSGSoftwareContext; class QSGSoftwareAdaptation : public QSGContextPlugin { public: - QSGSoftwareAdaptation(QObject *parent = 0); + QSGSoftwareAdaptation(QObject *parent = nullptr); QStringList keys() const override; QSGContext *create(const QString &key) const override; diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp index aa850a80db..5b5bf005d8 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp @@ -205,12 +205,12 @@ QSGRendererInterface::ShaderType QSGSoftwareContext::shaderType() const QSGRendererInterface::ShaderCompilationTypes QSGSoftwareContext::shaderCompilationType() const { - return 0; + return nullptr; } QSGRendererInterface::ShaderSourceTypes QSGSoftwareContext::shaderSourceType() const { - return 0; + return nullptr; } void *QSGSoftwareContext::getResource(QQuickWindow *window, Resource resource) const diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode.cpp index 10291b9cb5..3b0f3c48ff 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode.cpp @@ -318,7 +318,7 @@ void qDrawBorderPixmap(QPainter *painter, const QRect &targetRect, const QMargin QSGSoftwareInternalImageNode::QSGSoftwareInternalImageNode() : m_innerSourceRect(0, 0, 1, 1) , m_subSourceRect(0, 0, 1, 1) - , m_texture(0) + , m_texture(nullptr) , m_mirror(false) , m_smooth(true) , m_tileHorizontal(false) @@ -462,7 +462,7 @@ void QSGSoftwareInternalImageNode::paint(QPainter *painter) m_targetRect.right() - m_innerTargetRect.right(), m_targetRect.bottom() - m_innerTargetRect.bottom()); QSGSoftwareHelpers::QTileRules tilerules(getTileRule(m_subSourceRect.width()), getTileRule(m_subSourceRect.height())); QSGSoftwareHelpers::qDrawBorderPixmap(painter, m_targetRect.toRect(), margins, pm, QRect(0, 0, pm.width(), pm.height()), - margins, tilerules, QSGSoftwareHelpers::QDrawBorderPixmap::DrawingHints(0)); + margins, tilerules, QSGSoftwareHelpers::QDrawBorderPixmap::DrawingHints(nullptr)); return; } @@ -490,12 +490,13 @@ QRectF QSGSoftwareInternalImageNode::rect() const const QPixmap &QSGSoftwareInternalImageNode::pixmap() const { - if (QSGSoftwarePixmapTexture *pt = qobject_cast<QSGSoftwarePixmapTexture*>(m_texture)) { + if (QSGSoftwarePixmapTexture *pt = qobject_cast<QSGSoftwarePixmapTexture*>(m_texture)) return pt->pixmap(); - } else { - QSGSoftwareLayer *layer = qobject_cast<QSGSoftwareLayer*>(m_texture); + if (QSGSoftwareLayer *layer = qobject_cast<QSGSoftwareLayer*>(m_texture)) return layer->pixmap(); - } + Q_ASSERT(m_texture == nullptr); + static const QPixmap nullPixmap; + return nullPixmap; } QT_END_NAMESPACE diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode_p.h index f21667fdf7..5c95eb064a 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode_p.h +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode_p.h @@ -124,8 +124,8 @@ public: QRectF rect() const; -private: const QPixmap &pixmap() const; +private: QRectF m_targetRect; QRectF m_innerTargetRect; diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode.cpp index f6898b3879..bf3141bc32 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode.cpp @@ -227,8 +227,8 @@ void QSGSoftwareInternalRectangleNode::paint(QPainter *painter) { //We can only check for a device pixel ratio change when we know what //paint device is being used. - if (painter->device()->devicePixelRatio() != m_devicePixelRatio) { - m_devicePixelRatio = painter->device()->devicePixelRatio(); + if (!qFuzzyCompare(painter->device()->devicePixelRatioF(), m_devicePixelRatio)) { + m_devicePixelRatio = painter->device()->devicePixelRatioF(); generateCornerPixmap(); } @@ -245,7 +245,7 @@ void QSGSoftwareInternalRectangleNode::paint(QPainter *painter) } else { //Rounded Rects and Rects with Borders //Avoids broken behaviors of QPainter::drawRect/roundedRect - QPixmap pixmap = QPixmap(m_rect.width() * m_devicePixelRatio, m_rect.height() * m_devicePixelRatio); + QPixmap pixmap = QPixmap(qRound(m_rect.width() * m_devicePixelRatio), qRound(m_rect.height() * m_devicePixelRatio)); pixmap.fill(Qt::transparent); pixmap.setDevicePixelRatio(m_devicePixelRatio); QPainter pixmapPainter(&pixmap); @@ -356,7 +356,7 @@ void QSGSoftwareInternalRectangleNode::paintRectangle(QPainter *painter, const Q } else { //blit 4 corners to border - int scaledRadius = radius * m_devicePixelRatio; + int scaledRadius = qRound(radius * m_devicePixelRatio); QRectF topLeftCorner(QPointF(rect.x(), rect.y()), QPointF(rect.x() + radius, rect.y() + radius)); painter->drawPixmap(topLeftCorner, m_cornerPixmap, QRectF(0, 0, scaledRadius, scaledRadius)); @@ -416,7 +416,7 @@ void QSGSoftwareInternalRectangleNode::generateCornerPixmap() //Generate new corner Pixmap int radius = qFloor(qMin(qMin(m_rect.width(), m_rect.height()) * 0.5, m_radius)); - m_cornerPixmap = QPixmap(radius * 2 * m_devicePixelRatio, radius * 2 * m_devicePixelRatio); + m_cornerPixmap = QPixmap(qRound(radius * 2 * m_devicePixelRatio), qRound(radius * 2 * m_devicePixelRatio)); m_cornerPixmap.setDevicePixelRatio(m_devicePixelRatio); m_cornerPixmap.fill(Qt::transparent); diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode_p.h index f363e279e1..1f87424d2a 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode_p.h +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode_p.h @@ -95,7 +95,7 @@ private: bool m_cornerPixmapIsDirty; QPixmap m_cornerPixmap; - int m_devicePixelRatio; + qreal m_devicePixelRatio; }; QT_END_NAMESPACE diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer.cpp index bd5d8f72c0..b4301451d8 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer.cpp @@ -45,9 +45,9 @@ QT_BEGIN_NAMESPACE QSGSoftwareLayer::QSGSoftwareLayer(QSGRenderContext *renderContext) - : m_item(0) + : m_item(nullptr) , m_context(renderContext) - , m_renderer(0) + , m_renderer(nullptr) , m_device_pixel_ratio(1) , m_mirrorHorizontal(false) , m_mirrorVertical(true) @@ -203,7 +203,7 @@ void QSGSoftwareLayer::markDirtyTexture() void QSGSoftwareLayer::invalidated() { delete m_renderer; - m_renderer = 0; + m_renderer = nullptr; } void QSGSoftwareLayer::grab() @@ -229,9 +229,6 @@ void QSGSoftwareLayer::grab() if (m_pixmap.size() != m_size) { m_pixmap = QPixmap(m_size); m_pixmap.setDevicePixelRatio(m_device_pixel_ratio); - // This fill here is wasteful, but necessary because it is the only way - // to force a QImage based pixmap to have an alpha channel. - m_pixmap.fill(Qt::transparent); } // Render texture. diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarepainternode.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarepainternode.cpp index 34b0cd5b72..60ae06dd94 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarepainternode.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarepainternode.cpp @@ -47,7 +47,7 @@ QSGSoftwarePainterNode::QSGSoftwarePainterNode(QQuickPaintedItem *item) : QSGPainterNode() , m_preferredRenderTarget(QQuickPaintedItem::Image) , m_item(item) - , m_texture(0) + , m_texture(nullptr) , m_dirtyContents(false) , m_opaquePainting(false) , m_linear_filtering(false) diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer.cpp index ad6cf39425..303f98c801 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer.cpp @@ -79,16 +79,9 @@ void QSGSoftwarePixmapRenderer::render(QPaintDevice *target) QElapsedTimer renderTimer; // Setup background item - setBackgroundSize(QSize(target->width(), target->height())); + setBackgroundRect(m_projectionRect); setBackgroundColor(clearColor()); - QPainter painter(target); - painter.setRenderHint(QPainter::Antialiasing); - painter.setWindow(m_projectionRect); - auto rc = static_cast<QSGSoftwareRenderContext *>(context()); - QPainter *prevPainter = rc->m_activePainter; - rc->m_activePainter = &painter; - renderTimer.start(); buildRenderList(); qint64 buildRenderListTime = renderTimer.restart(); @@ -101,6 +94,19 @@ void QSGSoftwarePixmapRenderer::render(QPaintDevice *target) optimizeRenderList(); qint64 optimizeRenderListTime = renderTimer.restart(); + if (!isOpaque() && target->devType() == QInternal::Pixmap) { + // This fill here is wasteful, but necessary because it is the only way + // to force a QImage based pixmap to have an alpha channel. + static_cast<QPixmap *>(target)->fill(Qt::transparent); + } + + QPainter painter(target); + painter.setRenderHint(QPainter::Antialiasing); + painter.setWindow(m_projectionRect); + auto rc = static_cast<QSGSoftwareRenderContext *>(context()); + QPainter *prevPainter = rc->m_activePainter; + rc->m_activePainter = &painter; + QRegion paintedRegion = renderNodes(&painter); qint64 renderTime = renderTimer.elapsed(); diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes.cpp index 77d21ec042..1463681fa3 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes.cpp @@ -188,7 +188,7 @@ void QSGSoftwareNinePatchNode::paint(QPainter *painter) painter->drawPixmap(m_bounds, m_pixmap, QRectF(0, 0, m_pixmap.width(), m_pixmap.height())); else QSGSoftwareHelpers::qDrawBorderPixmap(painter, m_bounds.toRect(), m_margins, m_pixmap, QRect(0, 0, m_pixmap.width(), m_pixmap.height()), - m_margins, Qt::StretchTile, QSGSoftwareHelpers::QDrawBorderPixmap::DrawingHints(0)); + m_margins, Qt::StretchTile, QSGSoftwareHelpers::QDrawBorderPixmap::DrawingHints(nullptr)); } QRectF QSGSoftwareNinePatchNode::bounds() const diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes_p.h index 9f1913205b..114137fb55 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes_p.h +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes_p.h @@ -133,6 +133,8 @@ public: QRectF bounds() const; + bool isOpaque() const { return !m_pixmap.hasAlphaChannel(); } + private: QPixmap m_pixmap; QRectF m_bounds; diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenode.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenode.cpp index cecc6c21ca..7fb531cca3 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenode.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenode.cpp @@ -134,73 +134,58 @@ void QSGSoftwareRenderableNode::update() { // Update the Node properties m_isDirty = true; + m_isOpaque = false; QRectF boundingRect; switch (m_nodeType) { case QSGSoftwareRenderableNode::SimpleRect: - if (m_handle.simpleRectNode->color().alpha() == 255 && !m_transform.isRotating()) + if (m_handle.simpleRectNode->color().alpha() == 255) m_isOpaque = true; - else - m_isOpaque = false; boundingRect = m_handle.simpleRectNode->rect(); break; case QSGSoftwareRenderableNode::SimpleTexture: - if (!m_handle.simpleTextureNode->texture()->hasAlphaChannel() && !m_transform.isRotating()) + if (!m_handle.simpleTextureNode->texture()->hasAlphaChannel()) m_isOpaque = true; - else - m_isOpaque = false; boundingRect = m_handle.simpleTextureNode->rect(); break; case QSGSoftwareRenderableNode::Image: - // There isn't a way to tell, so assume it's not - m_isOpaque = false; + m_isOpaque = !m_handle.imageNode->pixmap().hasAlphaChannel(); boundingRect = m_handle.imageNode->rect().toRect(); break; case QSGSoftwareRenderableNode::Painter: - if (m_handle.painterNode->opaquePainting() && !m_transform.isRotating()) + if (m_handle.painterNode->opaquePainting()) m_isOpaque = true; - else - m_isOpaque = false; boundingRect = QRectF(0, 0, m_handle.painterNode->size().width(), m_handle.painterNode->size().height()); break; case QSGSoftwareRenderableNode::Rectangle: - if (m_handle.rectangleNode->isOpaque() && !m_transform.isRotating()) + if (m_handle.rectangleNode->isOpaque()) m_isOpaque = true; - else - m_isOpaque = false; boundingRect = m_handle.rectangleNode->rect(); break; case QSGSoftwareRenderableNode::Glyph: // Always has alpha - m_isOpaque = false; - boundingRect = m_handle.glpyhNode->boundingRect(); break; case QSGSoftwareRenderableNode::NinePatch: - // Difficult to tell, assume non-opaque - m_isOpaque = false; + m_isOpaque = m_handle.ninePatchNode->isOpaque(); boundingRect = m_handle.ninePatchNode->bounds(); break; case QSGSoftwareRenderableNode::SimpleRectangle: - if (m_handle.simpleRectangleNode->color().alpha() == 255 && !m_transform.isRotating()) + if (m_handle.simpleRectangleNode->color().alpha() == 255) m_isOpaque = true; - else - m_isOpaque = false; boundingRect = m_handle.simpleRectangleNode->rect(); break; case QSGSoftwareRenderableNode::SimpleImage: - if (!m_handle.simpleImageNode->texture()->hasAlphaChannel() && !m_transform.isRotating()) + if (!m_handle.simpleImageNode->texture()->hasAlphaChannel()) m_isOpaque = true; - else - m_isOpaque = false; boundingRect = m_handle.simpleImageNode->rect(); break; @@ -211,10 +196,8 @@ void QSGSoftwareRenderableNode::update() break; #endif case QSGSoftwareRenderableNode::RenderNode: - if (m_handle.renderNode->flags().testFlag(QSGRenderNode::OpaqueRendering) && !m_transform.isRotating()) + if (m_handle.renderNode->flags().testFlag(QSGRenderNode::OpaqueRendering)) m_isOpaque = true; - else - m_isOpaque = false; boundingRect = m_handle.renderNode->rect(); break; @@ -222,6 +205,9 @@ void QSGSoftwareRenderableNode::update() break; } + if (m_transform.isRotating()) + m_isOpaque = false; + const QRectF transformedRect = m_transform.mapRect(boundingRect); m_boundingRectMin = toRectMin(transformedRect); m_boundingRectMax = toRectMax(transformedRect); @@ -232,8 +218,9 @@ void QSGSoftwareRenderableNode::update() m_boundingRectMin = QRect(); m_boundingRectMax = QRect(); } else { - m_boundingRectMin = m_boundingRectMin.intersected(m_clipRegion.rects().constFirst()); - m_boundingRectMax = m_boundingRectMax.intersected(m_clipRegion.rects().constFirst()); + const auto rects = m_clipRegion.begin(); + m_boundingRectMin = m_boundingRectMin.intersected(rects[0]); + m_boundingRectMax = m_boundingRectMax.intersected(rects[0]); } } diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenodeupdater.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenodeupdater.cpp index 666f1d0616..fabecfcbb8 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenodeupdater.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenodeupdater.cpp @@ -83,7 +83,7 @@ void QSGSoftwareRenderableNodeUpdater::endVisit(QSGTransformNode *) bool QSGSoftwareRenderableNodeUpdater::visit(QSGClipNode *node) { // Make sure to translate the clip rect into world coordinates - if (m_clipState.count() == 0 || m_clipState.top().isNull()) { + if (m_clipState.count() == 0 || (m_clipState.count() == 1 && m_clipState.top().isNull())) { m_clipState.push(m_transformState.top().map(QRegion(node->clipRect().toRect()))); m_hasClip = true; } else { @@ -97,7 +97,7 @@ bool QSGSoftwareRenderableNodeUpdater::visit(QSGClipNode *node) void QSGSoftwareRenderableNodeUpdater::endVisit(QSGClipNode *) { m_clipState.pop(); - if (m_clipState.count() == 0 || m_clipState.top().isNull()) + if (m_clipState.count() == 0 || (m_clipState.count() == 1 && m_clipState.top().isNull())) m_hasClip = false; } diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer.cpp index 85d04fe136..ffcee5f56e 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer.cpp @@ -112,7 +112,8 @@ void QSGSoftwareRenderer::render() QElapsedTimer renderTimer; setBackgroundColor(clearColor()); - setBackgroundSize(QSize(m_paintDevice->width() / m_paintDevice->devicePixelRatio(), + setBackgroundRect(QRect(0, 0, + m_paintDevice->width() / m_paintDevice->devicePixelRatio(), m_paintDevice->height() / m_paintDevice->devicePixelRatio())); // Build Renderlist @@ -155,6 +156,7 @@ void QSGSoftwareRenderer::render() m_flushRegion = renderNodes(&painter); qint64 renderTime = renderTimer.elapsed(); + painter.end(); if (m_backingStore != nullptr) m_backingStore->endPaint(); diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp index 3f0d1383b9..423f5f7321 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp @@ -97,7 +97,6 @@ void QSGSoftwareRenderLoop::windowDestroyed(QQuickWindow *window) if (m_windows.size() == 0) { rc->invalidate(); - QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); } } diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp index 832b69d0cc..f8973af2fb 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp @@ -294,7 +294,7 @@ bool QSGSoftwareRenderThread::event(QEvent *e) } rc->invalidate(); QCoreApplication::processEvents(); - QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); + QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete); if (wme->destroying) delete wd->animationController; } @@ -456,7 +456,7 @@ void QSGSoftwareRenderThread::sync(bool inExpose) // Process deferred deletes now, directly after the sync as deleteLater // on the GUI must now also have resulted in SG changes and the delete // is a safe operation. - QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); + QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete); } if (!inExpose) { @@ -523,7 +523,7 @@ void QSGSoftwareRenderThread::syncAndRender() // rate of the current screen the window is on. int blockTime = vsyncDelta - (int) renderThrottleTimer.elapsed(); if (blockTime > 0) { - qCDebug(QSG_RASTER_LOG_RENDERLOOP) << "RT - blocking for " << blockTime << "ms"; + qCDebug(QSG_RASTER_LOG_RENDERLOOP, "RT - blocking for %d ms", blockTime); msleep(blockTime); } renderThrottleTimer.restart(); diff --git a/src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture.cpp b/src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture.cpp new file mode 100644 index 0000000000..e868a4380e --- /dev/null +++ b/src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture.cpp @@ -0,0 +1,174 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgcompressedatlastexture_p.h" + +#include <QtCore/QVarLengthArray> +#include <QtCore/QElapsedTimer> +#include <QtCore/QtMath> + +#include <QtGui/QOpenGLContext> +#include <QtGui/QGuiApplication> +#include <QtGui/QScreen> +#include <QtGui/QSurface> +#include <QtGui/QWindow> +#include <QtGui/QOpenGLFunctions> +#include <QtGui/QOpenGLTexture> +#include <QDebug> + +#include <private/qqmlglobal_p.h> +#include <private/qquickprofiler_p.h> +#include <private/qsgtexture_p.h> +#include <private/qsgcompressedtexture_p.h> +#include <private/qsgpkmhandler_p.h> + +QT_BEGIN_NAMESPACE + +static QElapsedTimer qsg_renderer_timer; + +namespace QSGCompressedAtlasTexture +{ + +Atlas::Atlas(const QSize &size, uint format) + : QSGAtlasTexture::AtlasBase(size) + , m_format(format) +{ +} + +Atlas::~Atlas() +{ +} + +Texture *Atlas::create(const QByteArray &data, int dataLength, int dataOffset, const QSize &size, const QSize &paddedSize) +{ + // No need to lock, as manager already locked it. + QRect rect = m_allocator.allocate(paddedSize); + if (rect.width() > 0 && rect.height() > 0) { + Texture *t = new Texture(this, rect, data, dataLength, dataOffset, size); + m_pending_uploads << t; + return t; + } + return nullptr; +} + +void Atlas::generateTexture() +{ + QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); + funcs->glCompressedTexImage2D(GL_TEXTURE_2D, 0, m_format, + m_size.width(), m_size.height(), 0, + (m_size.width() * m_size.height()) / 2, + nullptr); +} + +void Atlas::uploadPendingTexture(int i) +{ + Texture *texture = static_cast<Texture*>(m_pending_uploads.at(i)); + + const QRect &r = texture->atlasSubRect(); + + QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); + funcs->glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, + r.x(), r.y(), r.width(), r.height(), m_format, + texture->sizeInBytes(), + texture->data().constData() + texture->dataOffset()); + + qCDebug(QSG_LOG_TIME_TEXTURE).nospace() << "compressed atlastexture uploaded in: " << qsg_renderer_timer.elapsed() + << "ms (" << texture->textureSize().width() << "x" + << texture->textureSize().height() << ")"; + + // TODO: consider releasing the data (as is done in the regular atlas)? + // The advantage of keeping this data around is that it makes it much easier + // to remove the texture from the atlas +} + +Texture::Texture(Atlas *atlas, const QRect &textureRect, const QByteArray &data, int dataLength, int dataOffset, const QSize &size) + : QSGAtlasTexture::TextureBase(atlas, textureRect) + , m_nonatlas_texture(nullptr) + , m_data(data) + , m_size(size) + , m_dataLength(dataLength) + , m_dataOffset(dataOffset) +{ + float w = atlas->size().width(); + float h = atlas->size().height(); + QRect nopad = atlasSubRect(); + // offset by half-pixel to prevent bleeding when scaling + m_texture_coords_rect = QRectF((nopad.x() + .5) / w, + (nopad.y() + .5) / h, + (nopad.width() - 1.) / w, + (nopad.height() - 1.) / h); +} + +Texture::~Texture() +{ + delete m_nonatlas_texture; +} + +bool Texture::hasAlphaChannel() const +{ + return QSGCompressedTexture::formatIsOpaque(static_cast<Atlas*>(m_atlas)->format()); +} + +QSGTexture *Texture::removedFromAtlas() const +{ + if (m_nonatlas_texture) { + m_nonatlas_texture->setMipmapFiltering(mipmapFiltering()); + m_nonatlas_texture->setFiltering(filtering()); + return m_nonatlas_texture; + } + + if (!m_data.isEmpty()) { + QSGCompressedTexture::DataPtr texData(QSGCompressedTexture::DataPtr::create()); + texData->data = m_data; + texData->size = m_size; + texData->format = static_cast<Atlas*>(m_atlas)->format(); + texData->hasAlpha = hasAlphaChannel(); + texData->dataLength = m_dataLength; + texData->dataOffset = m_dataOffset; + m_nonatlas_texture = new QSGCompressedTexture(texData); + m_nonatlas_texture->setMipmapFiltering(mipmapFiltering()); + m_nonatlas_texture->setFiltering(filtering()); + } + + return m_nonatlas_texture; +} + +} + +QT_END_NAMESPACE diff --git a/src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture_p.h b/src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture_p.h new file mode 100644 index 0000000000..59e935b623 --- /dev/null +++ b/src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture_p.h @@ -0,0 +1,119 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSGCOMPRESSEDATLASTEXTURE_P_H +#define QSGCOMPRESSEDATLASTEXTURE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/QSize> + +#include <QtGui/qopengl.h> + +#include <QtQuick/QSGTexture> +#include <QtQuick/private/qsgareaallocator_p.h> +#include <QtQuick/private/qsgatlastexture_p.h> + +QT_BEGIN_NAMESPACE + +class QSGCompressedTextureFactory; + +namespace QSGCompressedAtlasTexture { + +class Texture; + +class Atlas : public QSGAtlasTexture::AtlasBase +{ +public: + Atlas(const QSize &size, uint format); + ~Atlas(); + + void generateTexture() override; + void uploadPendingTexture(int i) override; + + Texture *create(const QByteArray &data, int dataLength, int dataOffset, const QSize &size, const QSize &paddedSize); + + uint format() const { return m_format; } + +private: + uint m_format; +}; + +class Texture : public QSGAtlasTexture::TextureBase +{ + Q_OBJECT +public: + Texture(Atlas *atlas, const QRect &textureRect, const QByteArray &data, int dataLength, int dataOffset, const QSize &size); + ~Texture(); + + QSize textureSize() const override { return m_size; } + bool hasAlphaChannel() const override; + bool hasMipmaps() const override { return false; } + + QRectF normalizedTextureSubRect() const override { return m_texture_coords_rect; } + + QSGTexture *removedFromAtlas() const override; + + const QByteArray &data() const { return m_data; } + int sizeInBytes() const { return m_dataLength; } + int dataOffset() const { return m_dataOffset; } + +private: + QRectF m_texture_coords_rect; + mutable QSGTexture *m_nonatlas_texture; + QByteArray m_data; + QSize m_size; + int m_dataLength; + int m_dataOffset; +}; + +} + +QT_END_NAMESPACE + +#endif diff --git a/src/quick/scenegraph/compressedtexture/qsgcompressedtexture.cpp b/src/quick/scenegraph/compressedtexture/qsgcompressedtexture.cpp new file mode 100644 index 0000000000..839c562989 --- /dev/null +++ b/src/quick/scenegraph/compressedtexture/qsgcompressedtexture.cpp @@ -0,0 +1,246 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include "qsgcompressedtexture_p.h" +#include <QOpenGLContext> +#include <QOpenGLTexture> +#include <QOpenGLFunctions> +#include <QDebug> +#include <QtQuick/private/qquickwindow_p.h> + +QT_BEGIN_NAMESPACE + +Q_LOGGING_CATEGORY(QSG_LOG_TEXTUREIO, "qt.scenegraph.textureio"); + +bool QSGCompressedTextureData::isValid() const +{ + if (data.isNull() || size.isEmpty() || !format) + return false; + if (dataLength < 0 || dataOffset < 0 || dataOffset >= data.length()) + return false; + if (dataLength > 0 && qint64(dataOffset) + qint64(dataLength) > qint64(data.length())) + return false; + + return true; +} + +int QSGCompressedTextureData::sizeInBytes() const +{ + if (!isValid()) + return 0; + return dataLength > 0 ? dataLength : data.length() - dataOffset; +} + +Q_QUICK_PRIVATE_EXPORT QDebug operator<<(QDebug dbg, const QSGCompressedTextureData *d) +{ + QDebugStateSaver saver(dbg); + + dbg.nospace() << "QSGCompressedTextureData("; + if (d) { + dbg << d->logName << ' '; + dbg << static_cast<QOpenGLTexture::TextureFormat>(d->format) + << "[0x" << hex << d->format << dec << "]"; + dbg.space() << (d->hasAlpha ? "with" : "no") << "alpha" << d->size + << "databuffer" << d->data.size() << "offset" << d->dataOffset << "length"; + dbg.nospace() << d->dataLength << ")"; + } else { + dbg << "null)"; + } + return dbg; +} + +QSGCompressedTexture::QSGCompressedTexture(const DataPtr& texData) + : m_textureData(texData) +{ + if (m_textureData) { + m_size = m_textureData->size; + m_hasAlpha = m_textureData->hasAlpha; + } +} + +QSGCompressedTexture::~QSGCompressedTexture() +{ +#if QT_CONFIG(opengl) + if (m_textureId) { + QOpenGLContext *ctx = QOpenGLContext::currentContext(); + QOpenGLFunctions *funcs = ctx ? ctx->functions() : nullptr; + if (!funcs) + return; + + funcs->glDeleteTextures(1, &m_textureId); + } +#endif +} + +int QSGCompressedTexture::textureId() const +{ +#if QT_CONFIG(opengl) + if (!m_textureId) { + QOpenGLContext *ctx = QOpenGLContext::currentContext(); + QOpenGLFunctions *funcs = ctx ? ctx->functions() : nullptr; + if (!funcs) + return 0; + + funcs->glGenTextures(1, &m_textureId); + } +#endif + return m_textureId; +} + +QSize QSGCompressedTexture::textureSize() const +{ + return m_size; +} + +bool QSGCompressedTexture::hasAlphaChannel() const +{ + return m_hasAlpha; +} + +bool QSGCompressedTexture::hasMipmaps() const +{ + return false; +} + +void QSGCompressedTexture::bind() +{ +#if QT_CONFIG(opengl) + QOpenGLContext *ctx = QOpenGLContext::currentContext(); + QOpenGLFunctions *funcs = ctx ? ctx->functions() : nullptr; + if (!funcs) + return; + + if (!textureId()) + return; + + funcs->glBindTexture(GL_TEXTURE_2D, m_textureId); + + if (m_uploaded) + return; + + QByteArray logName(m_textureData ? m_textureData->logName : QByteArrayLiteral("(unset)")); + + if (!m_textureData || !m_textureData->isValid()) { + qCDebug(QSG_LOG_TEXTUREIO, "Invalid texture data for %s", logName.constData()); + funcs->glBindTexture(GL_TEXTURE_2D, 0); + return; + } + + if (Q_UNLIKELY(QSG_LOG_TEXTUREIO().isDebugEnabled())) { + qCDebug(QSG_LOG_TEXTUREIO) << "Uploading texture" << m_textureData.data(); + while (funcs->glGetError() != GL_NO_ERROR); + } + + funcs->glCompressedTexImage2D(GL_TEXTURE_2D, 0, m_textureData->format, + m_size.width(), m_size.height(), 0, m_textureData->sizeInBytes(), + m_textureData->data.constData() + m_textureData->dataOffset); + + if (Q_UNLIKELY(QSG_LOG_TEXTUREIO().isDebugEnabled())) { + GLuint error = funcs->glGetError(); + if (error != GL_NO_ERROR) { + qCDebug(QSG_LOG_TEXTUREIO, "glCompressedTexImage2D failed for %s, error 0x%x", logName.constData(), error); + } + } + + m_textureData.clear(); // Release this memory, not needed anymore + + updateBindOptions(true); + m_uploaded = true; +#endif // QT_CONFIG(opengl) +} + +bool QSGCompressedTexture::formatIsOpaque(quint32 glTextureFormat) +{ + switch (glTextureFormat) { + case QOpenGLTexture::RGB_DXT1: + case QOpenGLTexture::R_ATI1N_UNorm: + case QOpenGLTexture::R_ATI1N_SNorm: + case QOpenGLTexture::RG_ATI2N_UNorm: + case QOpenGLTexture::RG_ATI2N_SNorm: + case QOpenGLTexture::RGB_BP_UNSIGNED_FLOAT: + case QOpenGLTexture::RGB_BP_SIGNED_FLOAT: + case QOpenGLTexture::R11_EAC_UNorm: + case QOpenGLTexture::R11_EAC_SNorm: + case QOpenGLTexture::RG11_EAC_UNorm: + case QOpenGLTexture::RG11_EAC_SNorm: + case QOpenGLTexture::RGB8_ETC2: + case QOpenGLTexture::SRGB8_ETC2: + case QOpenGLTexture::RGB8_ETC1: + case QOpenGLTexture::SRGB_DXT1: + return true; + break; + default: + return false; + } +} + +QSGCompressedTextureFactory::QSGCompressedTextureFactory(const QSGCompressedTexture::DataPtr &texData) + : m_textureData(texData) +{ +} + +QSGTexture *QSGCompressedTextureFactory::createTexture(QQuickWindow *window) const +{ + if (!m_textureData || !m_textureData->isValid()) + return nullptr; + + // attempt to atlas the texture + QSGRenderContext *context = QQuickWindowPrivate::get(window)->context; + QSGTexture *t = context->compressedTextureForFactory(this); + if (t) + return t; + + return new QSGCompressedTexture(m_textureData); +} + +int QSGCompressedTextureFactory::textureByteCount() const +{ + return m_textureData ? m_textureData->sizeInBytes() : 0; +} + + +QSize QSGCompressedTextureFactory::textureSize() const +{ + if (m_textureData && m_textureData->isValid()) + return m_textureData->size; + return QSize(); +} + +QT_END_NAMESPACE diff --git a/src/quick/scenegraph/compressedtexture/qsgcompressedtexture_p.h b/src/quick/scenegraph/compressedtexture/qsgcompressedtexture_p.h new file mode 100644 index 0000000000..aa87316809 --- /dev/null +++ b/src/quick/scenegraph/compressedtexture/qsgcompressedtexture_p.h @@ -0,0 +1,126 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSGCOMPRESSEDTEXTURE_P_H +#define QSGCOMPRESSEDTEXTURE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QSGTexture> +#include <QtQuick/private/qsgcontext_p.h> +#include <QQuickTextureFactory> +#include <QOpenGLFunctions> + +QT_BEGIN_NAMESPACE + +struct Q_QUICK_PRIVATE_EXPORT QSGCompressedTextureData +{ + QByteArray logName; + QByteArray data; + QSize size; + uint format = 0; + int dataOffset = 0; + int dataLength = 0; + bool hasAlpha = false; + + bool isValid() const; + int sizeInBytes() const; +}; + +Q_QUICK_PRIVATE_EXPORT QDebug operator<<(QDebug, const QSGCompressedTextureData *); + + +class Q_QUICK_PRIVATE_EXPORT QSGCompressedTexture : public QSGTexture +{ + Q_OBJECT +public: + typedef QSharedPointer<QSGCompressedTextureData> DataPtr; + + QSGCompressedTexture(const DataPtr& texData); + virtual ~QSGCompressedTexture(); + + int textureId() const override; + QSize textureSize() const override; + bool hasAlphaChannel() const override; + bool hasMipmaps() const override; + + void bind() override; + + const QSGCompressedTextureData *textureData(); + + static bool formatIsOpaque(quint32 glTextureFormat); + +protected: + DataPtr m_textureData; + QSize m_size; + mutable uint m_textureId = 0; + bool m_hasAlpha = false; + bool m_uploaded = false; +}; + +namespace QSGAtlasTexture { + class Manager; +} + +class Q_QUICK_PRIVATE_EXPORT QSGCompressedTextureFactory : public QQuickTextureFactory +{ +public: + QSGCompressedTextureFactory(const QSGCompressedTexture::DataPtr& texData); + QSGTexture *createTexture(QQuickWindow *) const override; + int textureByteCount() const override; + QSize textureSize() const override; + +protected: + QSGCompressedTexture::DataPtr m_textureData; +private: + friend class QSGAtlasTexture::Manager; +}; + +QT_END_NAMESPACE + +#endif // QSGCOMPRESSEDTEXTURE_P_H diff --git a/src/quick/scenegraph/compressedtexture/qsgktxhandler.cpp b/src/quick/scenegraph/compressedtexture/qsgktxhandler.cpp new file mode 100644 index 0000000000..e3e4ca6824 --- /dev/null +++ b/src/quick/scenegraph/compressedtexture/qsgktxhandler.cpp @@ -0,0 +1,186 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgktxhandler_p.h" +#include "qsgcompressedtexture_p.h" +#include <QOpenGLTexture> +#include <QtEndian> + +//#define KTX_DEBUG + +QT_BEGIN_NAMESPACE + +#define KTX_IDENTIFIER_LENGTH 12 +static const char ktxIdentifier[KTX_IDENTIFIER_LENGTH] = { '\xAB', 'K', 'T', 'X', ' ', '1', '1', '\xBB', '\r', '\n', '\x1A', '\n' }; +static const quint32 platformEndianIdentifier = 0x04030201; +static const quint32 inversePlatformEndianIdentifier = 0x01020304; + +struct KTXHeader { + quint8 identifier[KTX_IDENTIFIER_LENGTH]; //Must match ktxIdentifier + quint32 endianness; //Either platformEndianIdentifier or inversePlatformEndianIdentifier, other values not allowed. + quint32 glType; + quint32 glTypeSize; + quint32 glFormat; + quint32 glInternalFormat; + quint32 glBaseInternalFormat; + quint32 pixelWidth; + quint32 pixelHeight; + quint32 pixelDepth; + quint32 numberOfArrayElements; + quint32 numberOfFaces; + quint32 numberOfMipmapLevels; + quint32 bytesOfKeyValueData; +}; + +static const int headerSize = sizeof(KTXHeader); + +// Currently unused, declared for future reference +struct KTXKeyValuePairItem { + quint32 keyAndValueByteSize; + /* + quint8 keyAndValue[keyAndValueByteSize]; + quint8 valuePadding[3 - ((keyAndValueByteSize + 3) % 4)]; + */ +}; + +struct KTXMipmapLevel { + quint32 imageSize; + /* + for each array_element in numberOfArrayElements* + for each face in numberOfFaces + for each z_slice in pixelDepth* + for each row or row_of_blocks in pixelHeight* + for each pixel or block_of_pixels in pixelWidth + Byte data[format-specific-number-of-bytes]** + end + end + end + Byte cubePadding[0-3] + end + end + quint8 mipPadding[3 - ((imageSize + 3) % 4)] + */ +}; + +bool QSGKtxHandler::canRead(const QByteArray &suffix, const QByteArray &block) +{ + Q_UNUSED(suffix) + + return (qstrncmp(block.constData(), ktxIdentifier, KTX_IDENTIFIER_LENGTH) == 0); +} + +QQuickTextureFactory *QSGKtxHandler::read() +{ + if (!device()) + return nullptr; + + QByteArray buf = device()->readAll(); + if (buf.size() < headerSize || !canRead(QByteArray(), buf)) { + qCDebug(QSG_LOG_TEXTUREIO, "Invalid KTX file %s", logName().constData()); + return nullptr; + } + + const KTXHeader *header = reinterpret_cast<const KTXHeader *>(buf.constData()); + if (!checkHeader(*header)) { + qCDebug(QSG_LOG_TEXTUREIO, "Unsupported KTX file format in %s", logName().constData()); + return nullptr; + } + + QSGCompressedTexture::DataPtr texData(QSGCompressedTexture::DataPtr::create()); + + texData->size = QSize(decode(header->pixelWidth), decode(header->pixelHeight)); + texData->format = decode(header->glInternalFormat); + texData->hasAlpha = !QSGCompressedTexture::formatIsOpaque(texData->format); + + // For now, ignore any additional mipmap levels + int preambleSize = headerSize + decode(header->bytesOfKeyValueData); + if (buf.size() >= preambleSize + int(sizeof(KTXMipmapLevel))) { + texData->data = buf; + texData->dataOffset = preambleSize + sizeof(quint32); // for the imageSize + const KTXMipmapLevel *level = reinterpret_cast<const KTXMipmapLevel *>(buf.constData() + preambleSize); + texData->dataLength = decode(level->imageSize); + } + + if (!texData->isValid()) { + qCDebug(QSG_LOG_TEXTUREIO, "Invalid values in header of KTX file %s", logName().constData()); + return nullptr; + } + + texData->logName = logName(); +#ifdef KTX_DEBUG + qDebug() << "KTX file handler read" << texData.data(); +#endif + + return new QSGCompressedTextureFactory(texData); +} + +bool QSGKtxHandler::checkHeader(const KTXHeader &header) +{ + if (header.endianness != platformEndianIdentifier && header.endianness != inversePlatformEndianIdentifier) + return false; + inverseEndian = (header.endianness == inversePlatformEndianIdentifier); +#ifdef KTX_DEBUG + QMetaEnum tfme = QMetaEnum::fromType<QOpenGLTexture::TextureFormat>(); + QMetaEnum ptme = QMetaEnum::fromType<QOpenGLTexture::PixelType>(); + qDebug("Header of %s:", logName().constData()); + qDebug(" glType: 0x%x (%s)", decode(header.glType), ptme.valueToKey(decode(header.glType))); + qDebug(" glTypeSize: %u", decode(header.glTypeSize)); + qDebug(" glFormat: 0x%x (%s)", decode(header.glFormat), tfme.valueToKey(decode(header.glFormat))); + qDebug(" glInternalFormat: 0x%x (%s)", decode(header.glInternalFormat), tfme.valueToKey(decode(header.glInternalFormat))); + qDebug(" glBaseInternalFormat: 0x%x (%s)", decode(header.glBaseInternalFormat), tfme.valueToKey(decode(header.glBaseInternalFormat))); + qDebug(" pixelWidth: %u", decode(header.pixelWidth)); + qDebug(" pixelHeight: %u", decode(header.pixelHeight)); + qDebug(" pixelDepth: %u", decode(header.pixelDepth)); + qDebug(" numberOfArrayElements: %u", decode(header.numberOfArrayElements)); + qDebug(" numberOfFaces: %u", decode(header.numberOfFaces)); + qDebug(" numberOfMipmapLevels: %u", decode(header.numberOfMipmapLevels)); + qDebug(" bytesOfKeyValueData: %u", decode(header.bytesOfKeyValueData)); +#endif + return ((decode(header.glType) == 0) && + (decode(header.glFormat) == 0) && + (decode(header.pixelDepth) == 0) && + (decode(header.numberOfFaces) == 1)); +} + +quint32 QSGKtxHandler::decode(quint32 val) +{ + return inverseEndian ? qbswap<quint32>(val) : val; +} + +QT_END_NAMESPACE diff --git a/src/quick/scenegraph/compressedtexture/qsgktxhandler_p.h b/src/quick/scenegraph/compressedtexture/qsgktxhandler_p.h new file mode 100644 index 0000000000..22f4db65b2 --- /dev/null +++ b/src/quick/scenegraph/compressedtexture/qsgktxhandler_p.h @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSGKTXHANDLER_H +#define QSGKTXHANDLER_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qsgtexturefilehandler_p.h" + +QT_BEGIN_NAMESPACE + +struct KTXHeader; + +class QSGKtxHandler : public QSGTextureFileHandler +{ +public: + using QSGTextureFileHandler::QSGTextureFileHandler; + + static bool canRead(const QByteArray &suffix, const QByteArray &block); + + QQuickTextureFactory *read() override; + +private: + bool checkHeader(const KTXHeader &header); + quint32 decode(quint32 val); + + bool inverseEndian = false; +}; + +QT_END_NAMESPACE + +#endif // QSGKTXHANDLER_H diff --git a/src/quick/scenegraph/compressedtexture/qsgpkmhandler.cpp b/src/quick/scenegraph/compressedtexture/qsgpkmhandler.cpp index bb8fce046d..618c0db045 100644 --- a/src/quick/scenegraph/compressedtexture/qsgpkmhandler.cpp +++ b/src/quick/scenegraph/compressedtexture/qsgpkmhandler.cpp @@ -38,172 +38,81 @@ ****************************************************************************/ #include "qsgpkmhandler_p.h" +#include "qsgcompressedtexture_p.h" #include <QFile> #include <QDebug> #include <qendian.h> #include <qopenglfunctions.h> #include <qqmlfile.h> +#include <QOpenGLTexture> //#define ETC_DEBUG -#ifndef GL_ETC1_RGB8_OES - #define GL_ETC1_RGB8_OES 0x8d64 -#endif - -#ifndef GL_COMPRESSED_RGB8_ETC2 - #define GL_COMPRESSED_RGB8_ETC2 0x9274 -#endif - -#ifndef GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 - #define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276 -#endif - -#ifndef GL_COMPRESSED_RGBA8_ETC2_EAC - #define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278 -#endif - QT_BEGIN_NAMESPACE static const int headerSize = 16; static unsigned int typeMap[5] = { - GL_ETC1_RGB8_OES, - GL_COMPRESSED_RGB8_ETC2, - 0, // unused - GL_COMPRESSED_RGBA8_ETC2_EAC, - GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 + QOpenGLTexture::RGB8_ETC1, // GL_ETC1_RGB8_OES, + QOpenGLTexture::RGB8_ETC2, // GL_COMPRESSED_RGB8_ETC2, + 0, // unused (obsolete) + QOpenGLTexture::RGBA8_ETC2_EAC, // GL_COMPRESSED_RGBA8_ETC2_EAC, + QOpenGLTexture::RGB8_PunchThrough_Alpha1_ETC2 // GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 }; -QEtcTexture::QEtcTexture() - : m_texture_id(0), m_uploaded(false) -{ - initializeOpenGLFunctions(); -} - -QEtcTexture::~QEtcTexture() -{ - if (m_texture_id) - glDeleteTextures(1, &m_texture_id); -} - -int QEtcTexture::textureId() const -{ - if (m_texture_id == 0) { - QEtcTexture *texture = const_cast<QEtcTexture*>(this); - texture->glGenTextures(1, &texture->m_texture_id); - } - return m_texture_id; -} - -bool QEtcTexture::hasAlphaChannel() const -{ - return m_type == GL_COMPRESSED_RGBA8_ETC2_EAC || - m_type == GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2; -} - - -void QEtcTexture::bind() +bool QSGPkmHandler::canRead(const QByteArray &suffix, const QByteArray &block) { - if (m_uploaded && m_texture_id) { - glBindTexture(GL_TEXTURE_2D, m_texture_id); - return; - } - - if (m_texture_id == 0) - glGenTextures(1, &m_texture_id); - glBindTexture(GL_TEXTURE_2D, m_texture_id); - -#ifdef ETC_DEBUG - qDebug() << "glCompressedTexImage2D, width: " << m_size.width() << "height" << m_size.height() << - "paddedWidth: " << m_paddedSize.width() << "paddedHeight: " << m_paddedSize.height(); -#endif + Q_UNUSED(suffix) -#ifndef QT_NO_DEBUG - while (glGetError() != GL_NO_ERROR) { } -#endif - - QOpenGLContext *ctx = QOpenGLContext::currentContext(); - Q_ASSERT(ctx != 0); - ctx->functions()->glCompressedTexImage2D(GL_TEXTURE_2D, 0, m_type, - m_size.width(), m_size.height(), 0, - (m_paddedSize.width() * m_paddedSize.height()) / 2, - m_data.data() + headerSize); - -#ifndef QT_NO_DEBUG - // Gracefully fail in case of an error... - GLuint error = glGetError(); - if (error != GL_NO_ERROR) { - qDebug () << "glCompressedTexImage2D for compressed texture failed, error: " << error; - glBindTexture(GL_TEXTURE_2D, 0); - glDeleteTextures(1, &m_texture_id); - m_texture_id = 0; - return; - } -#endif - - m_uploaded = true; - updateBindOptions(true); + return block.startsWith("PKM "); } -class QEtcTextureFactory : public QQuickTextureFactory -{ -public: - QByteArray m_data; - QSize m_size; - QSize m_paddedSize; - unsigned int m_type; - - QSize textureSize() const { return m_size; } - int textureByteCount() const { return m_data.size(); } - - QSGTexture *createTexture(QQuickWindow *) const { - QEtcTexture *texture = new QEtcTexture; - texture->m_data = m_data; - texture->m_size = m_size; - texture->m_paddedSize = m_paddedSize; - texture->m_type = m_type; - return texture; - } -}; - -QQuickTextureFactory *QSGPkmHandler::read(QIODevice *device) +QQuickTextureFactory *QSGPkmHandler::read() { - QScopedPointer<QEtcTextureFactory> ret(new QEtcTextureFactory); - ret->m_data = device->readAll(); - if (ret->m_data.isEmpty() || ret->m_data.size() < headerSize) + if (!device()) return nullptr; - const char *rawData = ret->m_data.constData(); + QSGCompressedTexture::DataPtr texData(QSGCompressedTexture::DataPtr::create()); - // magic number - if (qstrncmp(rawData, "PKM ", 4) != 0) + texData->data = device()->readAll(); + if (texData->data.size() < headerSize || !canRead(QByteArray(), texData->data)) { + qCDebug(QSG_LOG_TEXTUREIO, "Invalid PKM file %s", logName().constData()); return nullptr; + } + + const char *rawData = texData->data.constData(); - // currently ignore version (rawData + 4) + // ignore version (rawData + 4 & 5) // texture type quint16 type = qFromBigEndian<quint16>(rawData + 6); - static int typeCount = sizeof(typeMap)/sizeof(typeMap[0]); - if (type >= typeCount) + if (type > sizeof(typeMap)/sizeof(typeMap[0])) { + qCDebug(QSG_LOG_TEXTUREIO, "Unknown compression format in PKM file %s", logName().constData()); return nullptr; - ret->m_type = typeMap[type]; + } + texData->format = typeMap[type]; + texData->hasAlpha = !QSGCompressedTexture::formatIsOpaque(texData->format); // texture size - ret->m_paddedSize.setWidth(qFromBigEndian<quint16>(rawData + 8)); - ret->m_paddedSize.setHeight(qFromBigEndian<quint16>(rawData + 10)); - if ((ret->m_paddedSize.width() * ret->m_paddedSize.height()) / 2 > ret->m_data.size() - headerSize) - return nullptr; - ret->m_size.setWidth(qFromBigEndian<quint16>(rawData + 12)); - ret->m_size.setHeight(qFromBigEndian<quint16>(rawData + 14)); - if (ret->m_size.isEmpty()) + const int bpb = (texData->format == QOpenGLTexture::RGBA8_ETC2_EAC) ? 16 : 8; + QSize paddedSize(qFromBigEndian<quint16>(rawData + 8), qFromBigEndian<quint16>(rawData + 10)); + texData->dataLength = (paddedSize.width() / 4) * (paddedSize.height() / 4) * bpb; + QSize texSize(qFromBigEndian<quint16>(rawData + 12), qFromBigEndian<quint16>(rawData + 14)); + texData->size = texSize; + + texData->dataOffset = headerSize; + + if (!texData->isValid()) { + qCDebug(QSG_LOG_TEXTUREIO, "Invalid values in header of PKM file %s", logName().constData()); return nullptr; + } + texData->logName = logName(); #ifdef ETC_DEBUG - qDebug() << "requestTexture returning: " << ret->m_data.length() << "bytes; width: " << ret->m_size.width() << ", height: " << ret->m_size.height(); + qDebug() << "PKM file handler read" << texData.data(); #endif - - return ret.take(); + return new QSGCompressedTextureFactory(texData); } QT_END_NAMESPACE diff --git a/src/quick/scenegraph/compressedtexture/qsgpkmhandler_p.h b/src/quick/scenegraph/compressedtexture/qsgpkmhandler_p.h index eb6b2e46c0..6154c51b84 100644 --- a/src/quick/scenegraph/compressedtexture/qsgpkmhandler_p.h +++ b/src/quick/scenegraph/compressedtexture/qsgpkmhandler_p.h @@ -51,42 +51,18 @@ // We mean it. // -#include <QOpenGLFunctions> -#include <QQuickImageProvider> -#include <QtQuick/QSGTexture> -#include <QUrl> +#include "qsgtexturefilehandler_p.h" QT_BEGIN_NAMESPACE -class QSGPkmHandler +class QSGPkmHandler : public QSGTextureFileHandler { public: - QSGPkmHandler() {} + using QSGTextureFileHandler::QSGTextureFileHandler; - QQuickTextureFactory *read(QIODevice *device); -}; - -class QEtcTexture : public QSGTexture, protected QOpenGLFunctions -{ - Q_OBJECT -public: - QEtcTexture(); - ~QEtcTexture(); - - void bind(); - - QSize textureSize() const { return m_size; } - int textureId() const; - - bool hasAlphaChannel() const; - bool hasMipmaps() const { return false; } + static bool canRead(const QByteArray &suffix, const QByteArray &block); - QByteArray m_data; - QSize m_size; - QSize m_paddedSize; - GLuint m_texture_id; - GLenum m_type; - bool m_uploaded; + QQuickTextureFactory *read() override; }; QT_END_NAMESPACE diff --git a/src/quick/scenegraph/compressedtexture/qsgtexturefilehandler_p.h b/src/quick/scenegraph/compressedtexture/qsgtexturefilehandler_p.h new file mode 100644 index 0000000000..8b831aebb9 --- /dev/null +++ b/src/quick/scenegraph/compressedtexture/qsgtexturefilehandler_p.h @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSGTEXTUREFILEHANDLER_P_H +#define QSGTEXTUREFILEHANDLER_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QLoggingCategory> + +QT_BEGIN_NAMESPACE + +Q_DECLARE_LOGGING_CATEGORY(QSG_LOG_TEXTUREIO) + +class QQuickTextureFactory; + +class QSGTextureFileHandler +{ +public: + QSGTextureFileHandler(QIODevice *device, const QByteArray &logName = QByteArray()) + : m_device(device) + { + m_logName = !logName.isEmpty() ? logName : QByteArrayLiteral("(unknown)"); + } + virtual ~QSGTextureFileHandler() {} + + virtual QQuickTextureFactory *read() = 0; + QIODevice *device() const { return m_device; } + QByteArray logName() const { return m_logName; } + +private: + QIODevice *m_device = nullptr; + QByteArray m_logName; +}; + +QT_END_NAMESPACE + +#endif // QSGTEXTUREFILEHANDLER_P_H diff --git a/src/quick/scenegraph/coreapi/qsgabstractrenderer.cpp b/src/quick/scenegraph/coreapi/qsgabstractrenderer.cpp index 3d4ce24716..fddac7ed71 100644 --- a/src/quick/scenegraph/coreapi/qsgabstractrenderer.cpp +++ b/src/quick/scenegraph/coreapi/qsgabstractrenderer.cpp @@ -97,7 +97,7 @@ QT_BEGIN_NAMESPACE \internal */ QSGAbstractRendererPrivate::QSGAbstractRendererPrivate() - : m_root_node(0) + : m_root_node(nullptr) , m_clear_color(Qt::transparent) , m_clear_mode(QSGAbstractRenderer::ClearColorBuffer | QSGAbstractRenderer::ClearDepthBuffer) { diff --git a/src/quick/scenegraph/coreapi/qsgabstractrenderer.h b/src/quick/scenegraph/coreapi/qsgabstractrenderer.h index 304dc008d5..ab6fb4f317 100644 --- a/src/quick/scenegraph/coreapi/qsgabstractrenderer.h +++ b/src/quick/scenegraph/coreapi/qsgabstractrenderer.h @@ -62,7 +62,7 @@ public: }; Q_DECLARE_FLAGS(ClearMode, ClearModeBit) - virtual ~QSGAbstractRenderer(); + ~QSGAbstractRenderer() override; void setRootNode(QSGRootNode *node); QSGRootNode *rootNode() const; diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp index 0da35fba42..ba71551302 100644 --- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp +++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp @@ -144,7 +144,7 @@ ShaderManager::Shader *ShaderManager::prepareMaterial(QSGMaterial *material) Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphContextFrame); QSGMaterialShader *s = material->createShader(); - QOpenGLContext *ctx = QOpenGLContext::currentContext(); + QOpenGLContext *ctx = context->openglContext(); QSurfaceFormat::OpenGLContextProfile profile = ctx->format().profile(); QOpenGLShaderProgram *p = s->program(); @@ -155,10 +155,10 @@ ShaderManager::Shader *ShaderManager::prepareMaterial(QSGMaterial *material) p->bindAttributeLocation(attr[i], i); } p->bindAttributeLocation("_qt_order", i); - context->compileShader(s, material, qsgShaderRewriter_insertZAttributes(s->vertexShader(), profile), 0); + context->compileShader(s, material, qsgShaderRewriter_insertZAttributes(s->vertexShader(), profile), nullptr); context->initializeShader(s); if (!p->isLinked()) - return 0; + return nullptr; shader = new Shader; shader->program = s; @@ -215,7 +215,7 @@ void ShaderManager::invalidated() qDeleteAll(rewrittenShaders); rewrittenShaders.clear(); delete blitProgram; - blitProgram = 0; + blitProgram = nullptr; } void qsg_dumpShadowRoots(BatchRootInfo *i, int indent) @@ -226,7 +226,7 @@ void qsg_dumpShadowRoots(BatchRootInfo *i, int indent) QByteArray ind(indent + extraIndent + 10, ' '); if (!i) { - qDebug() << ind.constData() << "- no info"; + qDebug("%s - no info", ind.constData()); } else { qDebug() << ind.constData() << "- parent:" << i->parentRoot << "orders" << i->firstOrder << "->" << i->lastOrder << ", avail:" << i->availableOrders; for (QSet<Node *>::const_iterator it = i->subRoots.constBegin(); @@ -280,7 +280,7 @@ Updater::Updater(Renderer *r) void Updater::updateStates(QSGNode *n) { - m_current_clip = 0; + m_current_clip = nullptr; m_added = 0; m_transformChange = 0; @@ -293,15 +293,15 @@ void Updater::updateStates(QSGNode *n) qsg_dumpShadowRoots(sn); if (Q_UNLIKELY(debug_build())) { - qDebug() << "Updater::updateStates()"; + qDebug("Updater::updateStates()"); if (sn->dirtyState & (QSGNode::DirtyNodeAdded << 16)) - qDebug() << " - nodes have been added"; + qDebug(" - nodes have been added"); if (sn->dirtyState & (QSGNode::DirtyMatrix << 16)) - qDebug() << " - transforms have changed"; + qDebug(" - transforms have changed"); if (sn->dirtyState & (QSGNode::DirtyOpacity << 16)) - qDebug() << " - opacity has changed"; + qDebug(" - opacity has changed"); if (uint(sn->dirtyState) & uint(QSGNode::DirtyForceUpdate << 16)) - qDebug() << " - forceupdate"; + qDebug(" - forceupdate"); } if (Q_UNLIKELY(renderer->m_visualizeMode == Renderer::VisualizeChanges)) @@ -347,7 +347,7 @@ void Updater::visitNode(Node *n) m_added = count; m_force_update = force; - n->dirtyState = 0; + n->dirtyState = nullptr; } void Updater::visitClipNode(Node *n) @@ -473,7 +473,7 @@ void Updater::visitGeometryNode(Node *n) if (e->root) { BatchRootInfo *info = renderer->batchRootInfo(e->root); - while (info != 0) { + while (info != nullptr) { info->availableOrders--; if (info->availableOrders < 0) { renderer->m_rebuild |= Renderer::BuildRenderLists; @@ -481,10 +481,10 @@ void Updater::visitGeometryNode(Node *n) renderer->m_rebuild |= Renderer::BuildRenderListsForTaggedRoots; renderer->m_taggedRoots << e->root; } - if (info->parentRoot != 0) + if (info->parentRoot != nullptr) info = renderer->batchRootInfo(info->parentRoot); else - info = 0; + info = nullptr; } } else { renderer->m_rebuild |= Renderer::FullRebuild; @@ -680,12 +680,12 @@ void Batch::invalidate() // the batch to do an early out.. cleanupRemovedElements(); Element *e = first; - first = 0; - root = 0; + first = nullptr; + root = nullptr; while (e) { - e->batch = 0; + e->batch = nullptr; Element *n = e->nextInBatch; - e->nextInBatch = 0; + e->nextInBatch = nullptr; e = n; } } @@ -756,7 +756,7 @@ Renderer::Renderer(QSGDefaultRenderContext *ctx) , m_alphaRenderList(64) , m_nextRenderOrder(0) , m_partialRebuild(false) - , m_partialRebuildRoot(0) + , m_partialRebuildRoot(nullptr) , m_useDepthBuffer(true) , m_opaqueBatches(16) , m_alphaBatches(16) @@ -768,17 +768,17 @@ Renderer::Renderer(QSGDefaultRenderContext *ctx) , m_zRange(0) , m_renderOrderRebuildLower(-1) , m_renderOrderRebuildUpper(-1) - , m_currentMaterial(0) - , m_currentShader(0) + , m_currentMaterial(nullptr) + , m_currentShader(nullptr) , m_currentStencilValue(0) , m_clipMatrixId(0) - , m_currentClip(0) + , m_currentClip(nullptr) , m_currentClipType(NoClip) , m_vertexUploadPool(256) #ifdef QSG_SEPARATE_INDEX_BUFFER , m_indexUploadPool(64) #endif - , m_vao(0) + , m_vao(nullptr) , m_visualizeMode(VisualizeNothing) { initializeOpenGLFunctions(); @@ -805,8 +805,11 @@ Renderer::Renderer(QSGDefaultRenderContext *ctx) m_batchVertexThreshold = qt_sg_envInt("QSG_RENDERER_BATCH_VERTEX_THRESHOLD", 1024); if (Q_UNLIKELY(debug_build() || debug_render())) { - qDebug() << "Batch thresholds: nodes:" << m_batchNodeThreshold << " vertices:" << m_batchVertexThreshold; - qDebug() << "Using buffer strategy:" << (m_bufferStrategy == GL_STATIC_DRAW ? "static" : (m_bufferStrategy == GL_DYNAMIC_DRAW ? "dynamic" : "stream")); + qDebug("Batch thresholds: nodes: %d vertices: %d", + m_batchNodeThreshold, m_batchVertexThreshold); + qDebug("Using buffer strategy: %s", + (m_bufferStrategy == GL_STATIC_DRAW + ? "static" : (m_bufferStrategy == GL_DYNAMIC_DRAW ? "dynamic" : "stream"))); } // If rendering with an OpenGL Core profile context, we need to create a VAO @@ -913,7 +916,7 @@ void Renderer::unmap(Buffer *buffer, bool isIndexBuf) glBufferData(target, buffer->size, buffer->data, m_bufferStrategy); if (!m_context->hasBrokenIndexBufferObjects() && m_visualizeMode == VisualizeNothing) { - buffer->data = 0; + buffer->data = nullptr; } } @@ -941,7 +944,7 @@ void Renderer::removeBatchRootFromParent(Node *childRoot) Q_ASSERT(parentInfo->subRoots.contains(childRoot)); parentInfo->subRoots.remove(childRoot); - childInfo->parentRoot = 0; + childInfo->parentRoot = nullptr; } void Renderer::registerBatchRoot(Node *subRoot, Node *parentRoot) @@ -1069,7 +1072,7 @@ void Renderer::nodeWasRemoved(Node *node) if (e) { e->removed = true; m_elementsToDelete.add(e); - e->node = 0; + e->node = nullptr; if (e->root) { BatchRootInfo *info = batchRootInfo(e->root); info->availableOrders++; @@ -1112,7 +1115,7 @@ void Renderer::nodeWasRemoved(Node *node) void Renderer::turnNodeIntoBatchRoot(Node *node) { - if (Q_UNLIKELY(debug_change())) qDebug() << " - new batch root"; + if (Q_UNLIKELY(debug_change())) qDebug(" - new batch root"); m_rebuild |= FullRebuild; node->isBatchRoot = true; node->becameBatchRoot = true; @@ -1182,7 +1185,7 @@ void Renderer::nodeChanged(QSGNode *node, QSGNode::DirtyState state) return; } if (node == rootNode()) - nodeWasAdded(node, 0); + nodeWasAdded(node, nullptr); else nodeWasAdded(node, m_nodes.value(node->parent())); } @@ -1435,7 +1438,7 @@ void Renderer::buildRenderListsForTaggedRoots() } } m_partialRebuild = false; - m_partialRebuildRoot = 0; + m_partialRebuildRoot = nullptr; m_taggedRoots.clear(); m_nextRenderOrder = qMax(m_nextRenderOrder, maxRenderOrder); @@ -2032,7 +2035,7 @@ Renderer::ClipType Renderer::updateStencilClip(const QSGClipNode *clip) int vboSize = 0; bool useVBO = false; - QOpenGLContext *ctx = QOpenGLContext::currentContext(); + QOpenGLContext *ctx = m_context->openglContext(); QSurfaceFormat::OpenGLContextProfile profile = ctx->format().profile(); if (!ctx->isOpenGLES() && profile == QSurfaceFormat::CoreProfile) { @@ -2141,7 +2144,7 @@ Renderer::ClipType Renderer::updateStencilClip(const QSGClipNode *clip) glBufferSubData(GL_ARRAY_BUFFER, 0, vertexByteSize, g->vertexData()); } - pointer = 0; + pointer = nullptr; } glVertexAttribPointer(0, a->tupleSize, a->type, GL_FALSE, g->sizeOfVertex(), pointer); @@ -2183,7 +2186,7 @@ void Renderer::updateClip(const QSGClipNode *clipList, const Batch *batch) m_currentClip = clipList; // updateClip sets another program, so force-reactivate our own if (m_currentShader) - setActiveShader(0, 0); + setActiveShader(nullptr, nullptr); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); if (batch->isOpaque) @@ -2204,8 +2207,8 @@ void Renderer::updateClip(const QSGClipNode *clipList, const Batch *batch) */ void Renderer::setActiveShader(QSGMaterialShader *program, ShaderManager::Shader *shader) { - const char * const *c = m_currentProgram ? m_currentProgram->attributeNames() : 0; - const char * const *n = program ? program->attributeNames() : 0; + const char * const *c = m_currentProgram ? m_currentProgram->attributeNames() : nullptr; + const char * const *n = program ? program->attributeNames() : nullptr; int cza = m_currentShader ? m_currentShader->pos_order : -1; int nza = shader ? shader->pos_order : -1; @@ -2216,18 +2219,18 @@ void Renderer::setActiveShader(QSGMaterialShader *program, ShaderManager::Shader bool was = c; if (cza == i) { was = true; - c = 0; + c = nullptr; } else if (c && !c[i]) { // end of the attribute array names - c = 0; + c = nullptr; was = false; } bool is = n; if (nza == i) { is = true; - n = 0; + n = nullptr; } else if (n && !n[i]) { - n = 0; + n = nullptr; is = false; } @@ -2243,7 +2246,7 @@ void Renderer::setActiveShader(QSGMaterialShader *program, ShaderManager::Shader m_currentProgram->deactivate(); m_currentProgram = program; m_currentShader = shader; - m_currentMaterial = 0; + m_currentMaterial = nullptr; if (m_currentProgram) { m_currentProgram->program()->bind(); m_currentProgram->activate(); @@ -2295,7 +2298,7 @@ void Renderer::renderMergedBatch(const Batch *batch) glBindBuffer(GL_ARRAY_BUFFER, batch->vbo.id); - char *indexBase = 0; + char *indexBase = nullptr; #ifdef QSG_SEPARATE_INDEX_BUFFER const Buffer *indexBuf = &batch->ibo; #else @@ -2319,7 +2322,7 @@ void Renderer::renderMergedBatch(const Batch *batch) setActiveShader(program, sms); m_current_opacity = gn->inheritedOpacity(); - if (sms->lastOpacity != m_current_opacity) { + if (!qFuzzyCompare(sms->lastOpacity, float(m_current_opacity))) { dirty |= QSGMaterialShader::RenderState::DirtyOpacity; sms->lastOpacity = m_current_opacity; } @@ -2328,7 +2331,7 @@ void Renderer::renderMergedBatch(const Batch *batch) #ifndef QT_NO_DEBUG if (qsg_test_and_clear_material_failure()) { - qDebug() << "QSGMaterial::updateState triggered an error (merged), batch will be skipped:"; + qDebug("QSGMaterial::updateState triggered an error (merged), batch will be skipped:"); Element *ee = e; while (ee) { qDebug() << " -" << ee->node; @@ -2391,7 +2394,7 @@ void Renderer::renderUnmergedBatch(const Batch *batch) updateClip(gn->clipList(), batch); glBindBuffer(GL_ARRAY_BUFFER, batch->vbo.id); - char *indexBase = 0; + char *indexBase = nullptr; #ifdef QSG_SEPARATE_INDEX_BUFFER const Buffer *indexBuf = &batch->ibo; #else @@ -2449,7 +2452,7 @@ void Renderer::renderUnmergedBatch(const Batch *batch) #ifndef QT_NO_DEBUG if (qsg_test_and_clear_material_failure()) { - qDebug() << "QSGMaterial::updateState() triggered an error (unmerged), batch will be skipped:"; + qDebug("QSGMaterial::updateState() triggered an error (unmerged), batch will be skipped:"); qDebug() << " - offending node is" << e->node; QSGNodeDumper::dump(rootNode()); qFatal("Aborting: scene graph is invalid..."); @@ -2494,18 +2497,21 @@ void Renderer::updateLineWidth(QSGGeometry *g) 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 (!QOpenGLContext::currentContext()->isOpenGLES() && g->drawingMode() == GL_POINTS) { - QOpenGLFunctions_1_0 *gl1funcs = 0; - QOpenGLFunctions_3_2_Core *gl3funcs = 0; - if (QOpenGLContext::currentContext()->format().profile() == QSurfaceFormat::CoreProfile) - gl3funcs = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_3_2_Core>(); - else - gl1funcs = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_1_0>(); - Q_ASSERT(gl1funcs || gl3funcs); - if (gl1funcs) - gl1funcs->glPointSize(g->lineWidth()); - else - gl3funcs->glPointSize(g->lineWidth()); + else { + QOpenGLContext *ctx = m_context->openglContext(); + if (!ctx->isOpenGLES() && g->drawingMode() == GL_POINTS) { + QOpenGLFunctions_1_0 *gl1funcs = nullptr; + QOpenGLFunctions_3_2_Core *gl3funcs = nullptr; + if (ctx->format().profile() == QSurfaceFormat::CoreProfile) + gl3funcs = ctx->versionFunctions<QOpenGLFunctions_3_2_Core>(); + else + gl1funcs = ctx->versionFunctions<QOpenGLFunctions_1_0>(); + Q_ASSERT(gl1funcs || gl3funcs); + if (gl1funcs) + gl1funcs->glPointSize(g->lineWidth()); + else + gl3funcs->glPointSize(g->lineWidth()); + } } #endif } @@ -2540,10 +2546,10 @@ void Renderer::renderBatches() bindable()->clear(clearMode()); m_current_opacity = 1; - m_currentMaterial = 0; - m_currentShader = 0; - m_currentProgram = 0; - m_currentClip = 0; + m_currentMaterial = nullptr; + m_currentShader = nullptr; + m_currentProgram = nullptr; + m_currentClip = nullptr; bool renderOpaque = !debug_noopaque(); bool renderAlpha = !debug_noalpha(); @@ -2576,8 +2582,8 @@ void Renderer::renderBatches() } if (m_currentShader) - setActiveShader(0, 0); - updateStencilClip(0); + setActiveShader(nullptr, nullptr); + updateStencilClip(nullptr); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glDepthMask(true); @@ -2591,12 +2597,12 @@ void Renderer::deleteRemovedElements() for (int i=0; i<m_opaqueRenderList.size(); ++i) { Element **e = m_opaqueRenderList.data() + i; if (*e && (*e)->removed) - *e = 0; + *e = nullptr; } for (int i=0; i<m_alphaRenderList.size(); ++i) { Element **e = m_alphaRenderList.data() + i; if (*e && (*e)->removed) - *e = 0; + *e = nullptr; } for (int i=0; i<m_elementsToDelete.size(); ++i) { @@ -2611,6 +2617,8 @@ void Renderer::deleteRemovedElements() void Renderer::render() { + Q_ASSERT(m_context->openglContext() == QOpenGLContext::currentContext()); + if (Q_UNLIKELY(debug_dump())) { qDebug("\n"); QSGNodeDumper::dump(rootNode()); @@ -2655,12 +2663,12 @@ void Renderer::render() m_rebuild |= BuildBatches; if (Q_UNLIKELY(debug_build())) { - qDebug() << "Opaque render lists" << (complete ? "(complete)" : "(partial)") << ":"; + qDebug("Opaque render lists %s:", (complete ? "(complete)" : "(partial)")); for (int i=0; i<m_opaqueRenderList.size(); ++i) { Element *e = m_opaqueRenderList.at(i); qDebug() << " - element:" << e << " batch:" << e->batch << " node:" << e->node << " order:" << e->order; } - qDebug() << "Alpha render list:" << (complete ? "(complete)" : "(partial)") << ":"; + qDebug("Alpha render list %s:", complete ? "(complete)" : "(partial)"); for (int i=0; i<m_alphaRenderList.size(); ++i) { Element *e = m_alphaRenderList.at(i); qDebug() << " - element:" << e << " batch:" << e->batch << " node:" << e->node << " order:" << e->order; @@ -2685,7 +2693,7 @@ void Renderer::render() if (Q_UNLIKELY(debug_render())) timePrepareAlpha = timer.restart(); if (Q_UNLIKELY(debug_build())) { - qDebug() << "Opaque Batches:"; + qDebug("Opaque Batches:"); for (int i=0; i<m_opaqueBatches.size(); ++i) { Batch *b = m_opaqueBatches.at(i); qDebug() << " - Batch " << i << b << (b->needsUpload ? "upload" : "") << " root:" << b->root; @@ -2693,7 +2701,7 @@ void Renderer::render() qDebug() << " - element:" << e << " node:" << e->node << e->order; } } - qDebug() << "Alpha Batches:"; + qDebug("Alpha Batches:"); for (int i=0; i<m_alphaBatches.size(); ++i) { Batch *b = m_alphaBatches.at(i); qDebug() << " - Batch " << i << b << (b->needsUpload ? "upload" : "") << " root:" << b->root; @@ -2731,7 +2739,7 @@ void Renderer::render() int largestIBO = 0; #endif - if (Q_UNLIKELY(debug_upload())) qDebug() << "Uploading Opaque Batches:"; + if (Q_UNLIKELY(debug_upload())) qDebug("Uploading Opaque Batches:"); for (int i=0; i<m_opaqueBatches.size(); ++i) { Batch *b = m_opaqueBatches.at(i); largestVBO = qMax(b->vbo.size, largestVBO); @@ -2743,7 +2751,7 @@ void Renderer::render() if (Q_UNLIKELY(debug_render())) timeUploadOpaque = timer.restart(); - if (Q_UNLIKELY(debug_upload())) qDebug() << "Uploading Alpha Batches:"; + if (Q_UNLIKELY(debug_upload())) qDebug("Uploading Alpha Batches:"); for (int i=0; i<m_alphaBatches.size(); ++i) { Batch *b = m_alphaBatches.at(i); uploadBatch(b); @@ -2807,11 +2815,11 @@ void Renderer::renderRenderNode(Batch *batch) Q_ASSERT(batch->first->isRenderNode); RenderNodeElement *e = (RenderNodeElement *) batch->first; - setActiveShader(0, 0); + setActiveShader(nullptr, nullptr); QSGNode *clip = e->renderNode->parent(); QSGRenderNodePrivate *rd = QSGRenderNodePrivate::get(e->renderNode); - rd->m_clip_list = 0; + rd->m_clip_list = nullptr; while (clip != rootNode()) { if (clip->type() == QSGNode::ClipNodeType) { rd->m_clip_list = static_cast<QSGClipNode *>(clip); @@ -2875,8 +2883,8 @@ void Renderer::renderRenderNode(Batch *batch) e->renderNode->render(&state); - rd->m_matrix = 0; - rd->m_clip_list = 0; + rd->m_matrix = nullptr; + rd->m_clip_list = nullptr; if (changes & QSGRenderNode::ViewportState) { QRect r = viewportRect(); @@ -2891,7 +2899,7 @@ void Renderer::renderRenderNode(Batch *batch) if (changes & (QSGRenderNode::StencilState | QSGRenderNode::ScissorState)) { glDisable(GL_SCISSOR_TEST); - m_currentClip = 0; + m_currentClip = nullptr; m_currentClipType = NoClip; } @@ -3061,7 +3069,7 @@ void Renderer::visualizeChanges(Node *n) // This is because many changes don't propegate their dirty state to the // parent so the node updater will not unset these states. They are // not used for anything so, unsetting it should have no side effects. - n->dirtyState = 0; + n->dirtyState = nullptr; } SHADOWNODE_TRAVERSE(n) { @@ -3153,7 +3161,7 @@ void Renderer::visualizeOverdraw() visualizeOverdraw_helper(m_nodes.value(rootNode())); // Animate the view... - QSurface *surface = QOpenGLContext::currentContext()->surface(); + QSurface *surface = m_context->openglContext()->surface(); if (surface->surfaceClass() == QSurface::Window) if (QQuickWindow *window = qobject_cast<QQuickWindow *>(static_cast<QWindow *>(surface))) window->update(); diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h index 5c39242029..918f3ce82c 100644 --- a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h +++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h @@ -125,7 +125,6 @@ template <typename Type, int PageSize> class Allocator { public: Allocator() - : m_freePage(0) { pages.push_back(new AllocatorPage<Type, PageSize>()); } @@ -209,7 +208,7 @@ public: } QVector<AllocatorPage<Type, PageSize> *> pages; - int m_freePage; + int m_freePage = 0; }; @@ -306,12 +305,7 @@ struct Buffer { struct Element { Element() - : node(0) - , batch(0) - , nextInBatch(0) - , root(0) - , order(0) - , boundsComputed(false) + : boundsComputed(false) , boundsOutsideFloatRange(false) , translateOnlyToRoot(false) , removed(false) @@ -332,14 +326,14 @@ struct Element { } void computeBounds(); - QSGGeometryNode *node; - Batch *batch; - Element *nextInBatch; - Node *root; + QSGGeometryNode *node = nullptr; + Batch *batch = nullptr; + Element *nextInBatch = nullptr; + Node *root = nullptr; Rect bounds; // in device coordinates - int order; + int order = 0; uint boundsComputed : 1; uint boundsOutsideFloatRange : 1; @@ -362,12 +356,12 @@ struct RenderNodeElement : public Element { }; struct BatchRootInfo { - BatchRootInfo() : parentRoot(0), lastOrder(-1), firstOrder(-1), availableOrders(0) { } + BatchRootInfo() {} QSet<Node *> subRoots; - Node *parentRoot; - int lastOrder; - int firstOrder; - int availableOrders; + Node *parentRoot = nullptr; + int lastOrder = -1; + int firstOrder = -1; + int availableOrders = 0; }; struct ClipBatchRootInfo : public BatchRootInfo @@ -381,14 +375,13 @@ struct DrawSet : vertices(v) , zorders(z) , indices(i) - , indexCount(0) { } - DrawSet() : vertices(0), zorders(0), indices(0), indexCount(0) {} - int vertices; - int zorders; - int indices; - int indexCount; + DrawSet() {} + int vertices = 0; + int zorders = 0; + int indices = 0; + int indexCount = 0; }; enum BatchCompatibility @@ -410,8 +403,8 @@ struct Batch // pseudo-constructor... void init() { - first = 0; - root = 0; + first = nullptr; + root = nullptr; vertexCount = 0; indexCount = 0; isOpaque = false; @@ -440,7 +433,9 @@ struct Batch mutable uint uploadedThisFrame : 1; // solely for debugging purposes Buffer vbo; +#ifdef QSG_SEPARATE_INDEX_BUFFER Buffer ibo; +#endif QDataBuffer<DrawSet> drawSets; }; @@ -461,9 +456,9 @@ struct Node void append(Node *child) { Q_ASSERT(child); Q_ASSERT(!hasChild(child)); - Q_ASSERT(child->m_parent == 0); - Q_ASSERT(child->m_next == 0); - Q_ASSERT(child->m_prev == 0); + Q_ASSERT(child->m_parent == nullptr); + Q_ASSERT(child->m_next == nullptr); + Q_ASSERT(child->m_prev == nullptr); if (!m_child) { child->m_next = child; @@ -484,27 +479,27 @@ struct Node // only child.. if (child->m_next == child) { - m_child = 0; + m_child = nullptr; } else { if (m_child == child) m_child = child->m_next; child->m_next->m_prev = child->m_prev; child->m_prev->m_next = child->m_next; } - child->m_next = 0; - child->m_prev = 0; - child->setParent(0); + child->m_next = nullptr; + child->m_prev = nullptr; + child->setParent(nullptr); } Node *firstChild() const { return m_child; } Node *sibling() const { Q_ASSERT(m_parent); - return m_next == m_parent->m_child ? 0 : m_next; + return m_next == m_parent->m_child ? nullptr : m_next; } void setParent(Node *p) { - Q_ASSERT(m_parent == 0 || p == 0); + Q_ASSERT(m_parent == nullptr || p == nullptr); m_parent = p; } @@ -589,7 +584,7 @@ public: float lastOpacity; }; - ShaderManager(QSGDefaultRenderContext *ctx) : visualizeProgram(0), blitProgram(0), context(ctx) { } + ShaderManager(QSGDefaultRenderContext *ctx) : visualizeProgram(nullptr), blitProgram(nullptr), context(ctx) { } ~ShaderManager() { qDeleteAll(rewrittenShaders); qDeleteAll(stockShaders); @@ -743,7 +738,9 @@ private: ClipType m_currentClipType; QDataBuffer<char> m_vertexUploadPool; +#ifdef QSG_SEPARATE_INDEX_BUFFER QDataBuffer<char> m_indexUploadPool; +#endif // For minimal OpenGL core profile support QOpenGLVertexArrayObject *m_vao; @@ -763,7 +760,10 @@ Batch *Renderer::newBatch() m_batchPool.resize(size - 1); } else { b = new Batch(); - memset(&b->vbo, 0, sizeof(Buffer) * 2); // Clear VBO & IBO + memset(&b->vbo, 0, sizeof(Buffer)); +#ifdef QSG_SEPARATE_INDEX_BUFFER + memset(&b->ibo, 0, sizeof(Buffer)); +#endif } b->init(); return b; diff --git a/src/quick/scenegraph/coreapi/qsggeometry.cpp b/src/quick/scenegraph/coreapi/qsggeometry.cpp index 69a8c21ed2..226709094d 100644 --- a/src/quick/scenegraph/coreapi/qsggeometry.cpp +++ b/src/quick/scenegraph/coreapi/qsggeometry.cpp @@ -430,9 +430,9 @@ QSGGeometry::QSGGeometry(const QSGGeometry::AttributeSet &attributes, , m_index_count(0) , m_index_type(indexType) , m_attributes(attributes) - , m_data(0) + , m_data(nullptr) , m_index_data_offset(-1) - , m_server_data(0) + , m_server_data(nullptr) , m_owns_data(false) , m_index_usage_pattern(AlwaysUploadPattern) , m_vertex_usage_pattern(AlwaysUploadPattern) @@ -529,7 +529,7 @@ QSGGeometry::~QSGGeometry() void *QSGGeometry::indexData() { return m_index_data_offset < 0 - ? 0 + ? nullptr : ((char *) m_data + m_index_data_offset); } @@ -541,7 +541,7 @@ void *QSGGeometry::indexData() const void *QSGGeometry::indexData() const { return m_index_data_offset < 0 - ? 0 + ? nullptr : ((char *) m_data + m_index_data_offset); } @@ -768,6 +768,19 @@ void QSGGeometry::updateColoredRectGeometry(QSGGeometry *g, const QRectF &rect) v[3].y = rect.bottom(); } +/*! + \enum QSGGeometry::AttributeType + + This enum identifies several attribute types. + + \value UnknownAttribute Don't care + \value PositionAttribute Position + \value ColorAttribute Color + \value TexCoordAttribute Texture coordinate + \value TexCoord1Attribute Texture coordinate 1 + \value TexCoord2Attribute Texture coordinate 2 + + */ /*! \enum QSGGeometry::DataPattern diff --git a/src/quick/scenegraph/coreapi/qsgmaterial.cpp b/src/quick/scenegraph/coreapi/qsgmaterial.cpp index 07dc87a643..8557de1b1f 100644 --- a/src/quick/scenegraph/coreapi/qsgmaterial.cpp +++ b/src/quick/scenegraph/coreapi/qsgmaterial.cpp @@ -443,7 +443,12 @@ void QSGMaterialShader::compile() otherwise returns \c false. */ +/*! + \fn bool QSGMaterialShader::RenderState::isCachedMaterialDataDirty() const + Returns \c true if the dirtyStates() contains the dirty cached material state, + otherwise returns \c false. + */ /*! \fn QSGMaterialShader::RenderState::DirtyStates QSGMaterialShader::RenderState::dirtyStates() const @@ -636,7 +641,7 @@ static void qt_print_material_count() */ QSGMaterial::QSGMaterial() - : m_flags(0) + : m_flags(nullptr) { Q_UNUSED(m_reserved); #ifndef QT_NO_DEBUG diff --git a/src/quick/scenegraph/coreapi/qsgnode.cpp b/src/quick/scenegraph/coreapi/qsgnode.cpp index 22d57001fc..9717862baa 100644 --- a/src/quick/scenegraph/coreapi/qsgnode.cpp +++ b/src/quick/scenegraph/coreapi/qsgnode.cpp @@ -114,6 +114,10 @@ static void qt_print_node_count() \value DirtyOpacity The opacity of a QSGOpacityNode has changed. \value DirtySubtreeBlocked The subtree has been blocked. + \omitvalue DirtyForceUpdate + \omitvalue DirtyUsePreprocess + \omitvalue DirtyPropagationMask + \sa QSGNode::markDirty() */ @@ -135,6 +139,8 @@ static void qt_print_node_count() ownership over the opaque material and will delete it when the node is destroyed or a material is assigned. \value InternalReserved Reserved for internal use. + + \omitvalue IsVisitableNode */ /*! @@ -149,6 +155,8 @@ static void qt_print_node_count() \value OpacityNodeType The type of QSGOpacityNode \value RenderNodeType The type of QSGRenderNode + \omitvalue RootNodeType + \sa type() */ @@ -236,15 +244,8 @@ static void qt_print_node_count() * Constructs a new node */ QSGNode::QSGNode() - : m_parent(0) - , m_type(BasicNodeType) - , m_firstChild(0) - , m_lastChild(0) - , m_nextSibling(0) - , m_previousSibling(0) - , m_subtreeRenderableCount(0) - , m_nodeFlags(OwnedByParent) - , m_dirtyState(0) + : m_nodeFlags(OwnedByParent) + , m_dirtyState(nullptr) { init(); } @@ -255,15 +256,15 @@ QSGNode::QSGNode() * \internal */ QSGNode::QSGNode(NodeType type) - : m_parent(0) + : m_parent(nullptr) , m_type(type) - , m_firstChild(0) - , m_lastChild(0) - , m_nextSibling(0) - , m_previousSibling(0) + , m_firstChild(nullptr) + , m_lastChild(nullptr) + , m_nextSibling(nullptr) + , m_previousSibling(nullptr) , m_subtreeRenderableCount(type == GeometryNodeType || type == RenderNodeType ? 1 : 0) , m_nodeFlags(OwnedByParent) - , m_dirtyState(0) + , m_dirtyState(nullptr) { init(); } @@ -274,15 +275,15 @@ QSGNode::QSGNode(NodeType type) * \internal */ QSGNode::QSGNode(QSGNodePrivate &dd, NodeType type) - : m_parent(0) + : m_parent(nullptr) , m_type(type) - , m_firstChild(0) - , m_lastChild(0) - , m_nextSibling(0) - , m_previousSibling(0) + , m_firstChild(nullptr) + , m_lastChild(nullptr) + , m_nextSibling(nullptr) + , m_previousSibling(nullptr) , m_subtreeRenderableCount(type == GeometryNodeType || type == RenderNodeType ? 1 : 0) , m_nodeFlags(OwnedByParent) - , m_dirtyState(0) + , m_dirtyState(nullptr) , d_ptr(&dd) { init(); @@ -380,17 +381,17 @@ void QSGNode::destroy() { if (m_parent) { m_parent->removeChildNode(this); - Q_ASSERT(m_parent == 0); + Q_ASSERT(m_parent == nullptr); } while (m_firstChild) { QSGNode *child = m_firstChild; removeChildNode(child); - Q_ASSERT(child->m_parent == 0); + Q_ASSERT(child->m_parent == nullptr); if (child->flags() & OwnedByParent) delete child; } - Q_ASSERT(m_firstChild == 0 && m_lastChild == 0); + Q_ASSERT(m_firstChild == nullptr && m_lastChild == nullptr); } @@ -549,11 +550,11 @@ void QSGNode::removeChildNode(QSGNode *node) next->m_previousSibling = previous; else m_lastChild = previous; - node->m_previousSibling = 0; - node->m_nextSibling = 0; + node->m_previousSibling = nullptr; + node->m_nextSibling = nullptr; node->markDirty(DirtyNodeRemoved); - node->m_parent = 0; + node->m_parent = nullptr; } @@ -566,13 +567,13 @@ void QSGNode::removeAllChildNodes() while (m_firstChild) { QSGNode *node = m_firstChild; m_firstChild = node->m_nextSibling; - node->m_nextSibling = 0; + node->m_nextSibling = nullptr; if (m_firstChild) - m_firstChild->m_previousSibling = 0; + m_firstChild->m_previousSibling = nullptr; else - m_lastChild = 0; + m_lastChild = nullptr; node->markDirty(DirtyNodeRemoved); - node->m_parent = 0; + node->m_parent = nullptr; } } @@ -706,9 +707,9 @@ void qsgnode_set_description(QSGNode *node, const QString &description) */ QSGBasicGeometryNode::QSGBasicGeometryNode(NodeType type) : QSGNode(type) - , m_geometry(0) - , m_matrix(0) - , m_clip_list(0) + , m_geometry(nullptr) + , m_matrix(nullptr) + , m_clip_list(nullptr) { } @@ -718,9 +719,9 @@ QSGBasicGeometryNode::QSGBasicGeometryNode(NodeType type) */ QSGBasicGeometryNode::QSGBasicGeometryNode(QSGBasicGeometryNodePrivate &dd, NodeType type) : QSGNode(dd, type) - , m_geometry(0) - , m_matrix(0) - , m_clip_list(0) + , m_geometry(nullptr) + , m_matrix(nullptr) + , m_clip_list(nullptr) { } @@ -862,10 +863,6 @@ void QSGBasicGeometryNode::setGeometry(QSGGeometry *geometry) QSGGeometryNode::QSGGeometryNode() : QSGBasicGeometryNode(GeometryNodeType) - , m_render_order(0) - , m_material(0) - , m_opaque_material(0) - , m_opacity(1) { } @@ -876,8 +873,8 @@ QSGGeometryNode::QSGGeometryNode() QSGGeometryNode::QSGGeometryNode(QSGGeometryNodePrivate &dd) : QSGBasicGeometryNode(dd, GeometryNodeType) , m_render_order(0) - , m_material(0) - , m_opaque_material(0) + , m_material(nullptr) + , m_opaque_material(nullptr) , m_opacity(1) { } @@ -971,7 +968,7 @@ void QSGGeometryNode::setMaterial(QSGMaterial *material) delete m_material; m_material = material; #ifndef QT_NO_DEBUG - if (m_material != 0 && m_opaque_material == m_material) + if (m_material != nullptr && m_opaque_material == m_material) qWarning("QSGGeometryNode: using same material for both opaque and translucent"); #endif markDirty(DirtyMaterial); @@ -1002,7 +999,7 @@ void QSGGeometryNode::setOpaqueMaterial(QSGMaterial *material) delete m_opaque_material; m_opaque_material = material; #ifndef QT_NO_DEBUG - if (m_opaque_material != 0 && m_opaque_material == m_material) + if (m_opaque_material != nullptr && m_opaque_material == m_material) qWarning("QSGGeometryNode: using same material for both opaque and translucent"); #endif @@ -1266,7 +1263,7 @@ QSGRootNode::QSGRootNode() QSGRootNode::~QSGRootNode() { while (!m_renderers.isEmpty()) - m_renderers.constLast()->setRootNode(0); + m_renderers.constLast()->setRootNode(nullptr); destroy(); // Must call destroy() here because markDirty() casts this to QSGRootNode. } @@ -1318,8 +1315,6 @@ void QSGRootNode::notifyNodeChange(QSGNode *node, DirtyState state) */ QSGOpacityNode::QSGOpacityNode() : QSGNode(OpacityNodeType) - , m_opacity(1) - , m_combined_opacity(1) { } diff --git a/src/quick/scenegraph/coreapi/qsgnode.h b/src/quick/scenegraph/coreapi/qsgnode.h index f2708b2b96..854e284c9e 100644 --- a/src/quick/scenegraph/coreapi/qsgnode.h +++ b/src/quick/scenegraph/coreapi/qsgnode.h @@ -77,9 +77,7 @@ public: TransformNodeType, ClipNodeType, OpacityNodeType, -#ifndef qdoc RootNodeType, -#endif RenderNodeType }; @@ -96,9 +94,8 @@ public: OwnsOpaqueMaterial = 0x00040000, // Uppermost 8 bits are reserved for internal use. -#ifndef qdoc IsVisitableNode = 0x01000000 -#else +#ifdef Q_CLANG_QDOC InternalReserved = 0x01000000 #endif }; @@ -113,7 +110,6 @@ public: DirtyMaterial = 0x2000, DirtyOpacity = 0x4000, -#ifndef qdoc DirtyForceUpdate = 0x8000, DirtyUsePreprocess = UsePreprocess, @@ -122,7 +118,6 @@ public: | DirtyNodeAdded | DirtyOpacity | DirtyForceUpdate -#endif }; Q_DECLARE_FLAGS(DirtyState, DirtyStateBit) @@ -173,13 +168,13 @@ private: void init(); void destroy(); - QSGNode *m_parent; - NodeType m_type; - QSGNode *m_firstChild; - QSGNode *m_lastChild; - QSGNode *m_nextSibling; - QSGNode *m_previousSibling; - int m_subtreeRenderableCount; + QSGNode *m_parent = nullptr; + NodeType m_type = BasicNodeType; + QSGNode *m_firstChild = nullptr; + QSGNode *m_lastChild = nullptr; + QSGNode *m_nextSibling = nullptr; + QSGNode *m_previousSibling = nullptr; + int m_subtreeRenderableCount = 0; Flags m_nodeFlags; DirtyState m_dirtyState; // Obsolete, remove in Qt 6 @@ -195,7 +190,7 @@ void Q_QUICK_EXPORT qsgnode_set_description(QSGNode *node, const QString &descri class Q_QUICK_EXPORT QSGBasicGeometryNode : public QSGNode { public: - ~QSGBasicGeometryNode(); + ~QSGBasicGeometryNode() override; void setGeometry(QSGGeometry *geometry); const QSGGeometry *geometry() const { return m_geometry; } @@ -229,7 +224,7 @@ class Q_QUICK_EXPORT QSGGeometryNode : public QSGBasicGeometryNode { public: QSGGeometryNode(); - ~QSGGeometryNode(); + ~QSGGeometryNode() override; void setMaterial(QSGMaterial *material); QSGMaterial *material() const { return m_material; } @@ -251,18 +246,18 @@ protected: private: friend class QSGNodeUpdater; - int m_render_order; - QSGMaterial *m_material; - QSGMaterial *m_opaque_material; + int m_render_order = 0; + QSGMaterial *m_material = nullptr; + QSGMaterial *m_opaque_material = nullptr; - qreal m_opacity; + qreal m_opacity = 1; }; class Q_QUICK_EXPORT QSGClipNode : public QSGBasicGeometryNode { public: QSGClipNode(); - ~QSGClipNode(); + ~QSGClipNode() override; void setIsRectangular(bool rectHint); bool isRectangular() const { return m_is_rectangular; } @@ -282,7 +277,7 @@ class Q_QUICK_EXPORT QSGTransformNode : public QSGNode { public: QSGTransformNode(); - ~QSGTransformNode(); + ~QSGTransformNode() override; void setMatrix(const QMatrix4x4 &matrix); const QMatrix4x4 &matrix() const { return m_matrix; } @@ -300,7 +295,7 @@ class Q_QUICK_EXPORT QSGRootNode : public QSGNode { public: QSGRootNode(); - ~QSGRootNode(); + ~QSGRootNode() override; private: void notifyNodeChange(QSGNode *node, DirtyState state); @@ -317,7 +312,7 @@ class Q_QUICK_EXPORT QSGOpacityNode : public QSGNode { public: QSGOpacityNode(); - ~QSGOpacityNode(); + ~QSGOpacityNode() override; void setOpacity(qreal opacity); qreal opacity() const { return m_opacity; } @@ -328,8 +323,8 @@ public: bool isSubtreeBlocked() const override; private: - qreal m_opacity; - qreal m_combined_opacity; + qreal m_opacity = 1; + qreal m_combined_opacity = 1; }; class Q_QUICK_EXPORT QSGNodeVisitor { diff --git a/src/quick/scenegraph/coreapi/qsgnode_p.h b/src/quick/scenegraph/coreapi/qsgnode_p.h index 84d5477085..f81128f51a 100644 --- a/src/quick/scenegraph/coreapi/qsgnode_p.h +++ b/src/quick/scenegraph/coreapi/qsgnode_p.h @@ -78,18 +78,14 @@ public: class QSGBasicGeometryNodePrivate : public QSGNodePrivate { public: - QSGBasicGeometryNodePrivate() - : QSGNodePrivate() - {} + QSGBasicGeometryNodePrivate() {} }; class QSGGeometryNodePrivate: public QSGBasicGeometryNodePrivate { public: - QSGGeometryNodePrivate() - : QSGBasicGeometryNodePrivate() - {} + QSGGeometryNodePrivate() {} }; QT_END_NAMESPACE diff --git a/src/quick/scenegraph/coreapi/qsgnodeupdater.cpp b/src/quick/scenegraph/coreapi/qsgnodeupdater.cpp index d6d533307e..8bc9ded594 100644 --- a/src/quick/scenegraph/coreapi/qsgnodeupdater.cpp +++ b/src/quick/scenegraph/coreapi/qsgnodeupdater.cpp @@ -48,7 +48,7 @@ QT_BEGIN_NAMESPACE QSGNodeUpdater::QSGNodeUpdater() : m_combined_matrix_stack(64) , m_opacity_stack(64) - , m_current_clip(0) + , m_current_clip(nullptr) , m_force_update(0) { m_opacity_stack.add(1); @@ -60,7 +60,7 @@ QSGNodeUpdater::~QSGNodeUpdater() void QSGNodeUpdater::updateStates(QSGNode *n) { - m_current_clip = 0; + m_current_clip = nullptr; m_force_update = 0; Q_ASSERT(m_opacity_stack.size() == 1); // The one we added in the constructr... @@ -82,7 +82,7 @@ void QSGNodeUpdater::updateStates(QSGNode *n) bool QSGNodeUpdater::isNodeBlocked(QSGNode *node, QSGNode *root) const { - while (node != root && node != 0) { + while (node != root && node != nullptr) { if (node->isSubtreeBlocked()) return true; node = node->parent(); diff --git a/src/quick/scenegraph/coreapi/qsgrenderer.cpp b/src/quick/scenegraph/coreapi/qsgrenderer.cpp index 3ae79a933f..e1ba001d2d 100644 --- a/src/quick/scenegraph/coreapi/qsgrenderer.cpp +++ b/src/quick/scenegraph/coreapi/qsgrenderer.cpp @@ -132,8 +132,8 @@ QSGRenderer::QSGRenderer(QSGRenderContext *context) , m_current_determinant(1) , m_device_pixel_ratio(1) , m_context(context) - , m_node_updater(0) - , m_bindable(0) + , m_node_updater(nullptr) + , m_bindable(nullptr) , m_changed_emitted(false) , m_is_rendering(false) , m_is_preprocessing(false) @@ -143,7 +143,7 @@ QSGRenderer::QSGRenderer(QSGRenderContext *context) QSGRenderer::~QSGRenderer() { - setRootNode(0); + setRootNode(nullptr); delete m_node_updater; } @@ -249,7 +249,7 @@ void QSGRenderer::renderScene(const QSGBindable &bindable) m_is_rendering = false; m_changed_emitted = false; - m_bindable = 0; + m_bindable = nullptr; qCDebug(QSG_LOG_TIME_RENDERER, "time in renderer: total=%dms, preprocess=%d, updates=%d, binding=%d, rendering=%d", diff --git a/src/quick/scenegraph/coreapi/qsgrenderer_p.h b/src/quick/scenegraph/coreapi/qsgrenderer_p.h index ae8d9f75d2..8362ff54dc 100644 --- a/src/quick/scenegraph/coreapi/qsgrenderer_p.h +++ b/src/quick/scenegraph/coreapi/qsgrenderer_p.h @@ -168,12 +168,12 @@ class Q_QUICK_PRIVATE_EXPORT QSGNodeDumper : public QSGNodeVisitor { public: static void dump(QSGNode *n); - QSGNodeDumper() : m_indent(0) {} + QSGNodeDumper() {} void visitNode(QSGNode *n) override; void visitChildren(QSGNode *n) override; private: - int m_indent; + int m_indent = 0; }; diff --git a/src/quick/scenegraph/coreapi/qsgrendernode.cpp b/src/quick/scenegraph/coreapi/qsgrendernode.cpp index a8954848d6..df3fa16a32 100644 --- a/src/quick/scenegraph/coreapi/qsgrendernode.cpp +++ b/src/quick/scenegraph/coreapi/qsgrendernode.cpp @@ -74,8 +74,8 @@ QSGRenderNode::~QSGRenderNode() } QSGRenderNodePrivate::QSGRenderNodePrivate() - : m_matrix(0) - , m_clip_list(0) + : m_matrix(nullptr) + , m_clip_list(nullptr) , m_opacity(1) { } @@ -119,7 +119,7 @@ QSGRenderNodePrivate::QSGRenderNodePrivate() */ QSGRenderNode::StateFlags QSGRenderNode::changedStates() const { - return 0; + return nullptr; } /*! @@ -213,6 +213,22 @@ void QSGRenderNode::releaseResources() } /*! + \enum QSGRenderNode::StateFlag + + This enum is a bit mask identifying several states. + + \value DepthState Depth + \value StencilState Stencil + \value ScissorState Scissor + \value ColorState Color + \value BlendState Blend + \value CullState Cull + \value ViewportState View poirt + \value RenderTargetState Render target + + */ + +/*! \enum QSGRenderNode::RenderingFlag Possible values for the bitmask returned from flags(). @@ -251,7 +267,7 @@ void QSGRenderNode::releaseResources() */ QSGRenderNode::RenderingFlags QSGRenderNode::flags() const { - return 0; + return nullptr; } /*! @@ -354,7 +370,7 @@ QSGRenderNode::RenderState::~RenderState() */ /*! - \fn const QRegion *QSGRenderNode::clipRegion() const + \fn const QRegion *QSGRenderNode::RenderState::clipRegion() const \return the current clip region or null for backends where clipping is implemented via stencil or scissoring. diff --git a/src/quick/scenegraph/coreapi/qsgrendernode.h b/src/quick/scenegraph/coreapi/qsgrendernode.h index f6bc40d3ee..0fb83b080c 100644 --- a/src/quick/scenegraph/coreapi/qsgrendernode.h +++ b/src/quick/scenegraph/coreapi/qsgrendernode.h @@ -80,7 +80,7 @@ public: }; QSGRenderNode(); - ~QSGRenderNode(); + ~QSGRenderNode() override; virtual StateFlags changedStates() const; virtual void render(const RenderState *state) = 0; diff --git a/src/quick/scenegraph/qsgadaptationlayer_p.h b/src/quick/scenegraph/qsgadaptationlayer_p.h index ba146b884f..9c88b8272c 100644 --- a/src/quick/scenegraph/qsgadaptationlayer_p.h +++ b/src/quick/scenegraph/qsgadaptationlayer_p.h @@ -266,19 +266,19 @@ public: Texture // for APIs with separate texture and sampler objects }; struct InputParameter { - InputParameter() : semanticIndex(0) { } + InputParameter() {} // Semantics use the D3D keys (POSITION, TEXCOORD). // Attribute name based APIs can map based on pre-defined names. QByteArray semanticName; - int semanticIndex; + int semanticIndex = 0; }; struct Variable { - Variable() : type(Constant), offset(0), size(0), bindPoint(0) { } - VariableType type; + Variable() {} + VariableType type = Constant; QByteArray name; - uint offset; // for cbuffer members - uint size; // for cbuffer members - int bindPoint; // for textures and samplers; for register-based APIs + uint offset = 0; // for cbuffer members + uint size = 0; // for cbuffer members + int bindPoint = 0; // for textures and samplers; for register-based APIs }; QByteArray blob; // source or bytecode @@ -329,8 +329,8 @@ public: }; struct ShaderData { - ShaderData() : hasShaderCode(false) { } - bool hasShaderCode; + ShaderData() {} + bool hasShaderCode = false; QSGGuiThreadShaderEffectManager::ShaderInfo shaderInfo; QVector<VariableData> varData; }; @@ -373,7 +373,7 @@ public: HighQualitySubPixelAntialiasing }; - QSGGlyphNode() : m_ownerElement(0) {} + QSGGlyphNode() {} virtual void setGlyphs(const QPointF &position, const QGlyphRun &glyphs) = 0; virtual void setColor(const QColor &color) = 0; @@ -394,7 +394,7 @@ public: void accept(QSGNodeVisitorEx *visitor) override { if (visitor->visit(this)) visitor->visitChildren(this); visitor->endVisit(this); } protected: QRectF m_bounding_rect; - QQuickItem *m_ownerElement; + QQuickItem *m_ownerElement = nullptr; }; class Q_QUICK_PRIVATE_EXPORT QSGDistanceFieldGlyphConsumer @@ -421,24 +421,24 @@ public: }; struct TexCoord { - qreal x; - qreal y; - qreal width; - qreal height; - qreal xMargin; - qreal yMargin; + qreal x = 0; + qreal y = 0; + qreal width = -1; + qreal height = -1; + qreal xMargin = 0; + qreal yMargin = 0; - TexCoord() : x(0), y(0), width(-1), height(-1), xMargin(0), yMargin(0) { } + TexCoord() {} bool isNull() const { return width <= 0 || height <= 0; } bool isValid() const { return width >= 0 && height >= 0; } }; struct Texture { - uint textureId; + uint textureId = 0; QSize size; - Texture() : textureId(0), size(QSize()) { } + Texture() : size(QSize()) { } bool operator == (const Texture &other) const { return textureId == other.textureId; } }; @@ -478,13 +478,13 @@ protected: }; struct GlyphData { - Texture *texture; + Texture *texture = nullptr; TexCoord texCoord; QRectF boundingRect; QPainterPath path; - quint32 ref; + quint32 ref = 0; - GlyphData() : texture(0), ref(0) { } + GlyphData() {} }; virtual void requestGlyphs(const QSet<glyph_t> &glyphs) = 0; diff --git a/src/quick/scenegraph/qsgbasicglyphnode.cpp b/src/quick/scenegraph/qsgbasicglyphnode.cpp index 38f650a82c..4559b7951c 100644 --- a/src/quick/scenegraph/qsgbasicglyphnode.cpp +++ b/src/quick/scenegraph/qsgbasicglyphnode.cpp @@ -44,7 +44,7 @@ QT_BEGIN_NAMESPACE QSGBasicGlyphNode::QSGBasicGlyphNode() : m_style(QQuickText::Normal) - , m_material(0) + , m_material(nullptr) , m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 0) { m_geometry.setDrawingMode(QSGGeometry::DrawTriangles); @@ -59,7 +59,7 @@ QSGBasicGlyphNode::~QSGBasicGlyphNode() void QSGBasicGlyphNode::setColor(const QColor &color) { m_color = color; - if (m_material != 0) { + if (m_material != nullptr) { setMaterialColor(color); markDirty(DirtyMaterial); } @@ -67,7 +67,7 @@ void QSGBasicGlyphNode::setColor(const QColor &color) void QSGBasicGlyphNode::setGlyphs(const QPointF &position, const QGlyphRun &glyphs) { - if (m_material != 0) + if (m_material != nullptr) delete m_material; m_position = position; diff --git a/src/quick/scenegraph/qsgcontext.cpp b/src/quick/scenegraph/qsgcontext.cpp index fb66a6ebb1..d9ed25c099 100644 --- a/src/quick/scenegraph/qsgcontext.cpp +++ b/src/quick/scenegraph/qsgcontext.cpp @@ -363,13 +363,6 @@ void QSGRenderContext::registerFontengineForCleanup(QFontEngine *engine) } /*! - Factory function for texture objects. - - If \a image is a valid image, the QSGTexture::setImage function - will be called with \a image as argument. - */ - -/*! Factory function for the scene graph renderers. The renderers are used for the toplevel renderer and once for every @@ -379,7 +372,7 @@ void QSGRenderContext::registerFontengineForCleanup(QFontEngine *engine) QSGTexture *QSGRenderContext::textureForFactory(QQuickTextureFactory *factory, QQuickWindow *window) { if (!factory) - return 0; + return nullptr; m_mutex.lock(); QSGTexture *texture = m_textures.value(factory); @@ -404,6 +397,20 @@ void QSGRenderContext::textureFactoryDestroyed(QObject *o) m_mutex.unlock(); } +/*! + Return the texture corresponding to a texture factory. + + This may optionally manipulate the texture in some way; for example by returning + an atlased texture. + + This function is not a replacement for textureForFactory; both should be used + for a single texture (this might atlas, while the other might cache). +*/ +QSGTexture *QSGRenderContext::compressedTextureForFactory(const QSGCompressedTextureFactory *) const +{ + return nullptr; +} + #include "qsgcontext.moc" #include "moc_qsgcontext_p.cpp" diff --git a/src/quick/scenegraph/qsgcontext_p.h b/src/quick/scenegraph/qsgcontext_p.h index 84a2523f26..6d70d7ef6b 100644 --- a/src/quick/scenegraph/qsgcontext_p.h +++ b/src/quick/scenegraph/qsgcontext_p.h @@ -78,6 +78,7 @@ class QSGMaterial; class QSGRenderLoop; class QSGLayer; class QQuickTextureFactory; +class QSGCompressedTextureFactory; class QSGContext; class QQuickPaintedItem; class QSGRendererInterface; @@ -109,8 +110,8 @@ public: MsaaAntialiasing }; - explicit QSGContext(QObject *parent = 0); - virtual ~QSGContext(); + explicit QSGContext(QObject *parent = nullptr); + ~QSGContext() override; virtual void renderContextInitialized(QSGRenderContext *renderContext); virtual void renderContextInvalidated(QSGRenderContext *renderContext); @@ -158,7 +159,7 @@ public: }; QSGRenderContext(QSGContext *context); - virtual ~QSGRenderContext(); + ~QSGRenderContext() override; QSGContext *sceneGraphContext() const { return m_sg; } virtual bool isValid() const { return true; } @@ -173,6 +174,7 @@ public: virtual QSGTexture *createTexture(const QImage &image, uint flags = CreateTexture_Alpha) const = 0; virtual QSGRenderer *createRenderer() = 0; + virtual QSGTexture *compressedTextureForFactory(const QSGCompressedTextureFactory *) const; virtual void setAttachToGraphicsContext(bool attach) { Q_UNUSED(attach); } diff --git a/src/quick/scenegraph/qsgcontextplugin.cpp b/src/quick/scenegraph/qsgcontextplugin.cpp index 1c2550d197..31f1c4c722 100644 --- a/src/quick/scenegraph/qsgcontextplugin.cpp +++ b/src/quick/scenegraph/qsgcontextplugin.cpp @@ -74,8 +74,8 @@ struct QSGAdaptationBackendData { QSGAdaptationBackendData(); - bool tried; - QSGContextFactoryInterface *factory; + bool tried = false; + QSGContextFactoryInterface *factory = nullptr; QString name; QSGContextFactoryInterface::Flags flags; @@ -85,9 +85,7 @@ struct QSGAdaptationBackendData }; QSGAdaptationBackendData::QSGAdaptationBackendData() - : tried(false) - , factory(nullptr) - , flags(0) + : flags(nullptr) { // Fill in the table with the built-in adaptations. builtIns.append(new QSGSoftwareAdaptation); @@ -140,7 +138,9 @@ QSGAdaptationBackendData *contextFactory() #ifdef Q_OS_HTML5 requestedBackend = QString::fromLocal8Bit("software"); #endif + if (!requestedBackend.isEmpty()) { + qCDebug(QSG_LOG_INFO, "Loading backend %s", qUtf8Printable(requestedBackend)); // First look for a built-in adaptation. for (QSGContextFactoryInterface *builtInBackend : qAsConst(backendData->builtIns)) { @@ -210,7 +210,7 @@ QQuickTextureFactory *QSGContext::createTextureFactoryFromImage(const QImage &im QSGAdaptationBackendData *backendData = contextFactory(); if (backendData->factory) return backendData->factory->createTextureFactoryFromImage(image); - return 0; + return nullptr; } @@ -224,7 +224,7 @@ QSGRenderLoop *QSGContext::createWindowManager() QSGAdaptationBackendData *backendData = contextFactory(); if (backendData->factory) return backendData->factory->createWindowManager(); - return 0; + return nullptr; } void QSGContext::setBackend(const QString &backend) diff --git a/src/quick/scenegraph/qsgcontextplugin_p.h b/src/quick/scenegraph/qsgcontextplugin_p.h index 02d4b79b76..d37d4df270 100644 --- a/src/quick/scenegraph/qsgcontextplugin_p.h +++ b/src/quick/scenegraph/qsgcontextplugin_p.h @@ -87,13 +87,13 @@ class Q_QUICK_PRIVATE_EXPORT QSGContextPlugin : public QObject, public QSGContex Q_OBJECT Q_INTERFACES(QSGContextFactoryInterface:QFactoryInterface) public: - explicit QSGContextPlugin(QObject *parent = 0); + explicit QSGContextPlugin(QObject *parent = nullptr); virtual ~QSGContextPlugin(); QStringList keys() const override = 0; - QQuickTextureFactory *createTextureFactoryFromImage(const QImage &) override { return 0; } - QSGRenderLoop *createWindowManager() override { return 0; } + QQuickTextureFactory *createTextureFactoryFromImage(const QImage &) override { return nullptr; } + QSGRenderLoop *createWindowManager() override { return nullptr; } }; QT_END_NAMESPACE diff --git a/src/quick/scenegraph/qsgdefaultcontext.cpp b/src/quick/scenegraph/qsgdefaultcontext.cpp index be5fec9dab..9a0ac66690 100644 --- a/src/quick/scenegraph/qsgdefaultcontext.cpp +++ b/src/quick/scenegraph/qsgdefaultcontext.cpp @@ -149,20 +149,23 @@ void QSGDefaultContext::renderContextInitialized(QSGRenderContext *renderContext dumped = true; QSurfaceFormat format = openglRenderContext->openglContext()->format(); QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); - qCDebug(QSG_LOG_INFO) << "R/G/B/A Buffers: " << format.redBufferSize() << format.greenBufferSize() << format.blueBufferSize() << format.alphaBufferSize(); - qCDebug(QSG_LOG_INFO) << "Depth Buffer: " << format.depthBufferSize(); - qCDebug(QSG_LOG_INFO) << "Stencil Buffer: " << format.stencilBufferSize(); - qCDebug(QSG_LOG_INFO) << "Samples: " << format.samples(); - qCDebug(QSG_LOG_INFO) << "GL_VENDOR: " << (const char *) funcs->glGetString(GL_VENDOR); - qCDebug(QSG_LOG_INFO) << "GL_RENDERER: " << (const char *) funcs->glGetString(GL_RENDERER); - qCDebug(QSG_LOG_INFO) << "GL_VERSION: " << (const char *) funcs->glGetString(GL_VERSION); + qCDebug(QSG_LOG_INFO, "R/G/B/A Buffers: %d %d %d %d", format.redBufferSize(), + format.greenBufferSize(), format.blueBufferSize(), format.alphaBufferSize()); + qCDebug(QSG_LOG_INFO, "Depth Buffer: %d", format.depthBufferSize()); + qCDebug(QSG_LOG_INFO, "Stencil Buffer: %d", format.stencilBufferSize()); + qCDebug(QSG_LOG_INFO, "Samples: %d", format.samples()); + qCDebug(QSG_LOG_INFO, "GL_VENDOR: %s", (const char*)funcs->glGetString(GL_VENDOR)); + qCDebug(QSG_LOG_INFO, "GL_RENDERER: %s", + (const char*)funcs->glGetString(GL_RENDERER)); + qCDebug(QSG_LOG_INFO, "GL_VERSION: %s", (const char*)funcs->glGetString(GL_VERSION)); QSet<QByteArray> exts = openglRenderContext->openglContext()->extensions(); QByteArray all; for (const QByteArray &e : qAsConst(exts)) all += ' ' + e; - qCDebug(QSG_LOG_INFO) << "GL_EXTENSIONS: " << all.constData(); - qCDebug(QSG_LOG_INFO) << "Max Texture Size: " << openglRenderContext->maxTextureSize(); - qCDebug(QSG_LOG_INFO) << "Debug context: " << format.testOption(QSurfaceFormat::DebugContext); + qCDebug(QSG_LOG_INFO, "GL_EXTENSIONS: %s", all.constData()); + qCDebug(QSG_LOG_INFO, "Max Texture Size: %d", openglRenderContext->maxTextureSize()); + qCDebug(QSG_LOG_INFO, "Debug context: %s", + format.testOption(QSurfaceFormat::DebugContext) ? "true" : "false"); } m_mutex.unlock(); diff --git a/src/quick/scenegraph/qsgdefaultcontext_p.h b/src/quick/scenegraph/qsgdefaultcontext_p.h index b2964bf403..6dfd197cf6 100644 --- a/src/quick/scenegraph/qsgdefaultcontext_p.h +++ b/src/quick/scenegraph/qsgdefaultcontext_p.h @@ -60,7 +60,7 @@ QT_BEGIN_NAMESPACE class Q_QUICK_PRIVATE_EXPORT QSGDefaultContext : public QSGContext, public QSGRendererInterface { public: - QSGDefaultContext(QObject *parent = 0); + QSGDefaultContext(QObject *parent = nullptr); ~QSGDefaultContext(); void renderContextInitialized(QSGRenderContext *renderContext) override; diff --git a/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp b/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp index 7789ef8fb1..ef189ba461 100644 --- a/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp +++ b/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp @@ -63,12 +63,12 @@ QSGDefaultDistanceFieldGlyphCache::QSGDefaultDistanceFieldGlyphCache(QOpenGLCont : QSGDistanceFieldGlyphCache(c, font) , m_maxTextureSize(0) , m_maxTextureCount(3) - , m_blitProgram(0) + , m_blitProgram(nullptr) , m_blitBuffer(QOpenGLBuffer::VertexBuffer) - , m_fboGuard(0) + , m_fboGuard(nullptr) , m_funcs(c->functions()) #if !defined(QT_OPENGL_ES_2) - , m_coreFuncs(0) + , m_coreFuncs(nullptr) #endif { if (Q_LIKELY(m_blitBuffer.create())) { @@ -89,7 +89,7 @@ QSGDefaultDistanceFieldGlyphCache::~QSGDefaultDistanceFieldGlyphCache() for (int i = 0; i < m_textures.count(); ++i) m_funcs->glDeleteTextures(1, &m_textures[i].texture); - if (m_fboGuard != 0) + if (m_fboGuard != nullptr) m_fboGuard->free(); delete m_blitProgram; @@ -400,7 +400,7 @@ void QSGDefaultDistanceFieldGlyphCache::resizeTexture(TextureInfo *texInfo, int m_funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); #endif m_funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, oldWidth, oldHeight, 0, - GL_RGBA, GL_UNSIGNED_BYTE, NULL); + GL_RGBA, GL_UNSIGNED_BYTE, nullptr); m_funcs->glBindTexture(GL_TEXTURE_2D, 0); m_funcs->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tmp_texture, 0); diff --git a/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache_p.h b/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache_p.h index fe365495c2..76c0d20647 100644 --- a/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache_p.h +++ b/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache_p.h @@ -91,10 +91,9 @@ private: QSize size; QRect allocatedArea; QDistanceField image; - int padding; + int padding = -1; - TextureInfo(const QRect &preallocRect = QRect()) : texture(0), allocatedArea(preallocRect), padding(-1) - { } + TextureInfo(const QRect &preallocRect = QRect()) : texture(0), allocatedArea(preallocRect) { } }; void createTexture(TextureInfo * texInfo, int width, int height); diff --git a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp index 0169f097bc..dc473a6640 100644 --- a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp +++ b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp @@ -107,7 +107,7 @@ protected: char const *const *QSGTextMaskShader::attributeNames() const { - static char const *const attr[] = { "vCoord", "tCoord", 0 }; + static char const *const attr[] = { "vCoord", "tCoord", nullptr }; return attr; } @@ -141,13 +141,13 @@ void QSGTextMaskShader::updateState(const RenderState &state, QSGMaterial *newEf { QSGTextMaskMaterial *material = static_cast<QSGTextMaskMaterial *>(newEffect); QSGTextMaskMaterial *oldMaterial = static_cast<QSGTextMaskMaterial *>(oldEffect); - Q_ASSERT(oldEffect == 0 || newEffect->type() == oldEffect->type()); + Q_ASSERT(oldEffect == nullptr || newEffect->type() == oldEffect->type()); bool updated = material->ensureUpToDate(); Q_ASSERT(material->texture()); - Q_ASSERT(oldMaterial == 0 || oldMaterial->texture()); + Q_ASSERT(oldMaterial == nullptr || oldMaterial->texture()); if (updated - || oldMaterial == 0 + || oldMaterial == nullptr || oldMaterial->texture()->textureId() != material->texture()->textureId()) { program()->setUniformValue(m_textureScale_id, QVector2D(1.0 / material->cacheTextureWidth(), 1.0 / material->cacheTextureHeight())); @@ -190,7 +190,7 @@ void QSG8BitTextMaskShader::updateState(const RenderState &state, QSGMaterial *n QSGTextMaskMaterial *material = static_cast<QSGTextMaskMaterial *>(newEffect); QSGTextMaskMaterial *oldMaterial = static_cast<QSGTextMaskMaterial *>(oldEffect); - if (oldMaterial == 0 || material->color() != oldMaterial->color() || state.isOpacityDirty()) { + if (oldMaterial == nullptr || material->color() != oldMaterial->color() || state.isOpacityDirty()) { QVector4D color = qsg_premultiply(material->color(), state.opacity()); program()->setUniformValue(m_color_id, color); } @@ -282,7 +282,7 @@ void QSG24BitTextMaskShader::updateState(const RenderState &state, QSGMaterial * QSGTextMaskMaterial *material = static_cast<QSGTextMaskMaterial *>(newEffect); QSGTextMaskMaterial *oldMaterial = static_cast<QSGTextMaskMaterial *>(oldEffect); - if (oldMaterial == 0 || material->color() != oldMaterial->color() || state.isOpacityDirty()) { + if (oldMaterial == nullptr || material->color() != oldMaterial->color() || state.isOpacityDirty()) { QVector4D color = material->color(); if (useSRGB()) color = qt_sRGB_to_linear_RGB(color); @@ -346,20 +346,20 @@ void QSGStyledTextShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) { - Q_ASSERT(oldEffect == 0 || newEffect->type() == oldEffect->type()); + Q_ASSERT(oldEffect == nullptr || newEffect->type() == oldEffect->type()); QSGStyledTextMaterial *material = static_cast<QSGStyledTextMaterial *>(newEffect); QSGStyledTextMaterial *oldMaterial = static_cast<QSGStyledTextMaterial *>(oldEffect); - if (oldMaterial == 0 || oldMaterial->styleShift() != material->styleShift()) + if (oldMaterial == nullptr || oldMaterial->styleShift() != material->styleShift()) program()->setUniformValue(m_shift_id, material->styleShift()); - if (oldMaterial == 0 || material->color() != oldMaterial->color() || state.isOpacityDirty()) { + if (oldMaterial == nullptr || material->color() != oldMaterial->color() || state.isOpacityDirty()) { QVector4D color = qsg_premultiply(material->color(), state.opacity()); program()->setUniformValue(m_color_id, color); } - if (oldMaterial == 0 || material->styleColor() != oldMaterial->styleColor() || state.isOpacityDirty()) { + if (oldMaterial == nullptr || material->styleColor() != oldMaterial->styleColor() || state.isOpacityDirty()) { QVector4D styleColor = qsg_premultiply(material->styleColor(), state.opacity()); program()->setUniformValue(m_styleColor_id, styleColor); } @@ -367,9 +367,9 @@ void QSGStyledTextShader::updateState(const RenderState &state, bool updated = material->ensureUpToDate(); Q_ASSERT(material->texture()); - Q_ASSERT(oldMaterial == 0 || oldMaterial->texture()); + Q_ASSERT(oldMaterial == nullptr || oldMaterial->texture()); if (updated - || oldMaterial == 0 + || oldMaterial == nullptr || oldMaterial->texture()->textureId() != material->texture()->textureId()) { program()->setUniformValue(m_textureScale_id, QVector2D(1.0 / material->cacheTextureWidth(), 1.0 / material->cacheTextureHeight())); @@ -400,8 +400,8 @@ public: }; QSGTextMaskMaterial::QSGTextMaskMaterial(const QRawFont &font, QFontEngine::GlyphFormat glyphFormat) - : m_texture(0) - , m_glyphCache(0) + : m_texture(nullptr) + , m_glyphCache(nullptr) , m_font(font) { init(glyphFormat); @@ -419,7 +419,7 @@ void QSGTextMaskMaterial::init(QFontEngine::GlyphFormat glyphFormat) setFlag(Blending, true); QOpenGLContext *ctx = const_cast<QOpenGLContext *>(QOpenGLContext::currentContext()); - Q_ASSERT(ctx != 0); + Q_ASSERT(ctx != nullptr); // The following piece of code will read/write to the font engine's caches, // potentially from different threads. However, this is safe because this diff --git a/src/quick/scenegraph/qsgdefaultinternalimagenode.cpp b/src/quick/scenegraph/qsgdefaultinternalimagenode.cpp index a5a6da06a7..5dd6eaa4ca 100644 --- a/src/quick/scenegraph/qsgdefaultinternalimagenode.cpp +++ b/src/quick/scenegraph/qsgdefaultinternalimagenode.cpp @@ -83,7 +83,6 @@ QSGMaterialShader *QSGSmoothTextureMaterial::createShader() const } SmoothTextureMaterialShader::SmoothTextureMaterialShader() - : QSGTextureMaterialShader() { setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/qt-project.org/scenegraph/shaders/smoothtexture.vert")); setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/qt-project.org/scenegraph/shaders/smoothtexture.frag")); @@ -91,7 +90,7 @@ SmoothTextureMaterialShader::SmoothTextureMaterialShader() void SmoothTextureMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) { - if (oldEffect == 0) { + if (oldEffect == nullptr) { // The viewport is constant, so set the pixel size uniform only once. QRect r = state.viewportRect(); program()->setUniformValue(m_pixelSizeLoc, 2.0f / r.width(), 2.0f / r.height()); @@ -106,7 +105,7 @@ char const *const *SmoothTextureMaterialShader::attributeNames() const "multiTexCoord", "vertexOffset", "texCoordOffset", - 0 + nullptr }; return attributes; } @@ -171,7 +170,7 @@ void QSGDefaultInternalImageNode::updateMaterialAntialiasing() { if (m_antialiasing) { setMaterial(&m_smoothMaterial); - setOpaqueMaterial(0); + setOpaqueMaterial(nullptr); } else { setMaterial(&m_materialO); setOpaqueMaterial(&m_material); diff --git a/src/quick/scenegraph/qsgdefaultinternalrectanglenode.cpp b/src/quick/scenegraph/qsgdefaultinternalrectanglenode.cpp index e52dcaad52..fd0dcebd57 100644 --- a/src/quick/scenegraph/qsgdefaultinternalrectanglenode.cpp +++ b/src/quick/scenegraph/qsgdefaultinternalrectanglenode.cpp @@ -67,7 +67,6 @@ private: }; SmoothColorMaterialShader::SmoothColorMaterialShader() - : QSGMaterialShader() { setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/qt-project.org/scenegraph/shaders/smoothcolor.vert")); setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/qt-project.org/scenegraph/shaders/smoothcolor.frag")); @@ -81,7 +80,7 @@ void SmoothColorMaterialShader::updateState(const RenderState &state, QSGMateria if (state.isMatrixDirty()) program()->setUniformValue(m_matrixLoc, state.combinedMatrix()); - if (oldEffect == 0) { + if (oldEffect == nullptr) { // The viewport is constant, so set the pixel size uniform only once. QRect r = state.viewportRect(); program()->setUniformValue(m_pixelSizeLoc, 2.0f / r.width(), 2.0f / r.height()); @@ -94,7 +93,7 @@ char const *const *SmoothColorMaterialShader::attributeNames() const "vertex", "vertexColor", "vertexOffset", - 0 + nullptr }; return attributes; } diff --git a/src/quick/scenegraph/qsgdefaultlayer.cpp b/src/quick/scenegraph/qsgdefaultlayer.cpp index cd9c4a9a90..b2b123912f 100644 --- a/src/quick/scenegraph/qsgdefaultlayer.cpp +++ b/src/quick/scenegraph/qsgdefaultlayer.cpp @@ -90,15 +90,15 @@ namespace QSGDefaultLayer::QSGDefaultLayer(QSGRenderContext *context) : QSGLayer() - , m_item(0) + , m_item(nullptr) , m_device_pixel_ratio(1) , m_format(GL_RGBA) - , m_renderer(0) - , m_fbo(0) - , m_secondaryFbo(0) + , m_renderer(nullptr) + , m_fbo(nullptr) + , m_secondaryFbo(nullptr) , m_transparentTexture(0) #ifdef QSG_DEBUG_FBO_OVERLAY - , m_debugOverlay(0) + , m_debugOverlay(nullptr) #endif , m_samples(0) , m_mipmap(false) @@ -122,13 +122,13 @@ QSGDefaultLayer::~QSGDefaultLayer() void QSGDefaultLayer::invalidated() { delete m_renderer; - m_renderer = 0; + m_renderer = nullptr; delete m_fbo; delete m_secondaryFbo; - m_fbo = m_secondaryFbo = 0; + m_fbo = m_secondaryFbo = nullptr; #ifdef QSG_DEBUG_FBO_OVERLAY delete m_debugOverlay; - m_debugOverlay = 0; + m_debugOverlay = nullptr; #endif if (m_transparentTexture) { QOpenGLContext::currentContext()->functions()->glDeleteTextures(1, &m_transparentTexture); @@ -204,7 +204,7 @@ void QSGDefaultLayer::setItem(QSGNode *item) if (m_live && !m_item) { delete m_fbo; delete m_secondaryFbo; - m_fbo = m_secondaryFbo = 0; + m_fbo = m_secondaryFbo = nullptr; m_depthStencilBuffer.clear(); } @@ -228,7 +228,7 @@ void QSGDefaultLayer::setSize(const QSize &size) if (m_live && m_size.isNull()) { delete m_fbo; delete m_secondaryFbo; - m_fbo = m_secondaryFbo = 0; + m_fbo = m_secondaryFbo = nullptr; m_depthStencilBuffer.clear(); } @@ -252,7 +252,7 @@ void QSGDefaultLayer::setLive(bool live) if (m_live && (!m_item || m_size.isNull())) { delete m_fbo; delete m_secondaryFbo; - m_fbo = m_secondaryFbo = 0; + m_fbo = m_secondaryFbo = nullptr; m_depthStencilBuffer.clear(); } @@ -295,7 +295,7 @@ void QSGDefaultLayer::grab() if (!m_item || m_size.isNull()) { delete m_fbo; delete m_secondaryFbo; - m_fbo = m_secondaryFbo = 0; + m_fbo = m_secondaryFbo = nullptr; m_depthStencilBuffer.clear(); m_dirtyTexture = false; return; @@ -362,7 +362,7 @@ void QSGDefaultLayer::grab() delete m_fbo; delete m_secondaryFbo; m_fbo = new QOpenGLFramebufferObject(m_size, format); - m_secondaryFbo = 0; + m_secondaryFbo = nullptr; funcs->glBindTexture(GL_TEXTURE_2D, m_fbo->texture()); updateBindOptions(true); m_depthStencilBuffer = m_context->depthStencilBufferForFbo(m_fbo); diff --git a/src/quick/scenegraph/qsgdefaultrendercontext.cpp b/src/quick/scenegraph/qsgdefaultrendercontext.cpp index 95f3555994..7882496062 100644 --- a/src/quick/scenegraph/qsgdefaultrendercontext.cpp +++ b/src/quick/scenegraph/qsgdefaultrendercontext.cpp @@ -44,6 +44,7 @@ #include <QtQuick/private/qsgbatchrenderer_p.h> #include <QtQuick/private/qsgrenderer_p.h> #include <QtQuick/private/qsgatlastexture_p.h> +#include <QtQuick/private/qsgcompressedtexture_p.h> #include <QtQuick/private/qsgdefaultdistancefieldglyphcache_p.h> QT_BEGIN_NAMESPACE @@ -156,14 +157,14 @@ void QSGDefaultRenderContext::invalidate() m_fontEnginesToClean.clear(); delete m_depthStencilManager; - m_depthStencilManager = 0; + m_depthStencilManager = nullptr; qDeleteAll(m_glyphCaches); m_glyphCaches.clear(); if (m_gl->property(QSG_RENDERCONTEXT_PROPERTY) == QVariant::fromValue(this)) m_gl->setProperty(QSG_RENDERCONTEXT_PROPERTY, QVariant()); - m_gl = 0; + m_gl = nullptr; if (m_sg) m_sg->renderContextInvalidated(this); @@ -210,7 +211,7 @@ QSharedPointer<QSGDepthStencilBuffer> QSGDefaultRenderContext::depthStencilBuffe QSGDepthStencilBufferManager *QSGDefaultRenderContext::depthStencilBufferManager() { if (!m_gl) - return 0; + return nullptr; if (!m_depthStencilManager) m_depthStencilManager = new QSGDepthStencilBufferManager(m_gl); return m_depthStencilManager; @@ -243,6 +244,14 @@ QSGRenderer *QSGDefaultRenderContext::createRenderer() return new QSGBatchRenderer::Renderer(this); } +QSGTexture *QSGDefaultRenderContext::compressedTextureForFactory(const QSGCompressedTextureFactory *factory) const +{ + // The atlas implementation is only supported from the render thread + if (openglContext() && QThread::currentThread() == openglContext()->thread()) + return m_atlasManager->create(factory); + return nullptr; +} + /*! Compile \a shader, optionally using \a vertexCode and \a fragmentCode as replacement for the source code supplied by \a shader. diff --git a/src/quick/scenegraph/qsgdefaultrendercontext_p.h b/src/quick/scenegraph/qsgdefaultrendercontext_p.h index 2537a06988..eb62586a94 100644 --- a/src/quick/scenegraph/qsgdefaultrendercontext_p.h +++ b/src/quick/scenegraph/qsgdefaultrendercontext_p.h @@ -84,8 +84,9 @@ public: QSGTexture *createTexture(const QImage &image, uint flags) const override; QSGRenderer *createRenderer() override; + QSGTexture *compressedTextureForFactory(const QSGCompressedTextureFactory *factory) const override; - virtual void compileShader(QSGMaterialShader *shader, QSGMaterial *material, const char *vertexCode = 0, const char *fragmentCode = 0); + virtual void compileShader(QSGMaterialShader *shader, QSGMaterial *material, const char *vertexCode = nullptr, const char *fragmentCode = nullptr); virtual void initializeShader(QSGMaterialShader *shader); void setAttachToGraphicsContext(bool attach) override; diff --git a/src/quick/scenegraph/qsgdefaultspritenode.cpp b/src/quick/scenegraph/qsgdefaultspritenode.cpp index 7fe6048d59..8761d99c1f 100644 --- a/src/quick/scenegraph/qsgdefaultspritenode.cpp +++ b/src/quick/scenegraph/qsgdefaultspritenode.cpp @@ -70,26 +70,18 @@ public: return this - static_cast<const QQuickSpriteMaterial *>(other); } - QSGTexture *texture; - - float animT; - float animX1; - float animY1; - float animX2; - float animY2; - float animW; - float animH; + QSGTexture *texture = nullptr; + + float animT = 0.0f; + float animX1 = 0.0f; + float animY1 = 0.0f; + float animX2 = 0.0f; + float animY2 = 0.0f; + float animW = 1.0f; + float animH = 1.0f; }; QQuickSpriteMaterial::QQuickSpriteMaterial() - : texture(0) - , animT(0.0f) - , animX1(0.0f) - , animY1(0.0f) - , animX2(0.0f) - , animY2(0.0f) - , animW(1.0f) - , animH(1.0f) { setFlag(Blending, true); } @@ -103,7 +95,6 @@ class SpriteMaterialData : public QSGMaterialShader { public: SpriteMaterialData() - : QSGMaterialShader() { setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/qt-project.org/scenegraph/shaders/sprite.vert")); setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/qt-project.org/scenegraph/shaders/sprite.frag")); @@ -133,7 +124,7 @@ public: static const char *attr[] = { "vPos", "vTex", - 0 + nullptr }; return attr; } diff --git a/src/quick/scenegraph/qsgdistancefieldglyphnode.cpp b/src/quick/scenegraph/qsgdistancefieldglyphnode.cpp index 32eda2d142..ae6336718e 100644 --- a/src/quick/scenegraph/qsgdistancefieldglyphnode.cpp +++ b/src/quick/scenegraph/qsgdistancefieldglyphnode.cpp @@ -46,12 +46,12 @@ QT_BEGIN_NAMESPACE QSGDistanceFieldGlyphNode::QSGDistanceFieldGlyphNode(QSGRenderContext *context) : m_glyphNodeType(RootGlyphNode) , m_context(context) - , m_material(0) - , m_glyph_cache(0) + , m_material(nullptr) + , m_glyph_cache(nullptr) , m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 0) , m_style(QQuickText::Normal) , m_antialiasingMode(GrayAntialiasing) - , m_texture(0) + , m_texture(nullptr) , m_dirtyGeometry(false) , m_dirtyMaterial(false) { @@ -80,7 +80,7 @@ QSGDistanceFieldGlyphNode::~QSGDistanceFieldGlyphNode() void QSGDistanceFieldGlyphNode::setColor(const QColor &color) { m_color = color; - if (m_material != 0) { + if (m_material != nullptr) { m_material->setColor(color); markDirty(DirtyMaterial); } else { @@ -113,7 +113,7 @@ void QSGDistanceFieldGlyphNode::setGlyphs(const QPointF &position, const QGlyphR return; if (m_glyph_cache != oldCache) { - Q_ASSERT(ownerElement() != 0); + Q_ASSERT(ownerElement() != nullptr); if (oldCache) { oldCache->unregisterGlyphNode(this); oldCache->unregisterOwnerElement(ownerElement()); @@ -181,7 +181,7 @@ void QSGDistanceFieldGlyphNode::updateGeometry() // Remove previously created sub glyph nodes // We assume all the children are sub glyph nodes QSGNode *subnode = firstChild(); - QSGNode *nextNode = 0; + QSGNode *nextNode = nullptr; while (subnode) { nextNode = subnode->nextSibling(); delete subnode; diff --git a/src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp b/src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp index a67c659c99..aa58218505 100644 --- a/src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp +++ b/src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp @@ -61,37 +61,27 @@ protected: void updateColor(const QVector4D &c); void updateTextureScale(const QVector2D &ts); - float m_fontScale; - float m_matrixScale; + float m_fontScale = 1.0; + float m_matrixScale = 1.0; - int m_matrix_id; - int m_textureScale_id; - int m_alphaMin_id; - int m_alphaMax_id; - int m_color_id; + int m_matrix_id = -1; + int m_textureScale_id = -1; + int m_alphaMin_id = -1; + int m_alphaMax_id = -1; + int m_color_id = -1; QVector2D m_lastTextureScale; QVector4D m_lastColor; - float m_lastAlphaMin; - float m_lastAlphaMax; + float m_lastAlphaMin = -1; + float m_lastAlphaMax = -1; }; char const *const *QSGDistanceFieldTextMaterialShader::attributeNames() const { - static char const *const attr[] = { "vCoord", "tCoord", 0 }; + static char const *const attr[] = { "vCoord", "tCoord", nullptr }; return attr; } QSGDistanceFieldTextMaterialShader::QSGDistanceFieldTextMaterialShader() - : QSGMaterialShader(), - m_fontScale(1.0) - , m_matrixScale(1.0) - , m_matrix_id(-1) - , m_textureScale_id(-1) - , m_alphaMin_id(-1) - , m_alphaMax_id(-1) - , m_color_id(-1) - , m_lastAlphaMin(-1) - , m_lastAlphaMax(-1) { setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/qt-project.org/scenegraph/shaders/distancefieldtext.vert")); setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/qt-project.org/scenegraph/shaders/distancefieldtext.frag")); @@ -166,13 +156,13 @@ void QSGDistanceFieldTextMaterialShader::initialize() void QSGDistanceFieldTextMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) { - Q_ASSERT(oldEffect == 0 || newEffect->type() == oldEffect->type()); + Q_ASSERT(oldEffect == nullptr || newEffect->type() == oldEffect->type()); QSGDistanceFieldTextMaterial *material = static_cast<QSGDistanceFieldTextMaterial *>(newEffect); QSGDistanceFieldTextMaterial *oldMaterial = static_cast<QSGDistanceFieldTextMaterial *>(oldEffect); bool updated = material->updateTextureSize(); - if (oldMaterial == 0 + if (oldMaterial == nullptr || material->color() != oldMaterial->color() || state.isOpacityDirty()) { QVector4D color = material->color(); @@ -181,7 +171,7 @@ void QSGDistanceFieldTextMaterialShader::updateState(const RenderState &state, Q } bool updateRange = false; - if (oldMaterial == 0 + if (oldMaterial == nullptr || material->fontScale() != oldMaterial->fontScale()) { m_fontScale = material->fontScale(); updateRange = true; @@ -198,12 +188,12 @@ void QSGDistanceFieldTextMaterialShader::updateState(const RenderState &state, Q Q_ASSERT(material->glyphCache()); if (updated - || oldMaterial == 0 + || oldMaterial == nullptr || oldMaterial->texture()->textureId != material->texture()->textureId) { updateTextureScale(QVector2D(1.0 / material->textureSize().width(), 1.0 / material->textureSize().height())); - QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); + QOpenGLFunctions *funcs = state.context()->functions(); funcs->glBindTexture(GL_TEXTURE_2D, material->texture()->textureId); if (updated) { @@ -218,8 +208,8 @@ void QSGDistanceFieldTextMaterialShader::updateState(const RenderState &state, Q } QSGDistanceFieldTextMaterial::QSGDistanceFieldTextMaterial() - : m_glyph_cache(0) - , m_texture(0) + : m_glyph_cache(nullptr) + , m_texture(nullptr) , m_fontScale(1.0) { setFlag(Blending | RequiresDeterminant, true); @@ -288,12 +278,11 @@ public: protected: void initialize() override; - int m_styleColor_id; + int m_styleColor_id = -1; }; DistanceFieldStyledTextMaterialShader::DistanceFieldStyledTextMaterialShader() : QSGDistanceFieldTextMaterialShader() - , m_styleColor_id(-1) { } @@ -310,7 +299,7 @@ void DistanceFieldStyledTextMaterialShader::updateState(const RenderState &state QSGDistanceFieldStyledTextMaterial *material = static_cast<QSGDistanceFieldStyledTextMaterial *>(newEffect); QSGDistanceFieldStyledTextMaterial *oldMaterial = static_cast<QSGDistanceFieldStyledTextMaterial *>(oldEffect); - if (oldMaterial == 0 + if (oldMaterial == nullptr || material->styleColor() != oldMaterial->styleColor() || (state.isOpacityDirty())) { QVector4D color = material->styleColor(); @@ -358,14 +347,12 @@ protected: void updateOutlineAlphaRange(int dfRadius); - int m_outlineAlphaMax0_id; - int m_outlineAlphaMax1_id; + int m_outlineAlphaMax0_id = -1; + int m_outlineAlphaMax1_id = -1; }; DistanceFieldOutlineTextMaterialShader::DistanceFieldOutlineTextMaterialShader() : DistanceFieldStyledTextMaterialShader() - , m_outlineAlphaMax0_id(-1) - , m_outlineAlphaMax1_id(-1) { setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/qt-project.org/scenegraph/shaders/distancefieldoutlinetext.frag")); } @@ -398,7 +385,7 @@ void DistanceFieldOutlineTextMaterialShader::updateState(const RenderState &stat QSGDistanceFieldOutlineTextMaterial *material = static_cast<QSGDistanceFieldOutlineTextMaterial *>(newEffect); QSGDistanceFieldOutlineTextMaterial *oldMaterial = static_cast<QSGDistanceFieldOutlineTextMaterial *>(oldEffect); - if (oldMaterial == 0 + if (oldMaterial == nullptr || material->fontScale() != oldMaterial->fontScale() || state.isMatrixDirty()) updateOutlineAlphaRange(material->glyphCache()->distanceFieldRadius()); @@ -438,12 +425,11 @@ protected: void updateShift(qreal fontScale, const QPointF& shift); - int m_shift_id; + int m_shift_id = -1; }; DistanceFieldShiftedStyleTextMaterialShader::DistanceFieldShiftedStyleTextMaterialShader() : DistanceFieldStyledTextMaterialShader() - , m_shift_id(-1) { setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/qt-project.org/scenegraph/shaders/distancefieldshiftedtext.vert")); setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/qt-project.org/scenegraph/shaders/distancefieldshiftedtext.frag")); @@ -462,7 +448,7 @@ void DistanceFieldShiftedStyleTextMaterialShader::updateState(const RenderState QSGDistanceFieldShiftedStyleTextMaterial *material = static_cast<QSGDistanceFieldShiftedStyleTextMaterial *>(newEffect); QSGDistanceFieldShiftedStyleTextMaterial *oldMaterial = static_cast<QSGDistanceFieldShiftedStyleTextMaterial *>(oldEffect); - if (oldMaterial == 0 + if (oldMaterial == nullptr || oldMaterial->fontScale() != material->fontScale() || oldMaterial->shift() != material->shift() || oldMaterial->textureSize() != material->textureSize()) { @@ -516,14 +502,12 @@ public: void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) override; private: - int m_fontScale_id; - int m_vecDelta_id; + int m_fontScale_id = -1; + int m_vecDelta_id = -1; }; QSGHiQSubPixelDistanceFieldTextMaterialShader::QSGHiQSubPixelDistanceFieldTextMaterialShader() : QSGDistanceFieldTextMaterialShader() - , m_fontScale_id(-1) - , m_vecDelta_id(-1) { setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/qt-project.org/scenegraph/shaders/hiqsubpixeldistancefieldtext.vert")); setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/qt-project.org/scenegraph/shaders/hiqsubpixeldistancefieldtext.frag")); @@ -550,19 +534,19 @@ void QSGHiQSubPixelDistanceFieldTextMaterialShader::deactivate() void QSGHiQSubPixelDistanceFieldTextMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) { - Q_ASSERT(oldEffect == 0 || newEffect->type() == oldEffect->type()); + Q_ASSERT(oldEffect == nullptr || newEffect->type() == oldEffect->type()); QSGDistanceFieldTextMaterial *material = static_cast<QSGDistanceFieldTextMaterial *>(newEffect); QSGDistanceFieldTextMaterial *oldMaterial = static_cast<QSGDistanceFieldTextMaterial *>(oldEffect); - if (oldMaterial == 0 || material->color() != oldMaterial->color()) { + if (oldMaterial == nullptr || material->color() != oldMaterial->color()) { QVector4D c = material->color(); state.context()->functions()->glBlendColor(c.x(), c.y(), c.z(), 1.0f); } - if (oldMaterial == 0 || material->fontScale() != oldMaterial->fontScale()) + if (oldMaterial == nullptr || material->fontScale() != oldMaterial->fontScale()) program()->setUniformValue(m_fontScale_id, GLfloat(material->fontScale())); - if (oldMaterial == 0 || state.isMatrixDirty()) { + if (oldMaterial == nullptr || state.isMatrixDirty()) { int viewportWidth = state.viewportRect().width(); QMatrix4x4 mat = state.combinedMatrix().inverted(); program()->setUniformValue(m_vecDelta_id, mat.column(0) * (qreal(2) / viewportWidth)); diff --git a/src/quick/scenegraph/qsgrenderloop.cpp b/src/quick/scenegraph/qsgrenderloop.cpp index 58450d7a50..9e5cc27cd8 100644 --- a/src/quick/scenegraph/qsgrenderloop.cpp +++ b/src/quick/scenegraph/qsgrenderloop.cpp @@ -76,7 +76,7 @@ QT_BEGIN_NAMESPACE extern bool qsg_useConsistentTiming(); extern Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha); #if QT_CONFIG(opengl) -/*! +/* expectations for this manager to work: - one opengl context to render multiple windows - OpenGL pipeline will not block for vsync in swap @@ -88,7 +88,7 @@ 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 #endif -QSGRenderLoop *QSGRenderLoop::s_instance = 0; +QSGRenderLoop *QSGRenderLoop::s_instance = nullptr; QSGRenderLoop::~QSGRenderLoop() { @@ -107,11 +107,11 @@ void QSGRenderLoop::cleanup() QQuickWindowPrivate *wd = QQuickWindowPrivate::get(w); if (wd->windowManager == s_instance) { s_instance->windowDestroyed(w); - wd->windowManager = 0; + wd->windowManager = nullptr; } } delete s_instance; - s_instance = 0; + s_instance = nullptr; } /*! @@ -155,7 +155,7 @@ public: void releaseResources(QQuickWindow *) override; - QAnimationDriver *animationDriver() const override { return 0; } + QAnimationDriver *animationDriver() const override { return nullptr; } QSGContext *sceneGraphContext() const override; QSGRenderContext *createRenderContext(QSGContext *) const override { return rc; } @@ -282,7 +282,7 @@ void QSGRenderLoop::handleContextCreationFailure(QQuickWindow *window, } #if QT_CONFIG(opengl) QSGGuiThreadRenderLoop::QSGGuiThreadRenderLoop() - : gl(0) + : gl(nullptr) { if (qsg_useConsistentTiming()) { QUnifiedTimer::instance(true)->setConsistentTiming(true); @@ -334,7 +334,7 @@ void QSGGuiThreadRenderLoop::windowDestroyed(QQuickWindow *window) current = gl->makeCurrent(surface); } if (Q_UNLIKELY(!current)) - qCDebug(QSG_LOG_RENDERLOOP) << "cleanup without an OpenGL context"; + qCDebug(QSG_LOG_RENDERLOOP, "cleanup without an OpenGL context"); #if QT_CONFIG(quick_shadereffect) && QT_CONFIG(opengl) QQuickOpenGLShaderEffectMaterial::cleanupMaterialCache(); @@ -344,7 +344,7 @@ void QSGGuiThreadRenderLoop::windowDestroyed(QQuickWindow *window) if (m_windows.size() == 0) { rc->invalidate(); delete gl; - gl = 0; + gl = nullptr; } else if (gl && window == gl->surface() && current) { gl->doneCurrent(); } @@ -371,7 +371,7 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window) if (!gl->create()) { const bool isEs = gl->isOpenGLES(); delete gl; - gl = 0; + gl = nullptr; handleContextCreationFailure(window, isEs); } else { cd->fireOpenGLContextCreated(gl); diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp index 4a712d3cdd..8262708320 100644 --- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp +++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp @@ -115,7 +115,7 @@ QT_BEGIN_NAMESPACE -#define QSG_RT_PAD " (RT)" +#define QSG_RT_PAD " (RT) %s" static inline int qsgrl_animation_interval() { qreal refreshRate = QGuiApplication::primaryScreen()->refreshRate(); @@ -167,7 +167,7 @@ template <typename T> T *windowFor(const QList<T> &list, QQuickWindow *window) if (t.window == window) return const_cast<T *>(&t); } - return 0; + return nullptr; } @@ -270,13 +270,13 @@ class QSGRenderThread : public QThread public: QSGRenderThread(QSGThreadedRenderLoop *w, QSGRenderContext *renderContext) : wm(w) - , gl(0) - , animatorDriver(0) + , gl(nullptr) + , animatorDriver(nullptr) , pendingUpdate(0) , sleeping(false) , syncResultedInChanges(false) , active(false) - , window(0) + , window(nullptr) , stopEventProcessing(false) { sgrc = static_cast<QSGDefaultRenderContext *>(renderContext); @@ -315,7 +315,7 @@ public: public slots: void sceneGraphChanged() { - qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "sceneGraphChanged"; + qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "sceneGraphChanged"); syncResultedInChanges = true; } @@ -358,15 +358,15 @@ bool QSGRenderThread::event(QEvent *e) switch ((int) e->type()) { case WM_Obscure: { - qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "WM_Obscure"; + qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "WM_Obscure"); Q_ASSERT(!window || window == static_cast<WMWindowEvent *>(e)->window); mutex.lock(); if (window) { QQuickWindowPrivate::get(window)->fireAboutToStop(); - qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- window removed"; - window = 0; + qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- window removed"); + window = nullptr; } waitCondition.wakeOne(); mutex.unlock(); @@ -374,7 +374,7 @@ bool QSGRenderThread::event(QEvent *e) return true; } case WM_RequestSync: { - qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "WM_RequestSync"; + qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "WM_RequestSync"); WMSyncEvent *se = static_cast<WMSyncEvent *>(e); if (sleeping) stopEventProcessing = true; @@ -383,33 +383,33 @@ bool QSGRenderThread::event(QEvent *e) pendingUpdate |= SyncRequest; if (se->syncInExpose) { - qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- triggered from expose"; + qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- triggered from expose"); pendingUpdate |= ExposeRequest; } if (se->forceRenderPass) { - qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- repaint regardless"; + qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- repaint regardless"); pendingUpdate |= RepaintRequest; } return true; } case WM_TryRelease: { - qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "WM_TryRelease"; + qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "WM_TryRelease"); mutex.lock(); wm->m_lockedForSync = true; WMTryReleaseEvent *wme = static_cast<WMTryReleaseEvent *>(e); if (!window || wme->inDestructor) { - qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- setting exit flag and invalidating OpenGL"; + qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- setting exit flag and invalidating OpenGL"); invalidateOpenGL(wme->window, wme->inDestructor, wme->fallbackSurface); active = gl; Q_ASSERT_X(!wme->inDestructor || !active, "QSGRenderThread::invalidateOpenGL()", "Thread's active state is not set to false when shutting down"); if (sleeping) stopEventProcessing = true; } else { - qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- not releasing because window is still active"; + qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- not releasing because window is still active"); if (window) { QQuickWindowPrivate *d = QQuickWindowPrivate::get(window); if (d->renderer) { - qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- requesting renderer to release cached resources"; + qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- requesting renderer to release cached resources"); d->renderer->releaseCachedResources(); } } @@ -421,7 +421,7 @@ bool QSGRenderThread::event(QEvent *e) } case WM_Grab: { - qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "WM_Grab"; + qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "WM_Grab"); WMGrabEvent *ce = static_cast<WMGrabEvent *>(e); Q_ASSERT(ce->window); Q_ASSERT(ce->window == window || !window); @@ -429,41 +429,41 @@ bool QSGRenderThread::event(QEvent *e) if (ce->window) { gl->makeCurrent(ce->window); - qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- sync scene graph"; + qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- sync scene graph"); QQuickWindowPrivate *d = QQuickWindowPrivate::get(ce->window); d->syncSceneGraph(); sgrc->endSync(); - qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- rendering scene graph"; + qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- rendering scene graph"); QQuickWindowPrivate::get(ce->window)->renderSceneGraph(ce->window->size()); - qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- grabbing result"; + qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- grabbing result"); bool alpha = ce->window->format().alphaBufferSize() > 0 && ce->window->color().alpha() != 255; *ce->image = qt_gl_read_framebuffer(windowSize * ce->window->effectiveDevicePixelRatio(), alpha, alpha); ce->image->setDevicePixelRatio(ce->window->effectiveDevicePixelRatio()); } - qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- waking gui to handle result"; + qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- waking gui to handle result"); waitCondition.wakeOne(); mutex.unlock(); return true; } case WM_PostJob: { - qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "WM_PostJob"; + qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "WM_PostJob"); WMJobEvent *ce = static_cast<WMJobEvent *>(e); Q_ASSERT(ce->window == window); if (window) { gl->makeCurrent(window); ce->job->run(); delete ce->job; - ce->job = 0; - qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- job done"; + ce->job = nullptr; + qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- job done"); } return true; } case WM_RequestRepaint: - qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "WM_RequestPaint"; + qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "WM_RequestPaint"); // When GUI posts this event, it is followed by a polishAndSync, so we mustn't // exit the event loop yet. pendingUpdate |= RepaintRequest; @@ -477,13 +477,13 @@ bool QSGRenderThread::event(QEvent *e) void QSGRenderThread::invalidateOpenGL(QQuickWindow *window, bool inDestructor, QOffscreenSurface *fallback) { - qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "invalidateOpenGL()"; + qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "invalidateOpenGL()"); if (!gl) return; if (!window) { - qCWarning(QSG_LOG_RENDERLOOP()) << "QSGThreadedRenderLoop:QSGRenderThread: no window to make current..."; + qCWarning(QSG_LOG_RENDERLOOP, "QSGThreadedRenderLoop:QSGRenderThread: no window to make current..."); return; } @@ -493,7 +493,7 @@ void QSGRenderThread::invalidateOpenGL(QQuickWindow *window, bool inDestructor, bool current = gl->makeCurrent(fallback ? static_cast<QSurface *>(fallback) : static_cast<QSurface *>(window)); if (Q_UNLIKELY(!current)) { - qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- cleanup without an OpenGL context"; + qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- cleanup without an OpenGL context"); } QQuickWindowPrivate *dd = QQuickWindowPrivate::get(window); @@ -506,7 +506,7 @@ void QSGRenderThread::invalidateOpenGL(QQuickWindow *window, bool inDestructor, if (wipeSG) { dd->cleanupNodesOnShutdown(); } else { - qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- persistent SG, avoiding cleanup"; + qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- persistent SG, avoiding cleanup"); if (current) gl->doneCurrent(); return; @@ -514,29 +514,29 @@ void QSGRenderThread::invalidateOpenGL(QQuickWindow *window, bool inDestructor, sgrc->invalidate(); QCoreApplication::processEvents(); - QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); + QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete); if (inDestructor) delete dd->animationController; if (current) gl->doneCurrent(); - qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- invalidating scene graph"; + qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- invalidating scene graph"); if (wipeGL) { delete gl; - gl = 0; - qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- invalidated OpenGL"; + gl = nullptr; + qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- invalidated OpenGL"); } else { - qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- persistent GL, avoiding cleanup"; + qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- persistent GL, avoiding cleanup"); } } -/*! +/* Enters the mutex lock to make sure GUI is blocking and performs sync, then wakes GUI. */ void QSGRenderThread::sync(bool inExpose) { - qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "sync()"; + qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "sync()"); mutex.lock(); Q_ASSERT_X(wm->m_lockedForSync, "QSGRenderThread::sync()", "sync triggered on bad terms as gui is not already locked..."); @@ -554,7 +554,7 @@ void QSGRenderThread::sync(bool inExpose) } if (current) { QQuickWindowPrivate *d = QQuickWindowPrivate::get(window); - bool hadRenderer = d->renderer != 0; + bool hadRenderer = d->renderer != nullptr; // If the scene graph was touched since the last sync() make sure it sends the // changed signal. if (d->renderer) @@ -562,7 +562,7 @@ void QSGRenderThread::sync(bool inExpose) d->syncSceneGraph(); sgrc->endSync(); if (!hadRenderer && d->renderer) { - qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- renderer was created"; + qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- renderer was created"); syncResultedInChanges = true; connect(d->renderer, SIGNAL(sceneGraphChanged()), this, SLOT(sceneGraphChanged()), Qt::DirectConnection); } @@ -570,13 +570,13 @@ void QSGRenderThread::sync(bool inExpose) // Process deferred deletes now, directly after the sync as // deleteLater on the GUI must now also have resulted in SG changes // and the delete is a safe operation. - QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); + QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete); } else { - qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- window has bad size, sync aborted"; + qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- window has bad size, sync aborted"); } if (!inExpose) { - qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- sync complete, waking Gui"; + qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- sync complete, waking Gui"); waitCondition.wakeOne(); mutex.unlock(); } @@ -594,7 +594,7 @@ void QSGRenderThread::syncAndRender() QElapsedTimer waitTimer; waitTimer.start(); - qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "syncAndRender()"; + qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "syncAndRender()"); syncResultedInChanges = false; QQuickWindowPrivate *d = QQuickWindowPrivate::get(window); @@ -605,7 +605,7 @@ void QSGRenderThread::syncAndRender() pendingUpdate = 0; if (syncRequested) { - qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- updatePending, doing sync"; + qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- updatePending, doing sync"); sync(exposeRequested); } #ifndef QSG_NO_RENDER_TIMING @@ -616,14 +616,14 @@ void QSGRenderThread::syncAndRender() QQuickProfiler::SceneGraphRenderLoopSync); if (!syncResultedInChanges && !repaintRequested && sgrc->isValid()) { - qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- no changes, render aborted"; + qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- no changes, render aborted"); int waitTime = vsyncDelta - (int) waitTimer.elapsed(); if (waitTime > 0) msleep(waitTime); return; } - qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- rendering started"; + qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- rendering started"); if (animatorDriver->isRunning()) { @@ -653,10 +653,10 @@ void QSGRenderThread::syncAndRender() } else { Q_QUICK_SG_PROFILE_SKIP(QQuickProfiler::SceneGraphRenderLoopFrame, QQuickProfiler::SceneGraphRenderLoopSync, 1); - qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- window not ready, skipping render"; + qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- window not ready, skipping render"); } - qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- rendering done"; + qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- rendering done"); // Though it would be more correct to put this block directly after // fireFrameSwapped in the if (current) branch above, we don't do @@ -664,7 +664,7 @@ void QSGRenderThread::syncAndRender() // has started rendering with a bad window, causing makeCurrent to // fail or if the window has a bad size. if (exposeRequested) { - qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- wake Gui after initial expose"; + qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- wake Gui after initial expose"); waitCondition.wakeOne(); mutex.unlock(); } @@ -692,31 +692,31 @@ void QSGRenderThread::postEvent(QEvent *e) void QSGRenderThread::processEvents() { - qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "--- begin processEvents()"; + qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "--- begin processEvents()"); while (eventQueue.hasMoreEvents()) { QEvent *e = eventQueue.takeEvent(false); event(e); delete e; } - qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "--- done processEvents()"; + qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "--- done processEvents()"); } void QSGRenderThread::processEventsAndWaitForMore() { - qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "--- begin processEventsAndWaitForMore()"; + qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "--- begin processEventsAndWaitForMore()"); stopEventProcessing = false; while (!stopEventProcessing) { QEvent *e = eventQueue.takeEvent(true); event(e); delete e; } - qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "--- done processEventsAndWaitForMore()"; + qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "--- done processEventsAndWaitForMore()"); } void QSGRenderThread::run() { - qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "run()"; - animatorDriver = sgrc->sceneGraphContext()->createAnimationDriver(0); + qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "run()"); + animatorDriver = sgrc->sceneGraphContext()->createAnimationDriver(nullptr); animatorDriver->install(); if (QQmlDebugConnector::service<QQmlProfilerService>()) QQuickProfiler::registerAnimationCallback(); @@ -733,7 +733,7 @@ void QSGRenderThread::run() QCoreApplication::processEvents(); if (active && (pendingUpdate == 0 || !window)) { - qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "done drawing, sleep..."; + qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "done drawing, sleep..."); sleeping = true; processEventsAndWaitForMore(); sleeping = false; @@ -742,10 +742,10 @@ void QSGRenderThread::run() Q_ASSERT_X(!gl, "QSGRenderThread::run()", "The OpenGL context should be cleaned up before exiting the render thread..."); - qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "run() completed"; + qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "run() completed"); delete animatorDriver; - animatorDriver = 0; + animatorDriver = nullptr; sgrc->moveToThread(wm->thread()); moveToThread(wm->thread()); @@ -809,7 +809,7 @@ bool QSGThreadedRenderLoop::interleaveIncubation() const void QSGThreadedRenderLoop::animationStarted() { - qCDebug(QSG_LOG_RENDERLOOP) << "- animationStarted()"; + qCDebug(QSG_LOG_RENDERLOOP, "- animationStarted()"); startOrStopAnimationTimer(); for (int i=0; i<m_windows.size(); ++i) @@ -818,7 +818,7 @@ void QSGThreadedRenderLoop::animationStarted() void QSGThreadedRenderLoop::animationStopped() { - qCDebug(QSG_LOG_RENDERLOOP) << "- animationStopped()"; + qCDebug(QSG_LOG_RENDERLOOP, "- animationStopped()"); startOrStopAnimationTimer(); } @@ -826,7 +826,7 @@ void QSGThreadedRenderLoop::animationStopped() void QSGThreadedRenderLoop::startOrStopAnimationTimer() { int exposedWindows = 0; - const Window *theOne = 0; + const Window *theOne = nullptr; for (int i=0; i<m_windows.size(); ++i) { const Window &w = m_windows.at(i); if (w.window->isVisible() && w.window->isExposed()) { @@ -836,14 +836,14 @@ void QSGThreadedRenderLoop::startOrStopAnimationTimer() } if (m_animation_timer != 0 && (exposedWindows == 1 || !m_animation_driver->isRunning())) { - qCDebug(QSG_LOG_RENDERLOOP) << "*** Stopping animation timer"; + qCDebug(QSG_LOG_RENDERLOOP, "*** Stopping animation timer"); killTimer(m_animation_timer); m_animation_timer = 0; // If animations are running, make sure we keep on animating if (m_animation_driver->isRunning()) maybePostPolishRequest(const_cast<Window *>(theOne)); } else if (m_animation_timer == 0 && exposedWindows != 1 && m_animation_driver->isRunning()) { - qCDebug(QSG_LOG_RENDERLOOP) << "*** Starting animation timer"; + qCDebug(QSG_LOG_RENDERLOOP, "*** Starting animation timer"); m_animation_timer = startTimer(qsgrl_animation_interval()); } } @@ -870,7 +870,7 @@ void QSGThreadedRenderLoop::hide(QQuickWindow *window) } -/*! +/* If the window is first hide it, then perform a complete cleanup with releaseResources which will take down the GL context and exit the rendering thread. @@ -920,7 +920,7 @@ void QSGThreadedRenderLoop::exposureChanged(QQuickWindow *window) } } -/*! +/* Will post an event to the render thread that this window should start to render. */ @@ -930,7 +930,7 @@ void QSGThreadedRenderLoop::handleExposure(QQuickWindow *window) Window *w = windowFor(m_windows, window); if (!w) { - qCDebug(QSG_LOG_RENDERLOOP) << "- adding window to list"; + qCDebug(QSG_LOG_RENDERLOOP, "- adding window to list"); Window win; win.window = window; win.actualWindowFormat = window->format(); @@ -962,7 +962,7 @@ void QSGThreadedRenderLoop::handleExposure(QQuickWindow *window) // Start render thread if it is not running if (!w->thread->isRunning()) { - qCDebug(QSG_LOG_RENDERLOOP) << "- starting render thread"; + qCDebug(QSG_LOG_RENDERLOOP, "- starting render thread"); if (!w->thread->gl) { w->thread->gl = new QOpenGLContext(); @@ -973,7 +973,7 @@ void QSGThreadedRenderLoop::handleExposure(QQuickWindow *window) if (!w->thread->gl->create()) { const bool isEs = w->thread->gl->isOpenGLES(); delete w->thread->gl; - w->thread->gl = 0; + w->thread->gl = nullptr; handleContextCreationFailure(w->window, isEs); return; } @@ -981,7 +981,7 @@ void QSGThreadedRenderLoop::handleExposure(QQuickWindow *window) QQuickWindowPrivate::get(w->window)->fireOpenGLContextCreated(w->thread->gl); w->thread->gl->moveToThread(w->thread); - qCDebug(QSG_LOG_RENDERLOOP) << "- OpenGL context created"; + qCDebug(QSG_LOG_RENDERLOOP, "- OpenGL context created"); } QQuickAnimatorController *controller = QQuickWindowPrivate::get(w->window)->animationController; @@ -998,16 +998,16 @@ void QSGThreadedRenderLoop::handleExposure(QQuickWindow *window) qFatal("Render thread failed to start, aborting application."); } else { - qCDebug(QSG_LOG_RENDERLOOP) << "- render thread already running"; + qCDebug(QSG_LOG_RENDERLOOP, "- render thread already running"); } polishAndSync(w, true); - qCDebug(QSG_LOG_RENDERLOOP) << "- done with handleExposure()"; + qCDebug(QSG_LOG_RENDERLOOP, "- done with handleExposure()"); startOrStopAnimationTimer(); } -/*! +/* This function posts an event to the render thread to remove the window from the list of windowses to render. @@ -1029,7 +1029,7 @@ void QSGThreadedRenderLoop::handleObscurity(Window *w) void QSGThreadedRenderLoop::handleUpdateRequest(QQuickWindow *window) { - qCDebug(QSG_LOG_RENDERLOOP) << "- polish and sync update request"; + qCDebug(QSG_LOG_RENDERLOOP, "- polish and sync update request"); Window *w = windowFor(m_windows, window); if (w) polishAndSync(w); @@ -1042,7 +1042,7 @@ void QSGThreadedRenderLoop::maybeUpdate(QQuickWindow *window) maybeUpdate(w); } -/*! +/* Called whenever the QML scene has changed. Will post an event to ourselves that a sync is needed. */ @@ -1065,7 +1065,7 @@ void QSGThreadedRenderLoop::maybeUpdate(Window *w) // Call this function from the Gui thread later as startTimer cannot be // called from the render thread. if (current == w->thread) { - qCDebug(QSG_LOG_RENDERLOOP) << "- on render thread"; + qCDebug(QSG_LOG_RENDERLOOP, "- on render thread"); w->updateDuringSync = true; return; } @@ -1073,7 +1073,7 @@ void QSGThreadedRenderLoop::maybeUpdate(Window *w) maybePostPolishRequest(w); } -/*! +/* Called when the QQuickWindow should be explicitly repainted. This function can also be called on the render thread when the GUI thread is blocked to keep render thread animations alive. @@ -1105,7 +1105,7 @@ void QSGThreadedRenderLoop::releaseResources(QQuickWindow *window) releaseResources(w, false); } -/*! +/* * Release resources will post an event to the render thread to * free up the SG and GL resources and exists the render thread. */ @@ -1123,15 +1123,15 @@ void QSGThreadedRenderLoop::releaseResources(Window *w, bool inDestructor) // and the OpenGL resources. // QOffscreenSurface must be created on the GUI thread, so we // create it here and pass it on to QSGRenderThread::invalidateGL() - QOffscreenSurface *fallback = 0; + QOffscreenSurface *fallback = nullptr; if (!window->handle()) { - qCDebug(QSG_LOG_RENDERLOOP) << "- using fallback surface"; + qCDebug(QSG_LOG_RENDERLOOP, "- using fallback surface"); fallback = new QOffscreenSurface(); fallback->setFormat(w->actualWindowFormat); fallback->create(); } - qCDebug(QSG_LOG_RENDERLOOP) << "- posting release request to render thread"; + qCDebug(QSG_LOG_RENDERLOOP, "- posting release request to render thread"); w->thread->postEvent(new WMTryReleaseEvent(window, inDestructor, fallback)); w->thread->waitCondition.wait(&w->thread->mutex); delete fallback; @@ -1161,7 +1161,7 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose) QQuickWindow *window = w->window; if (!w->thread || !w->thread->window) { - qCDebug(QSG_LOG_RENDERLOOP) << "- not exposed, abort"; + qCDebug(QSG_LOG_RENDERLOOP, "- not exposed, abort"); return; } @@ -1170,7 +1170,7 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose) // The delivery of the event might have caused the window to stop rendering w = windowFor(m_windows, window); if (!w || !w->thread || !w->thread->window) { - qCDebug(QSG_LOG_RENDERLOOP) << "- removed after event flushing, abort"; + qCDebug(QSG_LOG_RENDERLOOP, "- removed after event flushing, abort"); return; } @@ -1196,13 +1196,13 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose) emit window->afterAnimating(); - qCDebug(QSG_LOG_RENDERLOOP) << "- lock for sync"; + qCDebug(QSG_LOG_RENDERLOOP, "- lock for sync"); w->thread->mutex.lock(); m_lockedForSync = true; w->thread->postEvent(new WMSyncEvent(window, inExpose, w->forceRenderPass)); w->forceRenderPass = false; - qCDebug(QSG_LOG_RENDERLOOP) << "- wait for sync"; + qCDebug(QSG_LOG_RENDERLOOP, "- wait for sync"); if (profileFrames) waitTime = timer.nsecsElapsed(); Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphPolishAndSync, @@ -1210,7 +1210,7 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose) w->thread->waitCondition.wait(&w->thread->mutex); m_lockedForSync = false; w->thread->mutex.unlock(); - qCDebug(QSG_LOG_RENDERLOOP) << "- unlock after sync"; + qCDebug(QSG_LOG_RENDERLOOP, "- unlock after sync"); if (profileFrames) syncTime = timer.nsecsElapsed(); @@ -1218,9 +1218,9 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose) QQuickProfiler::SceneGraphPolishAndSyncSync); if (m_animation_timer == 0 && m_animation_driver->isRunning()) { - qCDebug(QSG_LOG_RENDERLOOP) << "- advancing animations"; + qCDebug(QSG_LOG_RENDERLOOP, "- advancing animations"); m_animation_driver->advance(); - qCDebug(QSG_LOG_RENDERLOOP) << "- animations done.."; + qCDebug(QSG_LOG_RENDERLOOP, "- animations done.."); // We need to trigger another sync to keep animations running... maybePostPolishRequest(w); emit timeToIncubate(); @@ -1247,7 +1247,7 @@ bool QSGThreadedRenderLoop::event(QEvent *e) case QEvent::Timer: { QTimerEvent *te = static_cast<QTimerEvent *>(e); if (te->timerId() == m_animation_timer) { - qCDebug(QSG_LOG_RENDERLOOP) << "- ticking non-visual timer"; + qCDebug(QSG_LOG_RENDERLOOP, "- ticking non-visual timer"); m_animation_driver->advance(); emit timeToIncubate(); return true; @@ -1286,25 +1286,25 @@ QImage QSGThreadedRenderLoop::grab(QQuickWindow *window) if (!window->handle()) window->create(); - qCDebug(QSG_LOG_RENDERLOOP) << "- polishing items"; + qCDebug(QSG_LOG_RENDERLOOP, "- polishing items"); QQuickWindowPrivate *d = QQuickWindowPrivate::get(window); d->polishItems(); QImage result; w->thread->mutex.lock(); m_lockedForSync = true; - qCDebug(QSG_LOG_RENDERLOOP) << "- posting grab event"; + qCDebug(QSG_LOG_RENDERLOOP, "- posting grab event"); w->thread->postEvent(new WMGrabEvent(window, &result)); w->thread->waitCondition.wait(&w->thread->mutex); m_lockedForSync = false; w->thread->mutex.unlock(); - qCDebug(QSG_LOG_RENDERLOOP) << "- grab complete"; + qCDebug(QSG_LOG_RENDERLOOP, "- grab complete"); return result; } -/*! +/* * Posts a new job event to the render thread. * Returns true if posting succeeded. */ diff --git a/src/quick/scenegraph/qsgwindowsrenderloop.cpp b/src/quick/scenegraph/qsgwindowsrenderloop.cpp index e33f31f2ac..3b2737b8e1 100644 --- a/src/quick/scenegraph/qsgwindowsrenderloop.cpp +++ b/src/quick/scenegraph/qsgwindowsrenderloop.cpp @@ -64,7 +64,7 @@ QT_BEGIN_NAMESPACE extern Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha); -#define RLDEBUG(x) qCDebug(QSG_LOG_RENDERLOOP) << x; +#define RLDEBUG(x) qCDebug(QSG_LOG_RENDERLOOP, x) static QElapsedTimer qsg_render_timer; #define QSG_LOG_TIME_SAMPLE(sampleName) \ @@ -78,7 +78,7 @@ static QElapsedTimer qsg_render_timer; QSGWindowsRenderLoop::QSGWindowsRenderLoop() - : m_gl(0) + : m_gl(nullptr) , m_sg(QSGContext::createDefaultContext()) , m_updateTimer(0) , m_animationTimer(0) @@ -117,7 +117,7 @@ QSGWindowsRenderLoop::WindowData *QSGWindowsRenderLoop::windowData(QQuickWindow if (wd.window == window) return &wd; } - return 0; + return nullptr; } void QSGWindowsRenderLoop::maybePostUpdateTimer() @@ -158,7 +158,7 @@ void QSGWindowsRenderLoop::stopped() void QSGWindowsRenderLoop::show(QQuickWindow *window) { RLDEBUG("show"); - if (windowData(window) != 0) + if (windowData(window) != nullptr) return; // This happens before the platform window is shown, but after @@ -178,7 +178,7 @@ void QSGWindowsRenderLoop::show(QQuickWindow *window) if (!created) { const bool isEs = m_gl->isOpenGLES(); delete m_gl; - m_gl = 0; + m_gl = nullptr; handleContextCreationFailure(window, isEs); return; } @@ -243,7 +243,7 @@ void QSGWindowsRenderLoop::windowDestroyed(QQuickWindow *window) current = m_gl->makeCurrent(surface); } if (Q_UNLIKELY(!current)) - qCDebug(QSG_LOG_RENDERLOOP) << "cleanup without an OpenGL context"; + RLDEBUG("cleanup without an OpenGL context"); #if QT_CONFIG(quick_shadereffect) && QT_CONFIG(opengl) QQuickOpenGLShaderEffectMaterial::cleanupMaterialCache(); @@ -253,7 +253,7 @@ void QSGWindowsRenderLoop::windowDestroyed(QQuickWindow *window) if (m_windows.size() == 0) { d->context->invalidate(); delete m_gl; - m_gl = 0; + m_gl = nullptr; } else if (m_gl && current) { m_gl->doneCurrent(); } @@ -272,7 +272,7 @@ bool QSGWindowsRenderLoop::anyoneShowing() const void QSGWindowsRenderLoop::exposureChanged(QQuickWindow *window) { - if (windowData(window) == 0) + if (windowData(window) == nullptr) return; if (window->isExposed() && window->isVisible()) { diff --git a/src/quick/scenegraph/scenegraph.pri b/src/quick/scenegraph/scenegraph.pri index b5c72f521c..4fa3e7b6bf 100644 --- a/src/quick/scenegraph/scenegraph.pri +++ b/src/quick/scenegraph/scenegraph.pri @@ -1,4 +1,4 @@ -DEFINES += QSG_SEPARATE_INDEX_BUFFER +# DEFINES += QSG_SEPARATE_INDEX_BUFFER # DEFINES += QSG_DISTANCEFIELD_CACHE_DEBUG # Core API @@ -230,8 +230,15 @@ SOURCES += \ qtConfig(opengl(es1|es2)?) { HEADERS += \ - $$PWD/compressedtexture/qsgpkmhandler_p.h + $$PWD/compressedtexture/qsgcompressedatlastexture_p.h \ + $$PWD/compressedtexture/qsgcompressedtexture_p.h \ + $$PWD/compressedtexture/qsgtexturefilehandler_p.h \ + $$PWD/compressedtexture/qsgpkmhandler_p.h \ + $$PWD/compressedtexture/qsgktxhandler_p.h SOURCES += \ - $$PWD/compressedtexture/qsgpkmhandler.cpp + $$PWD/compressedtexture/qsgcompressedatlastexture.cpp \ + $$PWD/compressedtexture/qsgcompressedtexture.cpp \ + $$PWD/compressedtexture/qsgpkmhandler.cpp \ + $$PWD/compressedtexture/qsgktxhandler.cpp } diff --git a/src/quick/scenegraph/util/qsgareaallocator.cpp b/src/quick/scenegraph/util/qsgareaallocator.cpp index 67a9fa285a..cd270a1d63 100644 --- a/src/quick/scenegraph/util/qsgareaallocator.cpp +++ b/src/quick/scenegraph/util/qsgareaallocator.cpp @@ -72,8 +72,8 @@ struct QSGAreaAllocatorNode QSGAreaAllocatorNode::QSGAreaAllocatorNode(QSGAreaAllocatorNode *parent) : parent(parent) - , left(0) - , right(0) + , left(nullptr) + , right(nullptr) , isOccupied(false) { } @@ -86,14 +86,14 @@ QSGAreaAllocatorNode::~QSGAreaAllocatorNode() bool QSGAreaAllocatorNode::isLeaf() { - Q_ASSERT((left != 0) == (right != 0)); + Q_ASSERT((left != nullptr) == (right != nullptr)); return !left; } QSGAreaAllocator::QSGAreaAllocator(const QSize &size) : m_size(size) { - m_root = new QSGAreaAllocatorNode(0); + m_root = new QSGAreaAllocatorNode(nullptr); } QSGAreaAllocator::~QSGAreaAllocator() @@ -179,13 +179,13 @@ bool QSGAreaAllocator::deallocateInNode(const QPoint &pos, QSGAreaAllocatorNode void QSGAreaAllocator::mergeNodeWithNeighbors(QSGAreaAllocatorNode *node) { bool done = false; - QSGAreaAllocatorNode *parent = 0; - QSGAreaAllocatorNode *current = 0; + QSGAreaAllocatorNode *parent = nullptr; + QSGAreaAllocatorNode *current = nullptr; QSGAreaAllocatorNode *sibling; while (!done) { Q_ASSERT(node->isLeaf()); Q_ASSERT(!node->isOccupied); - if (node->parent == 0) + if (node->parent == nullptr) return; // No neighbours. SplitType splitType = SplitType(node->parent->splitType); @@ -238,7 +238,7 @@ void QSGAreaAllocator::mergeNodeWithNeighbors(QSGAreaAllocatorNode *node) } sibling->parent = parent->parent; *nodeRef = sibling; - parent->left = parent->right = 0; + parent->left = parent->right = nullptr; delete parent; delete neighbor; done = false; @@ -276,7 +276,7 @@ void QSGAreaAllocator::mergeNodeWithNeighbors(QSGAreaAllocatorNode *node) } sibling->parent = parent->parent; *nodeRef = sibling; - parent->left = parent->right = 0; + parent->left = parent->right = nullptr; delete parent; delete neighbor; done = false; diff --git a/src/quick/scenegraph/util/qsgareaallocator_p.h b/src/quick/scenegraph/util/qsgareaallocator_p.h index aa40ff0a6e..8bc05a5a5b 100644 --- a/src/quick/scenegraph/util/qsgareaallocator_p.h +++ b/src/quick/scenegraph/util/qsgareaallocator_p.h @@ -67,7 +67,7 @@ public: QRect allocate(const QSize &size); bool deallocate(const QRect &rect); - bool isEmpty() const { return m_root == 0; } + bool isEmpty() const { return m_root == nullptr; } QSize size() const { return m_size; } private: bool allocateInNode(const QSize &size, QPoint &result, const QRect ¤tRect, QSGAreaAllocatorNode *node); diff --git a/src/quick/scenegraph/util/qsgatlastexture.cpp b/src/quick/scenegraph/util/qsgatlastexture.cpp index 22f0b13f46..7608a81ddc 100644 --- a/src/quick/scenegraph/util/qsgatlastexture.cpp +++ b/src/quick/scenegraph/util/qsgatlastexture.cpp @@ -44,6 +44,7 @@ #include <QtCore/QtMath> #include <QtGui/QOpenGLContext> +#include <QtGui/QOpenGLTexture> #include <QtGui/QOpenGLFunctions> #include <QtGui/QGuiApplication> #include <QtGui/QScreen> @@ -51,7 +52,10 @@ #include <QtGui/QWindow> #include <QtGui/qpa/qplatformnativeinterface.h> +#include <private/qqmlglobal_p.h> #include <private/qsgtexture_p.h> +#include <private/qsgcompressedtexture_p.h> +#include <private/qsgcompressedatlastexture_p.h> #include <private/qquickprofiler_p.h> @@ -65,11 +69,13 @@ int qt_sg_envInt(const char *name, int defaultValue); static QElapsedTimer qsg_renderer_timer; +DEFINE_BOOL_CONFIG_OPTION(qsgEnableCompressedAtlas, QSG_ENABLE_COMPRESSED_ATLAS) + namespace QSGAtlasTexture { Manager::Manager() - : m_atlas(0) + : m_atlas(nullptr) { QOpenGLContext *gl = QOpenGLContext::currentContext(); Q_ASSERT(gl); @@ -99,7 +105,8 @@ Manager::Manager() Manager::~Manager() { - Q_ASSERT(m_atlas == 0); + Q_ASSERT(m_atlas == nullptr); + Q_ASSERT(m_atlases.isEmpty()); } void Manager::invalidate() @@ -107,13 +114,21 @@ void Manager::invalidate() if (m_atlas) { m_atlas->invalidate(); m_atlas->deleteLater(); - m_atlas = 0; + m_atlas = nullptr; + } + + QHash<unsigned int, QSGCompressedAtlasTexture::Atlas*>::iterator i = m_atlases.begin(); + while (i != m_atlases.end()) { + i.value()->invalidate(); + i.value()->deleteLater(); + ++i; } + m_atlases.clear(); } QSGTexture *Manager::create(const QImage &image, bool hasAlphaChannel) { - Texture *t = 0; + Texture *t = nullptr; if (image.width() < m_atlas_size_limit && image.height() < m_atlas_size_limit) { if (!m_atlas) m_atlas = new Atlas(m_atlas_size); @@ -125,13 +140,147 @@ QSGTexture *Manager::create(const QImage &image, bool hasAlphaChannel) return t; } -Atlas::Atlas(const QSize &size) +QSGTexture *Manager::create(const QSGCompressedTextureFactory *factory) +{ + QSGTexture *t = nullptr; + if (!qsgEnableCompressedAtlas() || !factory->m_textureData || !factory->m_textureData->isValid()) + return t; + + // TODO: further abstract the atlas and remove this restriction + unsigned int format = factory->m_textureData->format; + switch (format) { + case QOpenGLTexture::RGB8_ETC1: + case QOpenGLTexture::RGB8_ETC2: + case QOpenGLTexture::RGBA8_ETC2_EAC: + case QOpenGLTexture::RGB8_PunchThrough_Alpha1_ETC2: + break; + default: + return t; + } + + QSize size = factory->m_textureData->size; + if (size.width() < m_atlas_size_limit && size.height() < m_atlas_size_limit) { + QHash<unsigned int, QSGCompressedAtlasTexture::Atlas*>::iterator i = m_atlases.find(format); + if (i == m_atlases.end()) + i = m_atlases.insert(format, new QSGCompressedAtlasTexture::Atlas(m_atlas_size, format)); + // must be multiple of 4 + QSize paddedSize(((size.width() + 3) / 4) * 4, ((size.height() + 3) / 4) * 4); + QByteArray data = factory->m_textureData->data; + t = i.value()->create(data, factory->m_textureData->sizeInBytes(), factory->m_textureData->dataOffset, size, paddedSize); + } + return t; +} + +AtlasBase::AtlasBase(const QSize &size) : m_allocator(size) , m_texture_id(0) , m_size(size) - , m_atlas_transient_image_threshold(0) , m_allocated(false) { +} + +AtlasBase::~AtlasBase() +{ + Q_ASSERT(!m_texture_id); +} + +void AtlasBase::invalidate() +{ + if (m_texture_id && QOpenGLContext::currentContext()) + QOpenGLContext::currentContext()->functions()->glDeleteTextures(1, &m_texture_id); + m_texture_id = 0; +} + +int AtlasBase::textureId() const +{ + if (!m_texture_id) { + Q_ASSERT(QOpenGLContext::currentContext()); + QOpenGLContext::currentContext()->functions()->glGenTextures(1, &const_cast<AtlasBase *>(this)->m_texture_id); + } + + return m_texture_id; +} + +void AtlasBase::bind(QSGTexture::Filtering filtering) +{ + QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); + if (!m_allocated) { + m_allocated = true; + + while (funcs->glGetError() != GL_NO_ERROR) ; + + funcs->glGenTextures(1, &m_texture_id); + funcs->glBindTexture(GL_TEXTURE_2D, m_texture_id); + funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); +#if !defined(QT_OPENGL_ES_2) + if (!QOpenGLContext::currentContext()->isOpenGLES()) + funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); +#endif + generateTexture(); + + GLenum errorCode = funcs->glGetError(); + if (errorCode == GL_OUT_OF_MEMORY) { + qDebug("QSGTextureAtlas: texture atlas allocation failed, out of memory"); + funcs->glDeleteTextures(1, &m_texture_id); + m_texture_id = 0; + } else if (errorCode != GL_NO_ERROR) { + qDebug("QSGTextureAtlas: texture atlas allocation failed, code=%x", errorCode); + funcs->glDeleteTextures(1, &m_texture_id); + m_texture_id = 0; + } + } else { + funcs->glBindTexture(GL_TEXTURE_2D, m_texture_id); + } + + if (m_texture_id == 0) + return; + + // Upload all pending images.. + for (int i=0; i<m_pending_uploads.size(); ++i) { + + bool profileFrames = QSG_LOG_TIME_TEXTURE().isDebugEnabled(); + if (profileFrames) + qsg_renderer_timer.start(); + + Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphTexturePrepare); + + // Skip bind, convert, swizzle; they're irrelevant + Q_QUICK_SG_PROFILE_SKIP(QQuickProfiler::SceneGraphTexturePrepare, + QQuickProfiler::SceneGraphTexturePrepareStart, 3); + + uploadPendingTexture(i); + + Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphTexturePrepare, + QQuickProfiler::SceneGraphTexturePrepareUpload); + + // Skip mipmap; unused + Q_QUICK_SG_PROFILE_SKIP(QQuickProfiler::SceneGraphTexturePrepare, + QQuickProfiler::SceneGraphTexturePrepareUpload, 1); + Q_QUICK_SG_PROFILE_REPORT(QQuickProfiler::SceneGraphTexturePrepare, + QQuickProfiler::SceneGraphTexturePrepareMipmap); + } + + GLenum f = filtering == QSGTexture::Nearest ? GL_NEAREST : GL_LINEAR; + funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, f); + funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, f); + + m_pending_uploads.clear(); +} + +void AtlasBase::remove(TextureBase *t) +{ + QRect atlasRect = t->atlasSubRect(); + m_allocator.deallocate(atlasRect); + m_pending_uploads.removeOne(t); +} + +Atlas::Atlas(const QSize &size) + : AtlasBase(size) + , m_atlas_transient_image_threshold(0) +{ m_internalFormat = GL_RGBA; m_externalFormat = GL_BGRA; @@ -188,14 +337,6 @@ Atlas::Atlas(const QSize &size) Atlas::~Atlas() { - Q_ASSERT(!m_texture_id); -} - -void Atlas::invalidate() -{ - if (m_texture_id && QOpenGLContext::currentContext()) - QOpenGLContext::currentContext()->functions()->glDeleteTextures(1, &m_texture_id); - m_texture_id = 0; } Texture *Atlas::create(const QImage &image) @@ -207,18 +348,7 @@ Texture *Atlas::create(const QImage &image) m_pending_uploads << t; return t; } - return 0; -} - - -int Atlas::textureId() const -{ - if (!m_texture_id) { - Q_ASSERT(QOpenGLContext::currentContext()); - QOpenGLContext::currentContext()->functions()->glGenTextures(1, &const_cast<Atlas *>(this)->m_texture_id); - } - - return m_texture_id; + return nullptr; } static void swizzleBGRAToRGBA(QImage *image) @@ -334,122 +464,70 @@ void Atlas::uploadBgra(Texture *texture) } } -void Atlas::bind(QSGTexture::Filtering filtering) +void Atlas::generateTexture() { QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); - if (!m_allocated) { - m_allocated = true; - - while (funcs->glGetError() != GL_NO_ERROR) ; - - funcs->glGenTextures(1, &m_texture_id); - funcs->glBindTexture(GL_TEXTURE_2D, m_texture_id); - funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); -#if !defined(QT_OPENGL_ES_2) - if (!QOpenGLContext::currentContext()->isOpenGLES()) - funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); -#endif - funcs->glTexImage2D(GL_TEXTURE_2D, 0, m_internalFormat, m_size.width(), m_size.height(), 0, m_externalFormat, GL_UNSIGNED_BYTE, 0); + funcs->glTexImage2D(GL_TEXTURE_2D, 0, m_internalFormat, m_size.width(), m_size.height(), 0, m_externalFormat, GL_UNSIGNED_BYTE, nullptr); #if 0 - QImage pink(m_size.width(), m_size.height(), QImage::Format_ARGB32_Premultiplied); - pink.fill(0); - QPainter p(&pink); - QLinearGradient redGrad(0, 0, m_size.width(), 0); - redGrad.setColorAt(0, Qt::black); - redGrad.setColorAt(1, Qt::red); - p.fillRect(0, 0, m_size.width(), m_size.height(), redGrad); - p.setCompositionMode(QPainter::CompositionMode_Plus); - QLinearGradient blueGrad(0, 0, 0, m_size.height()); - blueGrad.setColorAt(0, Qt::black); - blueGrad.setColorAt(1, Qt::blue); - p.fillRect(0, 0, m_size.width(), m_size.height(), blueGrad); - p.end(); - - funcs->glTexImage2D(GL_TEXTURE_2D, 0, m_internalFormat, m_size.width(), m_size.height(), 0, m_externalFormat, GL_UNSIGNED_BYTE, pink.constBits()); + QImage pink(m_size.width(), m_size.height(), QImage::Format_ARGB32_Premultiplied); + pink.fill(0); + QPainter p(&pink); + QLinearGradient redGrad(0, 0, m_size.width(), 0); + redGrad.setColorAt(0, Qt::black); + redGrad.setColorAt(1, Qt::red); + p.fillRect(0, 0, m_size.width(), m_size.height(), redGrad); + p.setCompositionMode(QPainter::CompositionMode_Plus); + QLinearGradient blueGrad(0, 0, 0, m_size.height()); + blueGrad.setColorAt(0, Qt::black); + blueGrad.setColorAt(1, Qt::blue); + p.fillRect(0, 0, m_size.width(), m_size.height(), blueGrad); + p.end(); + + funcs->glTexImage2D(GL_TEXTURE_2D, 0, m_internalFormat, m_size.width(), m_size.height(), 0, m_externalFormat, GL_UNSIGNED_BYTE, pink.constBits()); #endif +} - GLenum errorCode = funcs->glGetError(); - if (errorCode == GL_OUT_OF_MEMORY) { - qDebug("QSGTextureAtlas: texture atlas allocation failed, out of memory"); - funcs->glDeleteTextures(1, &m_texture_id); - m_texture_id = 0; - } else if (errorCode != GL_NO_ERROR) { - qDebug("QSGTextureAtlas: texture atlas allocation failed, code=%x", errorCode); - funcs->glDeleteTextures(1, &m_texture_id); - m_texture_id = 0; - } +void Atlas::uploadPendingTexture(int i) +{ + Texture *t = static_cast<Texture*>(m_pending_uploads.at(i)); + if (m_externalFormat == GL_BGRA && + !m_use_bgra_fallback) { + uploadBgra(t); } else { - funcs->glBindTexture(GL_TEXTURE_2D, m_texture_id); + upload(t); } - - if (m_texture_id == 0) - return; - - // Upload all pending images.. - for (int i=0; i<m_pending_uploads.size(); ++i) { - - bool profileFrames = QSG_LOG_TIME_TEXTURE().isDebugEnabled(); - if (profileFrames) - qsg_renderer_timer.start(); - - Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphTexturePrepare); - - // Skip bind, convert, swizzle; they're irrelevant - Q_QUICK_SG_PROFILE_SKIP(QQuickProfiler::SceneGraphTexturePrepare, - QQuickProfiler::SceneGraphTexturePrepareStart, 3); - - Texture *t = m_pending_uploads.at(i); - if (m_externalFormat == GL_BGRA && - !m_use_bgra_fallback) { - uploadBgra(t); - } else { - upload(t); - } - const QSize textureSize = t->textureSize(); - if (textureSize.width() > m_atlas_transient_image_threshold || - textureSize.height() > m_atlas_transient_image_threshold) - t->releaseImage(); - - qCDebug(QSG_LOG_TIME_TEXTURE).nospace() << "atlastexture uploaded in: " << qsg_renderer_timer.elapsed() - << "ms (" << t->textureSize().width() << "x" - << t->textureSize().height() << ")"; - - Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphTexturePrepare, - QQuickProfiler::SceneGraphTexturePrepareUpload); - - // Skip mipmap; unused - Q_QUICK_SG_PROFILE_SKIP(QQuickProfiler::SceneGraphTexturePrepare, - QQuickProfiler::SceneGraphTexturePrepareUpload, 1); - Q_QUICK_SG_PROFILE_REPORT(QQuickProfiler::SceneGraphTexturePrepare, - QQuickProfiler::SceneGraphTexturePrepareMipmap); - } - - GLenum f = filtering == QSGTexture::Nearest ? GL_NEAREST : GL_LINEAR; - funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, f); - funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, f); - - m_pending_uploads.clear(); + const QSize textureSize = t->textureSize(); + if (textureSize.width() > m_atlas_transient_image_threshold || + textureSize.height() > m_atlas_transient_image_threshold) + t->releaseImage(); + + qCDebug(QSG_LOG_TIME_TEXTURE, "atlastexture uploaded in: %lldms (%dx%d)", + qsg_renderer_timer.elapsed(), + t->textureSize().width(), + t->textureSize().height()); } -void Atlas::remove(Texture *t) +TextureBase::TextureBase(AtlasBase *atlas, const QRect &textureRect) + : m_allocated_rect(textureRect) + , m_atlas(atlas) { - QRect atlasRect = t->atlasSubRect(); - m_allocator.deallocate(atlasRect); - m_pending_uploads.removeOne(t); } +TextureBase::~TextureBase() +{ + m_atlas->remove(this); +} +void TextureBase::bind() +{ + m_atlas->bind(filtering()); +} Texture::Texture(Atlas *atlas, const QRect &textureRect, const QImage &image) - : QSGTexture() - , m_allocated_rect(textureRect) + : TextureBase(atlas, textureRect) , m_image(image) - , m_atlas(atlas) - , m_nonatlas_texture(0) + , m_nonatlas_texture(nullptr) , m_has_alpha(image.hasAlphaChannel()) { float w = atlas->size().width(); @@ -463,16 +541,10 @@ Texture::Texture(Atlas *atlas, const QRect &textureRect, const QImage &image) Texture::~Texture() { - m_atlas->remove(this); if (m_nonatlas_texture) delete m_nonatlas_texture; } -void Texture::bind() -{ - m_atlas->bind(filtering()); -} - QSGTexture *Texture::removedFromAtlas() const { if (m_nonatlas_texture) { @@ -508,7 +580,7 @@ QSGTexture *Texture::removedFromAtlas() const QRect r = atlasSubRectWithoutPadding(); // and copy atlas into our texture. while (f->glGetError() != GL_NO_ERROR) ; - f->glCopyTexImage2D(GL_TEXTURE_2D, 0, m_atlas->internalFormat(), r.x(), r.y(), r.width(), r.height(), 0); + f->glCopyTexImage2D(GL_TEXTURE_2D, 0, static_cast<Atlas*>(m_atlas)->internalFormat(), r.x(), r.y(), r.width(), r.height(), 0); // BGRA may have been rejected by some GLES implementations if (f->glGetError() != GL_NO_ERROR) f->glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, r.x(), r.y(), r.width(), r.height(), 0); diff --git a/src/quick/scenegraph/util/qsgatlastexture_p.h b/src/quick/scenegraph/util/qsgatlastexture_p.h index 3dee539547..14dc8f7958 100644 --- a/src/quick/scenegraph/util/qsgatlastexture_p.h +++ b/src/quick/scenegraph/util/qsgatlastexture_p.h @@ -61,10 +61,16 @@ QT_BEGIN_NAMESPACE +namespace QSGCompressedAtlasTexture { + class Atlas; +} +class QSGCompressedTextureFactory; + namespace QSGAtlasTexture { class Texture; +class TextureBase; class Atlas; class Manager : public QObject @@ -76,93 +82,121 @@ public: ~Manager(); QSGTexture *create(const QImage &image, bool hasAlphaChannel); + QSGTexture *create(const QSGCompressedTextureFactory *factory); void invalidate(); private: Atlas *m_atlas; + // set of atlases for different compressed formats + QHash<unsigned int, QSGCompressedAtlasTexture::Atlas*> m_atlases; QSize m_atlas_size; int m_atlas_size_limit; }; -class Atlas : public QObject +class AtlasBase : public QObject { + Q_OBJECT public: - Atlas(const QSize &size); - ~Atlas(); + AtlasBase(const QSize &size); + ~AtlasBase(); void invalidate(); int textureId() const; void bind(QSGTexture::Filtering filtering); + void remove(TextureBase *t); + + QSize size() const { return m_size; } + +protected: + virtual void generateTexture() = 0; + virtual void uploadPendingTexture(int i) = 0; + +protected: + QSGAreaAllocator m_allocator; + unsigned int m_texture_id; + QSize m_size; + QList<TextureBase *> m_pending_uploads; + +private: + bool m_allocated; +}; + +class Atlas : public AtlasBase +{ +public: + Atlas(const QSize &size); + ~Atlas(); + + void generateTexture() override; + void uploadPendingTexture(int i) override; + void upload(Texture *texture); void uploadBgra(Texture *texture); Texture *create(const QImage &image); - void remove(Texture *t); - - QSize size() const { return m_size; } uint internalFormat() const { return m_internalFormat; } uint externalFormat() const { return m_externalFormat; } private: - QSGAreaAllocator m_allocator; - unsigned int m_texture_id; - QSize m_size; - QList<Texture *> m_pending_uploads; - uint m_internalFormat; uint m_externalFormat; int m_atlas_transient_image_threshold; - uint m_allocated : 1; uint m_use_bgra_fallback: 1; - uint m_debug_overlay : 1; }; -class Texture : public QSGTexture +class TextureBase : public QSGTexture +{ + Q_OBJECT +public: + TextureBase(AtlasBase *atlas, const QRect &textureRect); + ~TextureBase(); + + int textureId() const override { return m_atlas->textureId(); } + bool isAtlasTexture() const override { return true; } + + QRect atlasSubRect() const { return m_allocated_rect; } + + void bind() override; + +protected: + QRect m_allocated_rect; + AtlasBase *m_atlas; +}; + +class Texture : public TextureBase { Q_OBJECT public: Texture(Atlas *atlas, const QRect &textureRect, const QImage &image); ~Texture(); - int textureId() const override { return m_atlas->textureId(); } QSize textureSize() const override { return atlasSubRectWithoutPadding().size(); } void setHasAlphaChannel(bool alpha) { m_has_alpha = alpha; } bool hasAlphaChannel() const override { return m_has_alpha; } bool hasMipmaps() const override { return false; } - bool isAtlasTexture() const override { return true; } QRectF normalizedTextureSubRect() const override { return m_texture_coords_rect; } QRect atlasSubRect() const { return m_allocated_rect; } QRect atlasSubRectWithoutPadding() const { return m_allocated_rect.adjusted(1, 1, -1, -1); } - bool isTexture() const { return true; } - QSGTexture *removedFromAtlas() const override; void releaseImage() { m_image = QImage(); } const QImage &image() const { return m_image; } - void bind() override; - private: - QRect m_allocated_rect; QRectF m_texture_coords_rect; - QImage m_image; - - Atlas *m_atlas; - mutable QSGPlainTexture *m_nonatlas_texture; - - uint m_has_alpha : 1; + bool m_has_alpha; }; } diff --git a/src/quick/scenegraph/util/qsgdefaultpainternode.cpp b/src/quick/scenegraph/util/qsgdefaultpainternode.cpp index 9ffd1b4b08..981ea089be 100644 --- a/src/quick/scenegraph/util/qsgdefaultpainternode.cpp +++ b/src/quick/scenegraph/util/qsgdefaultpainternode.cpp @@ -78,11 +78,11 @@ QSGDefaultPainterNode::QSGDefaultPainterNode(QQuickPaintedItem *item) , m_preferredRenderTarget(QQuickPaintedItem::Image) , m_actualRenderTarget(QQuickPaintedItem::Image) , m_item(item) - , m_fbo(0) - , m_multisampledFbo(0) + , m_fbo(nullptr) + , m_multisampledFbo(nullptr) , m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4) - , m_texture(0) - , m_gl_device(0) + , m_texture(nullptr) + , m_gl_device(nullptr) , m_fillColor(Qt::transparent) , m_contentsScale(1.0) , m_dirtyContents(false) @@ -260,8 +260,8 @@ void QSGDefaultPainterNode::updateRenderTarget() delete m_fbo; delete m_multisampledFbo; delete m_gl_device; - m_fbo = m_multisampledFbo = 0; - m_gl_device = 0; + m_fbo = m_multisampledFbo = nullptr; + m_gl_device = nullptr; } if (m_actualRenderTarget == QQuickPaintedItem::FramebufferObject || @@ -275,7 +275,7 @@ void QSGDefaultPainterNode::updateRenderTarget() delete m_fbo; delete m_multisampledFbo; - m_fbo = m_multisampledFbo = 0; + m_fbo = m_multisampledFbo = nullptr; if (m_gl_device) m_gl_device->setSize(m_fboSize); diff --git a/src/quick/scenegraph/util/qsgdepthstencilbuffer.cpp b/src/quick/scenegraph/util/qsgdepthstencilbuffer.cpp index ba0207aca8..56508af152 100644 --- a/src/quick/scenegraph/util/qsgdepthstencilbuffer.cpp +++ b/src/quick/scenegraph/util/qsgdepthstencilbuffer.cpp @@ -43,7 +43,7 @@ QT_BEGIN_NAMESPACE QSGDepthStencilBuffer::QSGDepthStencilBuffer(QOpenGLContext *context, const Format &format) : m_functions(context) - , m_manager(0) + , m_manager(nullptr) , m_format(format) , m_depthBuffer(0) , m_stencilBuffer(0) @@ -160,7 +160,7 @@ QSGDepthStencilBufferManager::~QSGDepthStencilBufferManager() for (Hash::const_iterator it = m_buffers.constBegin(), cend = m_buffers.constEnd(); it != cend; ++it) { QSGDepthStencilBuffer *buffer = it.value().data(); buffer->free(); - buffer->m_manager = 0; + buffer->m_manager = nullptr; } } @@ -174,7 +174,7 @@ QSharedPointer<QSGDepthStencilBuffer> QSGDepthStencilBufferManager::bufferForFor void QSGDepthStencilBufferManager::insertBuffer(const QSharedPointer<QSGDepthStencilBuffer> &buffer) { - Q_ASSERT(buffer->m_manager == 0); + Q_ASSERT(buffer->m_manager == nullptr); Q_ASSERT(!m_buffers.contains(buffer->m_format)); buffer->m_manager = this; m_buffers.insert(buffer->m_format, buffer.toWeakRef()); diff --git a/src/quick/scenegraph/util/qsgengine.cpp b/src/quick/scenegraph/util/qsgengine.cpp index dffe199224..91fa46033c 100644 --- a/src/quick/scenegraph/util/qsgengine.cpp +++ b/src/quick/scenegraph/util/qsgengine.cpp @@ -157,7 +157,7 @@ QSGAbstractRenderer *QSGEngine::createRenderer() const { Q_D(const QSGEngine); if (!d->sgRenderContext->isValid()) - return 0; + return nullptr; QSGRenderer *renderer = d->sgRenderContext->createRenderer(); renderer->setCustomRenderMode(qgetenv("QSG_VISUALIZE")); @@ -178,7 +178,7 @@ QSGTexture *QSGEngine::createTextureFromImage(const QImage &image, CreateTexture { Q_D(const QSGEngine); if (!d->sgRenderContext->isValid()) - return 0; + return nullptr; uint flags = 0; if (options & TextureCanUseAtlas) flags |= QSGRenderContext::CreateTexture_Atlas; if (!(options & TextureIsOpaque)) flags |= QSGRenderContext::CreateTexture_Alpha; @@ -206,7 +206,7 @@ QSGTexture *QSGEngine::createTextureFromId(uint id, const QSize &size, CreateTex texture->setTextureSize(size); return texture; } - return 0; + return nullptr; } /*! diff --git a/src/quick/scenegraph/util/qsgengine.h b/src/quick/scenegraph/util/qsgengine.h index 514e6e8c2b..e9e01dc710 100644 --- a/src/quick/scenegraph/util/qsgengine.h +++ b/src/quick/scenegraph/util/qsgengine.h @@ -68,7 +68,7 @@ public: Q_DECLARE_FLAGS(CreateTextureOptions, CreateTextureOption) explicit QSGEngine(QObject *parent = nullptr); - ~QSGEngine(); + ~QSGEngine() override; void initialize(QOpenGLContext *context); void invalidate(); diff --git a/src/quick/scenegraph/util/qsgflatcolormaterial.cpp b/src/quick/scenegraph/util/qsgflatcolormaterial.cpp index a0c71b5340..28f6113a60 100644 --- a/src/quick/scenegraph/util/qsgflatcolormaterial.cpp +++ b/src/quick/scenegraph/util/qsgflatcolormaterial.cpp @@ -77,13 +77,13 @@ FlatColorMaterialShader::FlatColorMaterialShader() void FlatColorMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) { #if QT_CONFIG(opengl) - Q_ASSERT(oldEffect == 0 || newEffect->type() == oldEffect->type()); + Q_ASSERT(oldEffect == nullptr || newEffect->type() == oldEffect->type()); QSGFlatColorMaterial *oldMaterial = static_cast<QSGFlatColorMaterial *>(oldEffect); QSGFlatColorMaterial *newMaterial = static_cast<QSGFlatColorMaterial *>(newEffect); const QColor &c = newMaterial->color(); - if (oldMaterial == 0 || c != oldMaterial->color() || state.isOpacityDirty()) { + if (oldMaterial == nullptr || c != oldMaterial->color() || state.isOpacityDirty()) { float opacity = state.opacity() * c.alphaF(); QVector4D v(c.redF() * opacity, c.greenF() * opacity, @@ -103,7 +103,7 @@ void FlatColorMaterialShader::updateState(const RenderState &state, QSGMaterial char const *const *FlatColorMaterialShader::attributeNames() const { - static char const *const attr[] = { "vCoord", 0 }; + static char const *const attr[] = { "vCoord", nullptr }; return attr; } diff --git a/src/quick/scenegraph/util/qsgimagenode.cpp b/src/quick/scenegraph/util/qsgimagenode.cpp index c03c91d1cb..b154023247 100644 --- a/src/quick/scenegraph/util/qsgimagenode.cpp +++ b/src/quick/scenegraph/util/qsgimagenode.cpp @@ -168,7 +168,7 @@ QT_BEGIN_NAMESPACE */ /*! - \fn QSGImageNode::TextureCoordinatesTransformMode textureCoordinatesTransform() const + \fn QSGImageNode::TextureCoordinatesTransformMode QSGImageNode::textureCoordinatesTransform() const Returns the mode used to generate texture coordinates for this node. */ @@ -187,6 +187,15 @@ QT_BEGIN_NAMESPACE \return \c true if the node takes ownership of the texture; otherwise \c false. */ +/*! + Updates the geometry \a g with the \a texture, the coordinates + in \a rect, and the texture coordinates from \a sourceRect. + + \a g is assumed to be a triangle strip of four vertices of type + QSGGeometry::TexturedPoint2D. + + \a texCoordMode is used for normalizing the \a sourceRect. + */ void QSGImageNode::rebuildGeometry(QSGGeometry *g, QSGTexture *texture, const QRectF &rect, diff --git a/src/quick/scenegraph/util/qsgimagenode.h b/src/quick/scenegraph/util/qsgimagenode.h index 0e053c307f..526f52b7e5 100644 --- a/src/quick/scenegraph/util/qsgimagenode.h +++ b/src/quick/scenegraph/util/qsgimagenode.h @@ -48,7 +48,7 @@ QT_BEGIN_NAMESPACE class Q_QUICK_EXPORT QSGImageNode : public QSGGeometryNode { public: - virtual ~QSGImageNode() { } + ~QSGImageNode() override { } virtual void setRect(const QRectF &rect) = 0; inline void setRect(qreal x, qreal y, qreal w, qreal h) { setRect(QRectF(x, y, w, h)); } diff --git a/src/quick/scenegraph/util/qsgninepatchnode.h b/src/quick/scenegraph/util/qsgninepatchnode.h index 8509cbd326..e76afd3c4a 100644 --- a/src/quick/scenegraph/util/qsgninepatchnode.h +++ b/src/quick/scenegraph/util/qsgninepatchnode.h @@ -48,7 +48,7 @@ QT_BEGIN_NAMESPACE class Q_QUICK_EXPORT QSGNinePatchNode : public QSGGeometryNode { public: - virtual ~QSGNinePatchNode() { } + ~QSGNinePatchNode() override { } virtual void setTexture(QSGTexture *texture) = 0; virtual void setBounds(const QRectF &bounds) = 0; diff --git a/src/quick/scenegraph/util/qsgrectanglenode.h b/src/quick/scenegraph/util/qsgrectanglenode.h index 8e0da1d9c7..ba52b65b07 100644 --- a/src/quick/scenegraph/util/qsgrectanglenode.h +++ b/src/quick/scenegraph/util/qsgrectanglenode.h @@ -47,7 +47,7 @@ QT_BEGIN_NAMESPACE class Q_QUICK_EXPORT QSGRectangleNode : public QSGGeometryNode { public: - virtual ~QSGRectangleNode() { } + ~QSGRectangleNode() override { } virtual void setRect(const QRectF &rect) = 0; inline void setRect(qreal x, qreal y, qreal w, qreal h) { setRect(QRectF(x, y, w, h)); } diff --git a/src/quick/scenegraph/util/qsgshadersourcebuilder.cpp b/src/quick/scenegraph/util/qsgshadersourcebuilder.cpp index e134a5d4d3..93fc213f2e 100644 --- a/src/quick/scenegraph/util/qsgshadersourcebuilder.cpp +++ b/src/quick/scenegraph/util/qsgshadersourcebuilder.cpp @@ -262,8 +262,8 @@ void QSGShaderSourceBuilder::addDefinition(const QByteArray &definition) tok.initialize(input); // First find #version, #extension's and "void main() { ... " - const char *versionPos = 0; - const char *extensionPos = 0; + const char *versionPos = nullptr; + const char *extensionPos = nullptr; bool inSingleLineComment = false; bool inMultiLineComment = false; bool foundVersionStart = false; @@ -325,8 +325,8 @@ void QSGShaderSourceBuilder::removeVersion() tok.initialize(input); // First find #version beginning and end (if present) - const char *versionStartPos = 0; - const char *versionEndPos = 0; + const char *versionStartPos = nullptr; + const char *versionEndPos = nullptr; bool inSingleLineComment = false; bool inMultiLineComment = false; bool foundVersionStart = false; @@ -361,7 +361,7 @@ void QSGShaderSourceBuilder::removeVersion() t = tok.next(); } - if (versionStartPos == 0) + if (versionStartPos == nullptr) return; // Construct a new shader string, inserting the definition diff --git a/src/quick/scenegraph/util/qsgsimplematerial.cpp b/src/quick/scenegraph/util/qsgsimplematerial.cpp index f29c58ad9e..376f7dce5c 100644 --- a/src/quick/scenegraph/util/qsgsimplematerial.cpp +++ b/src/quick/scenegraph/util/qsgsimplematerial.cpp @@ -173,17 +173,17 @@ /*! - \fn char const *const *QSGSimpleMaterialShader::attributeNames() const + \fn template <typename State> char const *const *QSGSimpleMaterialShader<State>::attributeNames() const \internal */ /*! - \fn void QSGSimpleMaterialShader::initialize() + \fn template <typename State> void QSGSimpleMaterialShader<State>::initialize() \internal */ /*! - \fn void QSGSimpleMaterialShader::resolveUniforms() + \fn template <typename State> void QSGSimpleMaterialShader<State>::resolveUniforms() Reimplement this function to resolve the location of named uniforms in the shader program. @@ -192,34 +192,34 @@ */ /*! - \fn const char *QSGSimpleMaterialShader::uniformMatrixName() const + \fn template <typename State> const char *QSGSimpleMaterialShader<State>::uniformMatrixName() const Returns the name for the transform matrix uniform of this item. The default value is \c qt_Matrix. */ /*! - \fn const char *QSGSimpleMaterialShader::uniformOpacityName() const + \fn template <typename State> const char *QSGSimpleMaterialShader<State>::uniformOpacityName() const Returns the name for the opacity uniform of this item. The default value is \c qt_Opacity. */ /*! - \fn void QSGSimpleMaterialShader::updateState(const RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) + \fn template <typename State> void QSGSimpleMaterialShader<State>::updateState(const RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) \internal */ /*! - \fn QList<QByteArray> QSGSimpleMaterialShader::attributes() const + \fn template <typename State> QList<QByteArray> QSGSimpleMaterialShader<State>::attributes() const Returns a list of names, declaring the vertex attributes in the vertex shader. */ /*! - \fn void QSGSimpleMaterialShader::updateState(const State *newState, const State *oldState) + \fn template <typename State> void QSGSimpleMaterialShader<State>::updateState(const State *newState, const State *oldState) Called whenever the state of this shader should be updated from \a oldState to \a newState, typical for each new set of diff --git a/src/quick/scenegraph/util/qsgsimplematerial.h b/src/quick/scenegraph/util/qsgsimplematerial.h index b5b8815b4a..79180ca8e2 100644 --- a/src/quick/scenegraph/util/qsgsimplematerial.h +++ b/src/quick/scenegraph/util/qsgsimplematerial.h @@ -138,7 +138,7 @@ template <typename State> class QSGSimpleMaterial : public QSGMaterial { public: -#ifndef qdoc +#ifndef Q_CLANG_QDOC QSGSimpleMaterial(const State &aState, PtrShaderCreateFunc func) : m_state(aState) , m_func(func) @@ -185,7 +185,7 @@ public: QSGSimpleMaterialComparableMaterial(PtrShaderCreateFunc func) : QSGSimpleMaterial<State>(func) {} - int compare(const QSGMaterial *other) const { + int compare(const QSGMaterial *other) const override { return QSGSimpleMaterialComparableMaterial<State>::state()->compare(static_cast<const QSGSimpleMaterialComparableMaterial<State> *>(other)->state()); } }; @@ -207,7 +207,7 @@ Q_INLINE_TEMPLATE void QSGSimpleMaterialShader<State>::updateState(const RenderS Q_UNUSED(state) #endif State *ns = static_cast<QSGSimpleMaterial<State> *>(newMaterial)->state(); - State *old = 0; + State *old = nullptr; if (oldMaterial) old = static_cast<QSGSimpleMaterial<State> *>(oldMaterial)->state(); updateState(ns, old); diff --git a/src/quick/scenegraph/util/qsgsimpletexturenode.cpp b/src/quick/scenegraph/util/qsgsimpletexturenode.cpp index 6ce37de7cb..0c49ca9aa5 100644 --- a/src/quick/scenegraph/util/qsgsimpletexturenode.cpp +++ b/src/quick/scenegraph/util/qsgsimpletexturenode.cpp @@ -47,8 +47,7 @@ class QSGSimpleTextureNodePrivate : public QSGGeometryNodePrivate { public: QSGSimpleTextureNodePrivate() - : QSGGeometryNodePrivate() - , texCoordMode(QSGSimpleTextureNode::NoTransform) + : texCoordMode(QSGSimpleTextureNode::NoTransform) , isAtlasTexture(false) , ownsTexture(false) {} diff --git a/src/quick/scenegraph/util/qsgsimpletexturenode.h b/src/quick/scenegraph/util/qsgsimpletexturenode.h index 09e4277c66..010463d3c6 100644 --- a/src/quick/scenegraph/util/qsgsimpletexturenode.h +++ b/src/quick/scenegraph/util/qsgsimpletexturenode.h @@ -52,7 +52,7 @@ class Q_QUICK_EXPORT QSGSimpleTextureNode : public QSGGeometryNode { public: QSGSimpleTextureNode(); - ~QSGSimpleTextureNode(); + ~QSGSimpleTextureNode() override; void setRect(const QRectF &rect); inline void setRect(qreal x, qreal y, qreal w, qreal h) { setRect(QRectF(x, y, w, h)); } diff --git a/src/quick/scenegraph/util/qsgtexture.cpp b/src/quick/scenegraph/util/qsgtexture.cpp index 4f11d95e70..fea92a5121 100644 --- a/src/quick/scenegraph/util/qsgtexture.cpp +++ b/src/quick/scenegraph/util/qsgtexture.cpp @@ -53,7 +53,7 @@ #endif #include <private/qsgmaterialshader_p.h> -#if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID) && !defined(__UCLIBC__) +#if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID) && defined(__GLIBC__) #define CAN_BACKTRACE_EXECINFO #endif @@ -399,7 +399,7 @@ QSGTexture::~QSGTexture() QSGTexture *QSGTexture::removedFromAtlas() const { Q_ASSERT_X(!isAtlasTexture(), "QSGTexture::removedFromAtlas()", "Called on a non-atlas texture"); - return 0; + return nullptr; } /*! diff --git a/src/quick/scenegraph/util/qsgtexture.h b/src/quick/scenegraph/util/qsgtexture.h index 032129434e..7bd57a16e3 100644 --- a/src/quick/scenegraph/util/qsgtexture.h +++ b/src/quick/scenegraph/util/qsgtexture.h @@ -54,7 +54,7 @@ class Q_QUICK_EXPORT QSGTexture : public QObject public: QSGTexture(); - ~QSGTexture(); + ~QSGTexture() override; enum WrapMode { Repeat, diff --git a/src/quick/scenegraph/util/qsgtexture_p.h b/src/quick/scenegraph/util/qsgtexture_p.h index 52dc6db2d0..18dd5eff68 100644 --- a/src/quick/scenegraph/util/qsgtexture_p.h +++ b/src/quick/scenegraph/util/qsgtexture_p.h @@ -83,7 +83,7 @@ class Q_QUICK_PRIVATE_EXPORT QSGPlainTexture : public QSGTexture Q_OBJECT public: QSGPlainTexture(); - virtual ~QSGPlainTexture(); + ~QSGPlainTexture() override; void setOwnsTexture(bool owns) { m_owns_texture = owns; } bool ownsTexture() const { return m_owns_texture; } diff --git a/src/quick/scenegraph/util/qsgtexturematerial.cpp b/src/quick/scenegraph/util/qsgtexturematerial.cpp index fbc8f27a63..7b1d5abb26 100644 --- a/src/quick/scenegraph/util/qsgtexturematerial.cpp +++ b/src/quick/scenegraph/util/qsgtexturematerial.cpp @@ -57,7 +57,6 @@ inline static bool isPowerOfTwo(int x) QSGMaterialType QSGOpaqueTextureMaterialShader::type; QSGOpaqueTextureMaterialShader::QSGOpaqueTextureMaterialShader() - : QSGMaterialShader() { #if QT_CONFIG(opengl) setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/qt-project.org/scenegraph/shaders/opaquetexture.vert")); @@ -67,7 +66,7 @@ QSGOpaqueTextureMaterialShader::QSGOpaqueTextureMaterialShader() char const *const *QSGOpaqueTextureMaterialShader::attributeNames() const { - static char const *const attr[] = { "qt_VertexPosition", "qt_VertexTexCoord", 0 }; + static char const *const attr[] = { "qt_VertexPosition", "qt_VertexTexCoord", nullptr }; return attr; } @@ -80,7 +79,7 @@ void QSGOpaqueTextureMaterialShader::initialize() void QSGOpaqueTextureMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) { - Q_ASSERT(oldEffect == 0 || newEffect->type() == oldEffect->type()); + Q_ASSERT(oldEffect == nullptr || newEffect->type() == oldEffect->type()); QSGOpaqueTextureMaterial *tx = static_cast<QSGOpaqueTextureMaterial *>(newEffect); QSGOpaqueTextureMaterial *oldTx = static_cast<QSGOpaqueTextureMaterial *>(oldEffect); @@ -112,7 +111,7 @@ void QSGOpaqueTextureMaterialShader::updateState(const RenderState &state, QSGMa t->setMipmapFiltering(tx->mipmapFiltering()); t->setAnisotropyLevel(tx->anisotropyLevel()); - if (oldTx == 0 || oldTx->texture()->textureId() != t->textureId()) + if (oldTx == nullptr || oldTx->texture()->textureId() != t->textureId()) t->bind(); else t->updateBindOptions(); @@ -169,7 +168,7 @@ void QSGOpaqueTextureMaterialShader::updateState(const RenderState &state, QSGMa */ QSGOpaqueTextureMaterial::QSGOpaqueTextureMaterial() - : m_texture(0) + : m_texture(nullptr) , m_filtering(QSGTexture::Nearest) , m_mipmap_filtering(QSGTexture::None) , m_horizontal_wrap(QSGTexture::ClampToEdge) @@ -304,7 +303,17 @@ void QSGOpaqueTextureMaterial::setTexture(QSGTexture *texture) The default vertical wrap mode is \c QSGTexture::ClampToEdge. */ +/*! + \fn void QSGOpaqueTextureMaterial::setAnisotropyLevel(QSGTexture::AnisotropyLevel level) + + Sets this material's anistropy level to \a level. +*/ + +/*! + \fn QSGTexture::AnisotropyLevel QSGOpaqueTextureMaterial::anisotropyLevel() const + Returns this material's anistropy level. +*/ /*! \internal @@ -388,7 +397,7 @@ QSGTextureMaterialShader::QSGTextureMaterialShader() void QSGTextureMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) { - Q_ASSERT(oldEffect == 0 || newEffect->type() == oldEffect->type()); + Q_ASSERT(oldEffect == nullptr || newEffect->type() == oldEffect->type()); #if QT_CONFIG(opengl) if (state.isOpacityDirty()) program()->setUniformValue(m_opacity_id, state.opacity()); diff --git a/src/quick/scenegraph/util/qsgtexturereader.cpp b/src/quick/scenegraph/util/qsgtexturereader.cpp index 61729ada18..8af2c8e7cd 100644 --- a/src/quick/scenegraph/util/qsgtexturereader.cpp +++ b/src/quick/scenegraph/util/qsgtexturereader.cpp @@ -43,40 +43,71 @@ #if QT_CONFIG(opengl) #include <private/qsgpkmhandler_p.h> +#include <private/qsgktxhandler_p.h> #endif +#include <QFileInfo> + QT_BEGIN_NAMESPACE -QSGTextureReader::QSGTextureReader() +QSGTextureReader::QSGTextureReader(QIODevice *device, const QString &fileName) + : m_device(device), m_fileInfo(fileName) { +} +QSGTextureReader::~QSGTextureReader() +{ + delete m_handler; } -QQuickTextureFactory *QSGTextureReader::read(QIODevice *device, const QByteArray &format) +QQuickTextureFactory *QSGTextureReader::read() { #if QT_CONFIG(opengl) - if (format == QByteArrayLiteral("pkm")) { - QSGPkmHandler handler; - return handler.read(device); - } + if (!isTexture()) + return nullptr; + return m_handler->read(); #else - Q_UNUSED(device) - Q_UNUSED(format) -#endif return nullptr; +#endif } -bool QSGTextureReader::isTexture(QIODevice *device, const QByteArray &format) +bool QSGTextureReader::isTexture() { #if QT_CONFIG(opengl) - if (format == QByteArrayLiteral("pkm")) { - return device->peek(4) == QByteArrayLiteral("PKM "); + if (!checked) { + checked = true; + if (!init()) + return false; + + QByteArray headerBlock = m_device->peek(64); + QByteArray suffix = m_fileInfo.suffix().toLower().toLatin1(); + QByteArray logName = m_fileInfo.fileName().toUtf8(); + + // Currently the handlers are hardcoded; later maybe a list of plugins + if (QSGPkmHandler::canRead(suffix, headerBlock)) { + m_handler = new QSGPkmHandler(m_device, logName); + } else if (QSGKtxHandler::canRead(suffix, headerBlock)) { + m_handler = new QSGKtxHandler(m_device, logName); + } + // else if OtherHandler::canRead() ...etc. } + return (m_handler != nullptr); #else - Q_UNUSED(device) - Q_UNUSED(format) -#endif return false; +#endif +} + +QList<QByteArray> QSGTextureReader::supportedFileFormats() +{ + // Hardcoded for now + return {QByteArrayLiteral("pkm"), QByteArrayLiteral("ktx")}; +} + +bool QSGTextureReader::init() +{ + if (!m_device) + return false; + return m_device->isReadable(); } QT_END_NAMESPACE diff --git a/src/quick/scenegraph/util/qsgtexturereader_p.h b/src/quick/scenegraph/util/qsgtexturereader_p.h index 7d2fc314a6..19e33bf5c3 100644 --- a/src/quick/scenegraph/util/qsgtexturereader_p.h +++ b/src/quick/scenegraph/util/qsgtexturereader_p.h @@ -52,19 +52,34 @@ // #include <QString> +#include <QFileInfo> QT_BEGIN_NAMESPACE class QIODevice; class QQuickTextureFactory; +class QSGTextureFileHandler; class QSGTextureReader { public: - QSGTextureReader(); + QSGTextureReader(QIODevice *device, const QString &fileName = QString()); + ~QSGTextureReader(); - static QQuickTextureFactory *read(QIODevice *device, const QByteArray &format); - static bool isTexture(QIODevice *device, const QByteArray &format); + QQuickTextureFactory *read(); + bool isTexture(); + + // TBD access function to params + // TBD ask for identified fmt + + static QList<QByteArray> supportedFileFormats(); + +private: + bool init(); + QIODevice *m_device = nullptr; + QFileInfo m_fileInfo; + QSGTextureFileHandler *m_handler = nullptr; + bool checked = false; }; QT_END_NAMESPACE diff --git a/src/quick/scenegraph/util/qsgvertexcolormaterial.cpp b/src/quick/scenegraph/util/qsgvertexcolormaterial.cpp index 42c589b14a..cb61430e2e 100644 --- a/src/quick/scenegraph/util/qsgvertexcolormaterial.cpp +++ b/src/quick/scenegraph/util/qsgvertexcolormaterial.cpp @@ -64,7 +64,6 @@ private: QSGMaterialType QSGVertexColorMaterialShader::type; QSGVertexColorMaterialShader::QSGVertexColorMaterialShader() - : QSGMaterialShader() { #if QT_CONFIG(opengl) setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/qt-project.org/scenegraph/shaders/vertexcolor.vert")); @@ -87,7 +86,7 @@ void QSGVertexColorMaterialShader::updateState(const RenderState &state, QSGMate char const *const *QSGVertexColorMaterialShader::attributeNames() const { - static const char *const attr[] = { "vertexCoord", "vertexColor", 0 }; + static const char *const attr[] = { "vertexCoord", "vertexColor", nullptr }; return attr; } diff --git a/src/quick/util/qquickanimation.cpp b/src/quick/util/qquickanimation.cpp index bfac46adb9..a89f237499 100644 --- a/src/quick/util/qquickanimation.cpp +++ b/src/quick/util/qquickanimation.cpp @@ -91,7 +91,7 @@ QQuickAbstractAnimation::~QQuickAbstractAnimation() { Q_D(QQuickAbstractAnimation); if (d->group) - setGroup(0); //remove from group + setGroup(nullptr); //remove from group delete d->animationInstance; } @@ -643,7 +643,7 @@ QAbstractAnimationJob* QQuickAbstractAnimation::transition(QQuickStateActions &a Q_UNUSED(modified); Q_UNUSED(direction); Q_UNUSED(defaultTarget); - return 0; + return nullptr; } void QQuickAbstractAnimationPrivate::animationFinished(QAbstractAnimationJob*) @@ -838,7 +838,7 @@ void QQuickColorAnimation::setTo(const QColor &t) } QActionAnimation::QActionAnimation() - : QAbstractAnimationJob(), animAction(0) + : QAbstractAnimationJob(), animAction(nullptr) { } @@ -1666,13 +1666,13 @@ void QQuickRotationAnimation::setDirection(QQuickRotationAnimation::RotationDire d->direction = direction; switch(d->direction) { case Clockwise: - d->interpolator = reinterpret_cast<QVariantAnimation::Interpolator>(&_q_interpolateClockwiseRotation); + d->interpolator = reinterpret_cast<QVariantAnimation::Interpolator>(reinterpret_cast<void *>(&_q_interpolateClockwiseRotation)); break; case Counterclockwise: - d->interpolator = reinterpret_cast<QVariantAnimation::Interpolator>(&_q_interpolateCounterclockwiseRotation); + d->interpolator = reinterpret_cast<QVariantAnimation::Interpolator>(reinterpret_cast<void *>(&_q_interpolateCounterclockwiseRotation)); break; case Shortest: - d->interpolator = reinterpret_cast<QVariantAnimation::Interpolator>(&_q_interpolateShortestRotation); + d->interpolator = reinterpret_cast<QVariantAnimation::Interpolator>(reinterpret_cast<void *>(&_q_interpolateShortestRotation)); break; default: d->interpolator = QVariantAnimationPrivate::getInterpolator(d->interpolatorType); @@ -1706,7 +1706,7 @@ void QQuickAnimationGroupPrivate::clear_animation(QQmlListProperty<QQuickAbstrac if (q) { while (q->d_func()->animations.count()) { QQuickAbstractAnimation *firstAnim = q->d_func()->animations.at(0); - firstAnim->setGroup(0); + firstAnim->setGroup(nullptr); } } } @@ -1715,7 +1715,7 @@ QQuickAnimationGroup::~QQuickAnimationGroup() { Q_D(QQuickAnimationGroup); for (int i = 0; i < d->animations.count(); ++i) - d->animations.at(i)->d_func()->group = 0; + d->animations.at(i)->d_func()->group = nullptr; d->animations.clear(); } @@ -1937,7 +1937,7 @@ void QQuickPropertyAnimationPrivate::convertVariant(QVariant &variant, int type) } QQuickBulkValueAnimator::QQuickBulkValueAnimator() - : QAbstractAnimationJob(), animValue(0), fromSourced(0), m_duration(250) + : QAbstractAnimationJob(), animValue(nullptr), fromSourced(nullptr), m_duration(250) { } @@ -2112,7 +2112,7 @@ void QQuickPropertyAnimation::setFrom(const QVariant &f) return; d->from = f; d->fromIsDefined = f.isValid(); - emit fromChanged(f); + emit fromChanged(); } /*! @@ -2139,7 +2139,7 @@ void QQuickPropertyAnimation::setTo(const QVariant &t) return; d->to = t; d->toIsDefined = t.isValid(); - emit toChanged(t); + emit toChanged(); } /*! @@ -2556,7 +2556,7 @@ void QQuickAnimationPropertyUpdater::setValue(qreal v) if (deleted) return; } - wasDeleted = 0; + wasDeleted = nullptr; fromSourced = true; } diff --git a/src/quick/util/qquickanimation_p.h b/src/quick/util/qquickanimation_p.h index e27871dcaa..2293f2597f 100644 --- a/src/quick/util/qquickanimation_p.h +++ b/src/quick/util/qquickanimation_p.h @@ -87,8 +87,8 @@ public: AnyThread }; - QQuickAbstractAnimation(QObject *parent=0); - virtual ~QQuickAbstractAnimation(); + QQuickAbstractAnimation(QObject *parent=nullptr); + ~QQuickAbstractAnimation() override; enum Loops { Infinite = -2 }; Q_ENUM(Loops) @@ -144,7 +144,7 @@ public: virtual QAbstractAnimationJob* transition(QQuickStateActions &actions, QQmlProperties &modified, TransitionDirection direction, - QObject *defaultTarget = 0); + QObject *defaultTarget = nullptr); QAbstractAnimationJob* qtAnimation(); private Q_SLOTS: @@ -166,8 +166,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPauseAnimation : public QQuickAbstractAnimati Q_PROPERTY(int duration READ duration WRITE setDuration NOTIFY durationChanged) public: - QQuickPauseAnimation(QObject *parent=0); - virtual ~QQuickPauseAnimation(); + QQuickPauseAnimation(QObject *parent=nullptr); + ~QQuickPauseAnimation() override; int duration() const; void setDuration(int); @@ -179,7 +179,7 @@ protected: QAbstractAnimationJob* transition(QQuickStateActions &actions, QQmlProperties &modified, TransitionDirection direction, - QObject *defaultTarget = 0) override; + QObject *defaultTarget = nullptr) override; }; class QQuickScriptActionPrivate; @@ -192,8 +192,8 @@ class QQuickScriptAction : public QQuickAbstractAnimation Q_PROPERTY(QString scriptName READ stateChangeScriptName WRITE setStateChangeScriptName) public: - QQuickScriptAction(QObject *parent=0); - virtual ~QQuickScriptAction(); + QQuickScriptAction(QObject *parent=nullptr); + ~QQuickScriptAction() override; QQmlScriptString script() const; void setScript(const QQmlScriptString &); @@ -205,7 +205,7 @@ protected: QAbstractAnimationJob* transition(QQuickStateActions &actions, QQmlProperties &modified, TransitionDirection direction, - QObject *defaultTarget = 0) override; + QObject *defaultTarget = nullptr) override; }; class QQuickPropertyActionPrivate; @@ -222,8 +222,8 @@ class QQuickPropertyAction : public QQuickAbstractAnimation Q_PROPERTY(QVariant value READ value WRITE setValue NOTIFY valueChanged) public: - QQuickPropertyAction(QObject *parent=0); - virtual ~QQuickPropertyAction(); + QQuickPropertyAction(QObject *parent=nullptr); + ~QQuickPropertyAction() override; QObject *target() const; void setTargetObject(QObject *); @@ -250,7 +250,7 @@ protected: QAbstractAnimationJob* transition(QQuickStateActions &actions, QQmlProperties &modified, TransitionDirection direction, - QObject *defaultTarget = 0) override; + QObject *defaultTarget = nullptr) override; }; class QQuickPropertyAnimationPrivate; @@ -270,8 +270,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPropertyAnimation : public QQuickAbstractAnim Q_PROPERTY(QQmlListProperty<QObject> exclude READ exclude) public: - QQuickPropertyAnimation(QObject *parent=0); - virtual ~QQuickPropertyAnimation(); + QQuickPropertyAnimation(QObject *parent=nullptr); + ~QQuickPropertyAnimation() override; virtual int duration() const; virtual void setDuration(int); @@ -300,17 +300,17 @@ public: protected: QQuickStateActions createTransitionActions(QQuickStateActions &actions, QQmlProperties &modified, - QObject *defaultTarget = 0); + QObject *defaultTarget = nullptr); QQuickPropertyAnimation(QQuickPropertyAnimationPrivate &dd, QObject *parent); QAbstractAnimationJob* transition(QQuickStateActions &actions, QQmlProperties &modified, TransitionDirection direction, - QObject *defaultTarget = 0) override; + QObject *defaultTarget = nullptr) override; Q_SIGNALS: void durationChanged(int); - void fromChanged(const QVariant &); - void toChanged(const QVariant &); + void fromChanged(); + void toChanged(); void easingChanged(const QEasingCurve &); void propertiesChanged(const QString &); void targetChanged(); @@ -325,8 +325,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickColorAnimation : public QQuickPropertyAnimati Q_PROPERTY(QColor to READ to WRITE setTo) public: - QQuickColorAnimation(QObject *parent=0); - virtual ~QQuickColorAnimation(); + QQuickColorAnimation(QObject *parent=nullptr); + ~QQuickColorAnimation() override; QColor from() const; void setFrom(const QColor &); @@ -340,12 +340,12 @@ class Q_QUICK_PRIVATE_EXPORT QQuickNumberAnimation : public QQuickPropertyAnimat Q_OBJECT Q_DECLARE_PRIVATE(QQuickPropertyAnimation) - Q_PROPERTY(qreal from READ from WRITE setFrom) - Q_PROPERTY(qreal to READ to WRITE setTo) + Q_PROPERTY(qreal from READ from WRITE setFrom NOTIFY fromChanged) + Q_PROPERTY(qreal to READ to WRITE setTo NOTIFY toChanged) public: - QQuickNumberAnimation(QObject *parent=0); - virtual ~QQuickNumberAnimation(); + QQuickNumberAnimation(QObject *parent=nullptr); + ~QQuickNumberAnimation() override; qreal from() const; void setFrom(qreal); @@ -365,12 +365,12 @@ class Q_QUICK_PRIVATE_EXPORT QQuickVector3dAnimation : public QQuickPropertyAnim Q_OBJECT Q_DECLARE_PRIVATE(QQuickPropertyAnimation) - Q_PROPERTY(QVector3D from READ from WRITE setFrom) - Q_PROPERTY(QVector3D to READ to WRITE setTo) + Q_PROPERTY(QVector3D from READ from WRITE setFrom NOTIFY fromChanged) + Q_PROPERTY(QVector3D to READ to WRITE setTo NOTIFY toChanged) public: - QQuickVector3dAnimation(QObject *parent=0); - virtual ~QQuickVector3dAnimation(); + QQuickVector3dAnimation(QObject *parent=nullptr); + ~QQuickVector3dAnimation() override; QVector3D from() const; void setFrom(QVector3D); @@ -385,13 +385,13 @@ class Q_QUICK_PRIVATE_EXPORT QQuickRotationAnimation : public QQuickPropertyAnim Q_OBJECT Q_DECLARE_PRIVATE(QQuickRotationAnimation) - Q_PROPERTY(qreal from READ from WRITE setFrom) - Q_PROPERTY(qreal to READ to WRITE setTo) + Q_PROPERTY(qreal from READ from WRITE setFrom NOTIFY fromChanged) + Q_PROPERTY(qreal to READ to WRITE setTo NOTIFY toChanged) Q_PROPERTY(RotationDirection direction READ direction WRITE setDirection NOTIFY directionChanged) public: - QQuickRotationAnimation(QObject *parent=0); - virtual ~QQuickRotationAnimation(); + QQuickRotationAnimation(QObject *parent=nullptr); + ~QQuickRotationAnimation() override; qreal from() const; void setFrom(qreal); @@ -419,7 +419,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickAnimationGroup : public QQuickAbstractAnimati public: QQuickAnimationGroup(QObject *parent); - virtual ~QQuickAnimationGroup(); + ~QQuickAnimationGroup() override; QQmlListProperty<QQuickAbstractAnimation> animations(); friend class QQuickAbstractAnimation; @@ -434,15 +434,15 @@ class QQuickSequentialAnimation : public QQuickAnimationGroup Q_DECLARE_PRIVATE(QQuickAnimationGroup) public: - QQuickSequentialAnimation(QObject *parent=0); - virtual ~QQuickSequentialAnimation(); + QQuickSequentialAnimation(QObject *parent=nullptr); + ~QQuickSequentialAnimation() override; protected: ThreadingModel threadingModel() const override; QAbstractAnimationJob* transition(QQuickStateActions &actions, QQmlProperties &modified, TransitionDirection direction, - QObject *defaultTarget = 0) override; + QObject *defaultTarget = nullptr) override; }; class Q_QUICK_PRIVATE_EXPORT QQuickParallelAnimation : public QQuickAnimationGroup @@ -451,15 +451,15 @@ class Q_QUICK_PRIVATE_EXPORT QQuickParallelAnimation : public QQuickAnimationGro Q_DECLARE_PRIVATE(QQuickAnimationGroup) public: - QQuickParallelAnimation(QObject *parent=0); - virtual ~QQuickParallelAnimation(); + QQuickParallelAnimation(QObject *parent=nullptr); + ~QQuickParallelAnimation() override; protected: ThreadingModel threadingModel() const override; QAbstractAnimationJob* transition(QQuickStateActions &actions, QQmlProperties &modified, TransitionDirection direction, - QObject *defaultTarget = 0) override; + QObject *defaultTarget = nullptr) override; }; diff --git a/src/quick/util/qquickanimation_p_p.h b/src/quick/util/qquickanimation_p_p.h index 7a1bd8ff13..c20ec65c24 100644 --- a/src/quick/util/qquickanimation_p_p.h +++ b/src/quick/util/qquickanimation_p_p.h @@ -102,7 +102,7 @@ public: QActionAnimation(); QActionAnimation(QAbstractAnimationAction *action); - ~QActionAnimation(); + ~QActionAnimation() override; int duration() const override; void setAnimAction(QAbstractAnimationAction *action); @@ -130,7 +130,7 @@ class Q_AUTOTEST_EXPORT QQuickBulkValueAnimator : public QAbstractAnimationJob Q_DISABLE_COPY(QQuickBulkValueAnimator) public: QQuickBulkValueAnimator(); - ~QQuickBulkValueAnimator(); + ~QQuickBulkValueAnimator() override; void setAnimValue(QQuickBulkValueUpdater *value); QQuickBulkValueUpdater *getAnimValue() const { return animValue; } @@ -178,7 +178,7 @@ public: : running(false), paused(false), alwaysRunToEnd(false), /*connectedTimeLine(false), */componentComplete(true), avoidPropertyValueSourceStart(false), disableUserControl(false), - registered(false), loopCount(1), group(0), animationInstance(0) {} + registered(false), loopCount(1), group(nullptr), animationInstance(nullptr) {} bool running:1; bool paused:1; @@ -237,7 +237,7 @@ class QQuickPropertyActionPrivate : public QQuickAbstractAnimationPrivate Q_DECLARE_PUBLIC(QQuickPropertyAction) public: QQuickPropertyActionPrivate() - : QQuickAbstractAnimationPrivate(), target(0) {} + : QQuickAbstractAnimationPrivate(), target(nullptr) {} QObject *target; QString propertyName; @@ -265,8 +265,8 @@ class QQuickPropertyAnimationPrivate : public QQuickAbstractAnimationPrivate Q_DECLARE_PUBLIC(QQuickPropertyAnimation) public: QQuickPropertyAnimationPrivate() - : QQuickAbstractAnimationPrivate(), target(0), fromSourced(false), fromIsDefined(false), toIsDefined(false), - defaultToInterpolatorType(0), interpolatorType(0), interpolator(0), duration(250), actions(0) {} + : QQuickAbstractAnimationPrivate(), target(nullptr), fromSourced(false), fromIsDefined(false), toIsDefined(false), + defaultToInterpolatorType(0), interpolatorType(0), interpolator(nullptr), duration(250), actions(nullptr) {} QVariant from; QVariant to; @@ -306,8 +306,8 @@ public: class Q_AUTOTEST_EXPORT QQuickAnimationPropertyUpdater : public QQuickBulkValueUpdater { public: - QQuickAnimationPropertyUpdater() : interpolatorType(0), interpolator(0), prevInterpolatorType(0), reverse(false), fromSourced(false), fromDefined(false), wasDeleted(0) {} - ~QQuickAnimationPropertyUpdater(); + QQuickAnimationPropertyUpdater() : interpolatorType(0), interpolator(nullptr), prevInterpolatorType(0), reverse(false), fromSourced(false), fromDefined(false), wasDeleted(nullptr) {} + ~QQuickAnimationPropertyUpdater() override; void setValue(qreal v) override; diff --git a/src/quick/util/qquickanimationcontroller.cpp b/src/quick/util/qquickanimationcontroller.cpp index cebb0391ae..63373541a6 100644 --- a/src/quick/util/qquickanimationcontroller.cpp +++ b/src/quick/util/qquickanimationcontroller.cpp @@ -49,7 +49,7 @@ class QQuickAnimationControllerPrivate : public QObjectPrivate, QAnimationJobCha Q_DECLARE_PUBLIC(QQuickAnimationController) public: QQuickAnimationControllerPrivate() - : progress(0.0), animation(0), animationInstance(0), finalized(false) {} + : progress(0.0), animation(nullptr), animationInstance(nullptr), finalized(false) {} void animationFinished(QAbstractAnimationJob *job) override; void animationCurrentTimeChanged(QAbstractAnimationJob *job, int currentTime) override; @@ -197,7 +197,7 @@ void QQuickAnimationController::reload() return; if (!d->animation) { - d->animationInstance = 0; + d->animationInstance = nullptr; } else { QQuickStateActions actions; QQmlProperties properties; @@ -223,7 +223,7 @@ void QQuickAnimationController::updateProgress() d->animationInstance->setDisableUserControl(); d->animationInstance->start(); - QQmlAnimationTimer::unregisterAnimation(d->animationInstance); + QQmlAnimationTimer::instance()->unregisterAnimation(d->animationInstance); d->animationInstance->setCurrentTime(d->progress * d->animationInstance->duration()); } diff --git a/src/quick/util/qquickanimationcontroller_p.h b/src/quick/util/qquickanimationcontroller_p.h index 43555ac1c1..d9ce377060 100644 --- a/src/quick/util/qquickanimationcontroller_p.h +++ b/src/quick/util/qquickanimationcontroller_p.h @@ -69,7 +69,7 @@ class Q_AUTOTEST_EXPORT QQuickAnimationController : public QObject, public QQmlP Q_PROPERTY(QQuickAbstractAnimation *animation READ animation WRITE setAnimation NOTIFY animationChanged) public: - QQuickAnimationController(QObject *parent=0); + QQuickAnimationController(QObject *parent=nullptr); ~QQuickAnimationController(); qreal progress() const; diff --git a/src/quick/util/qquickanimator.cpp b/src/quick/util/qquickanimator.cpp index 5608326f8a..d1ff78f8bc 100644 --- a/src/quick/util/qquickanimator.cpp +++ b/src/quick/util/qquickanimator.cpp @@ -280,22 +280,22 @@ QAbstractAnimationJob *QQuickAnimator::transition(QQuickStateActions &actions, if (d->defaultProperty.isValid() && propertyName() != d->defaultProperty.name()) { qDebug() << Q_FUNC_INFO << "property name conflict..."; - return 0; + return nullptr; } // The animation system cannot handle backwards uncontrolled animations. if (direction == Backward) - return 0; + return nullptr; QQuickAnimatorJob *job = createJob(); if (!job) - return 0; + return nullptr; d->apply(job, propertyName(), actions, modified, defaultTarget); if (!job->target()) { delete job; - return 0; + return nullptr; } return job; @@ -576,7 +576,7 @@ QQuickAnimatorJob *QQuickUniformAnimator::createJob() const { QString u = propertyName(); if (u.isEmpty()) - return 0; + return nullptr; QQuickUniformAnimatorJob *job = new QQuickUniformAnimatorJob(); job->setUniform(u.toLatin1()); diff --git a/src/quick/util/qquickanimator_p.h b/src/quick/util/qquickanimator_p.h index 92c66299dc..511cecda7f 100644 --- a/src/quick/util/qquickanimator_p.h +++ b/src/quick/util/qquickanimator_p.h @@ -94,8 +94,8 @@ protected: TransitionDirection, QObject *) override; - QQuickAnimator(QQuickAnimatorPrivate &dd, QObject *parent = 0); - QQuickAnimator(QObject *parent = 0); + QQuickAnimator(QQuickAnimatorPrivate &dd, QObject *parent = nullptr); + QQuickAnimator(QObject *parent = nullptr); Q_SIGNALS: void targetItemChanged(QQuickItem *); @@ -110,7 +110,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickScaleAnimator : public QQuickAnimator { Q_OBJECT public: - QQuickScaleAnimator(QObject *parent = 0); + QQuickScaleAnimator(QObject *parent = nullptr); protected: QQuickAnimatorJob *createJob() const override; QString propertyName() const override { return QStringLiteral("scale"); } @@ -120,7 +120,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickXAnimator : public QQuickAnimator { Q_OBJECT public: - QQuickXAnimator(QObject *parent = 0); + QQuickXAnimator(QObject *parent = nullptr); protected: QQuickAnimatorJob *createJob() const override; QString propertyName() const override { return QStringLiteral("x"); } @@ -130,7 +130,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickYAnimator : public QQuickAnimator { Q_OBJECT public: - QQuickYAnimator(QObject *parent = 0); + QQuickYAnimator(QObject *parent = nullptr); protected: QQuickAnimatorJob *createJob() const override; QString propertyName() const override { return QStringLiteral("y"); } @@ -140,7 +140,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickOpacityAnimator : public QQuickAnimator { Q_OBJECT public: - QQuickOpacityAnimator(QObject *parent = 0); + QQuickOpacityAnimator(QObject *parent = nullptr); protected: QQuickAnimatorJob *createJob() const override; QString propertyName() const override { return QStringLiteral("opacity"); } @@ -157,7 +157,7 @@ public: enum RotationDirection { Numerical, Shortest, Clockwise, Counterclockwise }; Q_ENUM(RotationDirection) - QQuickRotationAnimator(QObject *parent = 0); + QQuickRotationAnimator(QObject *parent = nullptr); void setDirection(RotationDirection dir); RotationDirection direction() const; @@ -179,7 +179,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickUniformAnimator : public QQuickAnimator Q_PROPERTY(QString uniform READ uniform WRITE setUniform NOTIFY uniformChanged) public: - QQuickUniformAnimator(QObject *parent = 0); + QQuickUniformAnimator(QObject *parent = nullptr); QString uniform() const; void setUniform(const QString &); diff --git a/src/quick/util/qquickanimatorcontroller.cpp b/src/quick/util/qquickanimatorcontroller.cpp index 3f7347c01d..5cf8051922 100644 --- a/src/quick/util/qquickanimatorcontroller.cpp +++ b/src/quick/util/qquickanimatorcontroller.cpp @@ -123,8 +123,10 @@ static void qquickanimator_sync_before_start(QAbstractAnimationJob *job) void QQuickAnimatorController::beforeNodeSync() { - for (const QSharedPointer<QAbstractAnimationJob> &toStop : qAsConst(m_rootsPendingStop)) + for (const QSharedPointer<QAbstractAnimationJob> &toStop : qAsConst(m_rootsPendingStop)) { toStop->stop(); + m_animationRoots.remove(toStop.data()); + } m_rootsPendingStop.clear(); diff --git a/src/quick/util/qquickanimatorjob.cpp b/src/quick/util/qquickanimatorjob.cpp index 43c8eb302a..6574f8f67e 100644 --- a/src/quick/util/qquickanimatorjob.cpp +++ b/src/quick/util/qquickanimatorjob.cpp @@ -250,8 +250,8 @@ void QQuickAnimatorProxyJob::syncBackCurrentValues() } QQuickAnimatorJob::QQuickAnimatorJob() - : m_target(0) - , m_controller(0) + : m_target(nullptr) + , m_controller(nullptr) , m_from(0) , m_to(0) , m_value(0) diff --git a/src/quick/util/qquickanimatorjob_p.h b/src/quick/util/qquickanimatorjob_p.h index 777da2ee6c..74085526c0 100644 --- a/src/quick/util/qquickanimatorjob_p.h +++ b/src/quick/util/qquickanimatorjob_p.h @@ -194,7 +194,7 @@ public: { Helper() : ref(1) - , node(0) + , node(nullptr) , ox(0) , oy(0) , dx(0) diff --git a/src/quick/util/qquickapplication_p.h b/src/quick/util/qquickapplication_p.h index 8ee203f0da..66a33489e4 100644 --- a/src/quick/util/qquickapplication_p.h +++ b/src/quick/util/qquickapplication_p.h @@ -72,7 +72,7 @@ class Q_AUTOTEST_EXPORT QQuickApplication : public QQmlApplication Q_PROPERTY(QQmlListProperty<QQuickScreenInfo> screens READ screens NOTIFY screensChanged) public: - explicit QQuickApplication(QObject *parent = 0); + explicit QQuickApplication(QObject *parent = nullptr); virtual ~QQuickApplication(); bool active() const; Qt::LayoutDirection layoutDirection() const; diff --git a/src/quick/util/qquickbehavior.cpp b/src/quick/util/qquickbehavior.cpp index a562ebd937..8a4ff6a779 100644 --- a/src/quick/util/qquickbehavior.cpp +++ b/src/quick/util/qquickbehavior.cpp @@ -57,7 +57,7 @@ class QQuickBehaviorPrivate : public QObjectPrivate, public QAnimationJobChangeL { Q_DECLARE_PUBLIC(QQuickBehavior) public: - QQuickBehaviorPrivate() : animation(0), animationInstance(0), enabled(true), finalized(false) + QQuickBehaviorPrivate() : animation(nullptr), animationInstance(nullptr), enabled(true), finalized(false) , blockRunningChanged(false) {} void animationStateChanged(QAbstractAnimationJob *, QAbstractAnimationJob::State newState, QAbstractAnimationJob::State oldState) override; diff --git a/src/quick/util/qquickbehavior_p.h b/src/quick/util/qquickbehavior_p.h index b3fd2af400..f939597d15 100644 --- a/src/quick/util/qquickbehavior_p.h +++ b/src/quick/util/qquickbehavior_p.h @@ -72,7 +72,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickBehavior : public QObject, public QQmlPropert Q_CLASSINFO("DeferredPropertyNames", "animation") public: - QQuickBehavior(QObject *parent=0); + QQuickBehavior(QObject *parent=nullptr); ~QQuickBehavior(); void setTarget(const QQmlProperty &) override; diff --git a/src/quick/util/qquickfontloader.cpp b/src/quick/util/qquickfontloader.cpp index 68e27c25fd..2da541304d 100644 --- a/src/quick/util/qquickfontloader.cpp +++ b/src/quick/util/qquickfontloader.cpp @@ -77,8 +77,8 @@ Q_SIGNALS: void fontDownloaded(const QString&, QQuickFontLoader::Status); private: - int redirectCount; - QNetworkReply *reply; + int redirectCount = 0; + QNetworkReply *reply = nullptr; private Q_SLOTS: void replyFinished(); @@ -91,13 +91,8 @@ public: }; QQuickFontObject::QQuickFontObject(int _id) - : QObject(0) -#if QT_CONFIG(qml_network) - ,redirectCount(0), reply(0) -#endif - ,id(_id) + : QObject(nullptr), id(_id) { - } #if QT_CONFIG(qml_network) @@ -119,7 +114,7 @@ void QQuickFontObject::replyFinished() QUrl url = reply->url().resolved(redirect.toUrl()); QNetworkAccessManager *manager = reply->manager(); reply->deleteLater(); - reply = 0; + reply = nullptr; download(url, manager); return; } @@ -138,7 +133,7 @@ void QQuickFontObject::replyFinished() emit fontDownloaded(QString(), QQuickFontLoader::Error); } reply->deleteLater(); - reply = 0; + reply = nullptr; } } #endif // qml_network @@ -148,11 +143,11 @@ class QQuickFontLoaderPrivate : public QObjectPrivate Q_DECLARE_PUBLIC(QQuickFontLoader) public: - QQuickFontLoaderPrivate() : status(QQuickFontLoader::Null) {} + QQuickFontLoaderPrivate() {} QUrl url; QString name; - QQuickFontLoader::Status status; + QQuickFontLoader::Status status = QQuickFontLoader::Null; }; static void q_QFontLoaderFontsStaticReset(); diff --git a/src/quick/util/qquickfontloader_p.h b/src/quick/util/qquickfontloader_p.h index 29feecde4f..8d277f7cf7 100644 --- a/src/quick/util/qquickfontloader_p.h +++ b/src/quick/util/qquickfontloader_p.h @@ -72,7 +72,7 @@ public: enum Status { Null = 0, Ready, Loading, Error }; Q_ENUM(Status) - QQuickFontLoader(QObject *parent = 0); + QQuickFontLoader(QObject *parent = nullptr); ~QQuickFontLoader(); QUrl source() const; diff --git a/src/quick/util/qquickfontmetrics_p.h b/src/quick/util/qquickfontmetrics_p.h index ebabe51712..db2b7b6796 100644 --- a/src/quick/util/qquickfontmetrics_p.h +++ b/src/quick/util/qquickfontmetrics_p.h @@ -80,7 +80,7 @@ class Q_AUTOTEST_EXPORT QQuickFontMetrics : public QObject Q_PROPERTY(qreal strikeOutPosition READ strikeOutPosition NOTIFY fontChanged) Q_PROPERTY(qreal lineWidth READ lineWidth NOTIFY fontChanged) public: - explicit QQuickFontMetrics(QObject *parent = 0); + explicit QQuickFontMetrics(QObject *parent = nullptr); ~QQuickFontMetrics(); QFont font() const; diff --git a/src/quick/util/qquickglobal.cpp b/src/quick/util/qquickglobal.cpp index 5f8d2b94d3..7fa20636ec 100644 --- a/src/quick/util/qquickglobal.cpp +++ b/src/quick/util/qquickglobal.cpp @@ -419,7 +419,7 @@ public: break; } - return 0; + return nullptr; } bool init(int type, QVariant& dst) override @@ -863,8 +863,8 @@ void QQuick_initializeProviders() void QQuick_deinitializeProviders() { QQml_removeValueTypeProvider(getValueTypeProvider()); - QQml_setColorProvider(0); // technically, another plugin may have overridden our providers - QQml_setGuiProvider(0); // but we cannot handle that case in a sane way. + QQml_setColorProvider(nullptr); // technically, another plugin may have overridden our providers + QQml_setGuiProvider(nullptr); // but we cannot handle that case in a sane way. } QT_END_NAMESPACE diff --git a/src/quick/util/qquickimageprovider.cpp b/src/quick/util/qquickimageprovider.cpp index 6ee5b95dc7..1a13f6395a 100644 --- a/src/quick/util/qquickimageprovider.cpp +++ b/src/quick/util/qquickimageprovider.cpp @@ -108,7 +108,7 @@ QImage QQuickTextureFactory::image() const QQuickTextureFactory *QQuickTextureFactory::textureFactoryForImage(const QImage &image) { if (image.isNull()) - return 0; + return nullptr; QQuickTextureFactory *texture = QSGContext::createTextureFactoryFromImage(image); if (texture) return texture; @@ -469,7 +469,7 @@ QQuickTextureFactory *QQuickImageProvider::requestTexture(const QString &id, QSi Q_UNUSED(requestedSize); if (d->type == Texture) qWarning("ImageProvider supports Texture type but has not implemented requestTexture()"); - return 0; + return nullptr; } /*! @@ -484,7 +484,7 @@ QQuickTextureFactory *QQuickImageProvider::requestTexture(const QString &id, QSi */ QQuickAsyncImageProvider::QQuickAsyncImageProvider() : QQuickImageProvider(ImageResponse, ForceAsynchronousImageLoading) - , d(0) // just as a placeholder in case we need it for the future + , d(nullptr) // just as a placeholder in case we need it for the future { Q_UNUSED(d); } @@ -515,15 +515,12 @@ class QQuickImageProviderOptionsPrivate : public QSharedData { public: QQuickImageProviderOptionsPrivate() - : autoTransform(QQuickImageProviderOptions::UsePluginDefaultTransform) - , preserveAspectRatioCrop(false) - , preserveAspectRatioFit(false) { } - QQuickImageProviderOptions::AutoTransform autoTransform; - bool preserveAspectRatioCrop; - bool preserveAspectRatioFit; + QQuickImageProviderOptions::AutoTransform autoTransform = QQuickImageProviderOptions::UsePluginDefaultTransform; + bool preserveAspectRatioCrop = false; + bool preserveAspectRatioFit = false; }; /*! @@ -683,13 +680,15 @@ QSize QQuickImageProviderWithOptions::loadSize(const QSize &originalSize, const return res; const bool preserveAspectCropOrFit = options.preserveAspectRatioCrop() || options.preserveAspectRatioFit(); - const bool force_scale = (format == "svg" || format == "svgz"); + + if (!preserveAspectCropOrFit && (format == "svg" || format == "svgz") && !requestedSize.isEmpty()) + return requestedSize; qreal ratio = 0.0; - if (requestedSize.width() && (preserveAspectCropOrFit || force_scale || requestedSize.width() < originalSize.width())) { + if (requestedSize.width() && (preserveAspectCropOrFit || requestedSize.width() < originalSize.width())) { ratio = qreal(requestedSize.width()) / originalSize.width(); } - if (requestedSize.height() && (preserveAspectCropOrFit || force_scale || requestedSize.height() < originalSize.height())) { + if (requestedSize.height() && (preserveAspectCropOrFit || requestedSize.height() < originalSize.height())) { qreal hr = qreal(requestedSize.height()) / originalSize.height(); if (ratio == 0.0) ratio = hr; diff --git a/src/quick/util/qquickimageprovider.h b/src/quick/util/qquickimageprovider.h index 681de4b6c2..4f8193789a 100644 --- a/src/quick/util/qquickimageprovider.h +++ b/src/quick/util/qquickimageprovider.h @@ -56,9 +56,10 @@ class QQuickWindow; class Q_QUICK_EXPORT QQuickTextureFactory : public QObject { + Q_OBJECT public: QQuickTextureFactory(); - virtual ~QQuickTextureFactory(); + ~QQuickTextureFactory() override; virtual QSGTexture *createTexture(QQuickWindow *window) const = 0; virtual QSize textureSize() const = 0; @@ -73,7 +74,7 @@ class Q_QUICK_EXPORT QQuickImageResponse : public QObject Q_OBJECT public: QQuickImageResponse(); - virtual ~QQuickImageResponse(); + ~QQuickImageResponse() override; virtual QQuickTextureFactory *textureFactory() const = 0; virtual QString errorString() const; @@ -90,7 +91,7 @@ class Q_QUICK_EXPORT QQuickImageProvider : public QQmlImageProviderBase friend class QQuickImageProviderWithOptions; // ### Qt 6 Remove public: QQuickImageProvider(ImageType type, Flags flags = Flags()); - virtual ~QQuickImageProvider(); + ~QQuickImageProvider() override; ImageType imageType() const override; Flags flags() const override; @@ -113,7 +114,7 @@ class Q_QUICK_EXPORT QQuickAsyncImageProvider : public QQuickImageProvider { public: QQuickAsyncImageProvider(); - virtual ~QQuickAsyncImageProvider(); + ~QQuickAsyncImageProvider() override; #if QT_VERSION >= QT_VERSION_CHECK(6,0,0) virtual QQuickImageResponse *requestImageResponse(const QString &id, const QSize &requestedSize, const QQuickImageProviderOptions &options) = 0; diff --git a/src/quick/util/qquickpath.cpp b/src/quick/util/qquickpath.cpp index 0323dc9286..56eafcd12a 100644 --- a/src/quick/util/qquickpath.cpp +++ b/src/quick/util/qquickpath.cpp @@ -256,7 +256,7 @@ bool QQuickPath::isClosed() const QQmlListProperty<QQuickPathElement> QQuickPath::pathElements() { return QQmlListProperty<QQuickPathElement>(this, - 0, + nullptr, pathElements_append, pathElements_count, pathElements_at, @@ -397,7 +397,12 @@ void QQuickPath::processPath() d->_pointCache.clear(); d->prevBez.isValid = false; - d->_path = createPath(QPointF(), QPointF(), d->_attributes, d->pathLength, d->_attributePoints, &d->closed); + if (d->isShapePath) { + // This path is a ShapePath, so avoid extra overhead + d->_path = createShapePath(QPointF(), QPointF(), d->pathLength, &d->closed); + } else { + d->_path = createPath(QPointF(), QPointF(), d->_attributes, d->pathLength, d->_attributePoints, &d->closed); + } emit changed(); } @@ -493,6 +498,42 @@ QPainterPath QQuickPath::createPath(const QPointF &startPoint, const QPointF &en return path; } +QPainterPath QQuickPath::createShapePath(const QPointF &startPoint, const QPointF &endPoint, qreal &pathLength, bool *closed) +{ + Q_D(QQuickPath); + + if (!d->componentComplete) + return QPainterPath(); + + QPainterPath path; + + qreal startX = d->startX.isValid() ? d->startX.value : startPoint.x(); + qreal startY = d->startY.isValid() ? d->startY.value : startPoint.y(); + path.moveTo(startX, startY); + + int index = 0; + for (QQuickCurve *curve : qAsConst(d->_pathCurves)) { + QQuickPathData data; + data.index = index; + data.endPoint = endPoint; + data.curves = d->_pathCurves; + curve->addToPath(path, data); + ++index; + } + + if (closed) { + QPointF end = path.currentPosition(); + *closed = startX == end.x() && startY == end.y(); + } + + // Note: Length of paths inside ShapePath is not used, so currently + // length is always 0. This avoids potentially heavy path.length() + //pathLength = path.length(); + pathLength = 0; + + return path; +} + void QQuickPath::classBegin() { Q_D(QQuickPath); diff --git a/src/quick/util/qquickpath_p.h b/src/quick/util/qquickpath_p.h index d5474e2d30..6b9a40fe6d 100644 --- a/src/quick/util/qquickpath_p.h +++ b/src/quick/util/qquickpath_p.h @@ -78,7 +78,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathElement : public QObject { Q_OBJECT public: - QQuickPathElement(QObject *parent=0) : QObject(parent) {} + QQuickPathElement(QObject *parent=nullptr) : QObject(parent) {} Q_SIGNALS: void changed(); }; @@ -90,7 +90,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathAttribute : public QQuickPathElement Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) Q_PROPERTY(qreal value READ value WRITE setValue NOTIFY valueChanged) public: - QQuickPathAttribute(QObject *parent=0) : QQuickPathElement(parent), _value(0) {} + QQuickPathAttribute(QObject *parent=nullptr) : QQuickPathElement(parent) {} QString name() const; @@ -105,7 +105,7 @@ Q_SIGNALS: private: QString _name; - qreal _value; + qreal _value = 0; }; class Q_QUICK_PRIVATE_EXPORT QQuickCurve : public QQuickPathElement @@ -117,7 +117,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickCurve : public QQuickPathElement Q_PROPERTY(qreal relativeX READ relativeX WRITE setRelativeX NOTIFY relativeXChanged) Q_PROPERTY(qreal relativeY READ relativeY WRITE setRelativeY NOTIFY relativeYChanged) public: - QQuickCurve(QObject *parent=0) : QQuickPathElement(parent) {} + QQuickCurve(QObject *parent=nullptr) : QQuickPathElement(parent) {} qreal x() const; void setX(qreal x); @@ -154,7 +154,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathLine : public QQuickCurve { Q_OBJECT public: - QQuickPathLine(QObject *parent=0) : QQuickCurve(parent) {} + QQuickPathLine(QObject *parent=nullptr) : QQuickCurve(parent) {} void addToPath(QPainterPath &path, const QQuickPathData &) override; }; @@ -163,7 +163,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathMove : public QQuickCurve { Q_OBJECT public: - QQuickPathMove(QObject *parent=0) : QQuickCurve(parent) {} + QQuickPathMove(QObject *parent=nullptr) : QQuickCurve(parent) {} void addToPath(QPainterPath &path, const QQuickPathData &) override; }; @@ -177,7 +177,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathQuad : public QQuickCurve Q_PROPERTY(qreal relativeControlX READ relativeControlX WRITE setRelativeControlX NOTIFY relativeControlXChanged) Q_PROPERTY(qreal relativeControlY READ relativeControlY WRITE setRelativeControlY NOTIFY relativeControlYChanged) public: - QQuickPathQuad(QObject *parent=0) : QQuickCurve(parent), _controlX(0), _controlY(0) {} + QQuickPathQuad(QObject *parent=nullptr) : QQuickCurve(parent) {} qreal controlX() const; void setControlX(qreal x); @@ -202,8 +202,8 @@ Q_SIGNALS: void relativeControlYChanged(); private: - qreal _controlX; - qreal _controlY; + qreal _controlX = 0; + qreal _controlY = 0; QQmlNullableValue<qreal> _relativeControlX; QQmlNullableValue<qreal> _relativeControlY; }; @@ -221,7 +221,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathCubic : public QQuickCurve Q_PROPERTY(qreal relativeControl2X READ relativeControl2X WRITE setRelativeControl2X NOTIFY relativeControl2XChanged) Q_PROPERTY(qreal relativeControl2Y READ relativeControl2Y WRITE setRelativeControl2Y NOTIFY relativeControl2YChanged) public: - QQuickPathCubic(QObject *parent=0) : QQuickCurve(parent), _control1X(0), _control1Y(0), _control2X(0), _control2Y(0) {} + QQuickPathCubic(QObject *parent=nullptr) : QQuickCurve(parent) {} qreal control1X() const; void setControl1X(qreal x); @@ -264,10 +264,10 @@ Q_SIGNALS: void relativeControl2YChanged(); private: - qreal _control1X; - qreal _control1Y; - qreal _control2X; - qreal _control2Y; + qreal _control1X = 0; + qreal _control1Y = 0; + qreal _control2X = 0; + qreal _control2Y = 0; QQmlNullableValue<qreal> _relativeControl1X; QQmlNullableValue<qreal> _relativeControl1Y; QQmlNullableValue<qreal> _relativeControl2X; @@ -278,7 +278,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathCatmullRomCurve : public QQuickCurve { Q_OBJECT public: - QQuickPathCatmullRomCurve(QObject *parent=0) : QQuickCurve(parent) {} + QQuickPathCatmullRomCurve(QObject *parent=nullptr) : QQuickCurve(parent) {} void addToPath(QPainterPath &path, const QQuickPathData &) override; }; @@ -293,8 +293,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathArc : public QQuickCurve Q_PROPERTY(qreal xAxisRotation READ xAxisRotation WRITE setXAxisRotation NOTIFY xAxisRotationChanged REVISION 2) public: - QQuickPathArc(QObject *parent=0) - : QQuickCurve(parent), _radiusX(0), _radiusY(0), _useLargeArc(false), _direction(Clockwise), _xAxisRotation(0) {} + QQuickPathArc(QObject *parent=nullptr) + : QQuickCurve(parent) {} enum ArcDirection { Clockwise, Counterclockwise }; Q_ENUM(ArcDirection) @@ -324,11 +324,11 @@ Q_SIGNALS: Q_REVISION(2) void xAxisRotationChanged(); private: - qreal _radiusX; - qreal _radiusY; - bool _useLargeArc; - ArcDirection _direction; - qreal _xAxisRotation; + qreal _radiusX = 0; + qreal _radiusY = 0; + bool _useLargeArc = false; + ArcDirection _direction = Clockwise; + qreal _xAxisRotation = 0; }; class Q_QUICK_PRIVATE_EXPORT QQuickPathAngleArc : public QQuickCurve @@ -343,8 +343,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathAngleArc : public QQuickCurve Q_PROPERTY(bool moveToStart READ moveToStart WRITE setMoveToStart NOTIFY moveToStartChanged) public: - QQuickPathAngleArc(QObject *parent=0) - : QQuickCurve(parent), _centerX(0), _centerY(0), _radiusX(0), _radiusY(0), _startAngle(0), _sweepAngle(0), _moveToStart(true) {} + QQuickPathAngleArc(QObject *parent=nullptr) + : QQuickCurve(parent) {} qreal centerX() const; void setCenterX(qreal); @@ -379,13 +379,13 @@ Q_SIGNALS: void moveToStartChanged(); private: - qreal _centerX; - qreal _centerY; - qreal _radiusX; - qreal _radiusY; - qreal _startAngle; - qreal _sweepAngle; - bool _moveToStart; + qreal _centerX = 0; + qreal _centerY = 0; + qreal _radiusX = 0; + qreal _radiusY = 0; + qreal _startAngle = 0; + qreal _sweepAngle = 0; + bool _moveToStart = true; }; class Q_QUICK_PRIVATE_EXPORT QQuickPathSvg : public QQuickCurve @@ -393,7 +393,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathSvg : public QQuickCurve Q_OBJECT Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged) public: - QQuickPathSvg(QObject *parent=0) : QQuickCurve(parent) {} + QQuickPathSvg(QObject *parent=nullptr) : QQuickCurve(parent) {} QString path() const; void setPath(const QString &path); @@ -412,7 +412,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathPercent : public QQuickPathElement Q_OBJECT Q_PROPERTY(qreal value READ value WRITE setValue NOTIFY valueChanged) public: - QQuickPathPercent(QObject *parent=0) : QQuickPathElement(parent), _value(0) {} + QQuickPathPercent(QObject *parent=nullptr) : QQuickPathElement(parent) {} qreal value() const; void setValue(qreal value); @@ -421,18 +421,18 @@ Q_SIGNALS: void valueChanged(); private: - qreal _value; + qreal _value = 0; }; struct QQuickCachedBezier { - QQuickCachedBezier() : isValid(false) {} + QQuickCachedBezier() {} QBezier bezier; int element; qreal bezLength; qreal currLength; qreal p; - bool isValid; + bool isValid = false; }; class QQuickPathPrivate; @@ -448,8 +448,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPath : public QObject, public QQmlParserStatu Q_CLASSINFO("DefaultProperty", "pathElements") Q_INTERFACES(QQmlParserStatus) public: - QQuickPath(QObject *parent=0); - ~QQuickPath(); + QQuickPath(QObject *parent=nullptr); + ~QQuickPath() override; QQmlListProperty<QQuickPathElement> pathElements(); @@ -467,7 +467,7 @@ public: QStringList attributes() const; qreal attributeAt(const QString &, qreal) const; QPointF pointAt(qreal) const; - QPointF sequentialPointAt(qreal p, qreal *angle = 0) const; + QPointF sequentialPointAt(qreal p, qreal *angle = nullptr) const; void invalidateSequentialHistory() const; Q_SIGNALS: @@ -494,15 +494,15 @@ private Q_SLOTS: private: struct AttributePoint { - AttributePoint() : percent(0), scale(1), origpercent(0) {} + AttributePoint() {} AttributePoint(const AttributePoint &other) : percent(other.percent), scale(other.scale), origpercent(other.origpercent), values(other.values) {} AttributePoint &operator=(const AttributePoint &other) { percent = other.percent; scale = other.scale; origpercent = other.origpercent; values = other.values; return *this; } - qreal percent; //massaged percent along the painter path - qreal scale; - qreal origpercent; //'real' percent along the painter path + qreal percent = 0; //massaged percent along the painter path + qreal scale = 1; + qreal origpercent = 0; //'real' percent along the painter path QHash<QString, qreal> values; }; @@ -512,8 +512,8 @@ private: static void interpolate(QList<AttributePoint> &points, int idx, const QString &name, qreal value); static void endpoint(QList<AttributePoint> &attributePoints, const QString &name); - static QPointF forwardsPointAt(const QPainterPath &path, const qreal &pathLength, const QList<AttributePoint> &attributePoints, QQuickCachedBezier &prevBez, qreal p, qreal *angle = 0); - static QPointF backwardsPointAt(const QPainterPath &path, const qreal &pathLength, const QList<AttributePoint> &attributePoints, QQuickCachedBezier &prevBez, qreal p, qreal *angle = 0); + static QPointF forwardsPointAt(const QPainterPath &path, const qreal &pathLength, const QList<AttributePoint> &attributePoints, QQuickCachedBezier &prevBez, qreal p, qreal *angle = nullptr); + static QPointF backwardsPointAt(const QPainterPath &path, const qreal &pathLength, const QList<AttributePoint> &attributePoints, QQuickCachedBezier &prevBez, qreal p, qreal *angle = nullptr); private: Q_DISABLE_COPY(QQuickPath) @@ -521,8 +521,9 @@ private: friend class QQuickPathAnimationUpdater; public: - QPainterPath createPath(const QPointF &startPoint, const QPointF &endPoint, const QStringList &attributes, qreal &pathLength, QList<AttributePoint> &attributePoints, bool *closed = 0); - static QPointF sequentialPointAt(const QPainterPath &path, const qreal &pathLength, const QList<AttributePoint> &attributePoints, QQuickCachedBezier &prevBez, qreal p, qreal *angle = 0); + QPainterPath createPath(const QPointF &startPoint, const QPointF &endPoint, const QStringList &attributes, qreal &pathLength, QList<AttributePoint> &attributePoints, bool *closed = nullptr); + QPainterPath createShapePath(const QPointF &startPoint, const QPointF &endPoint, qreal &pathLength, bool *closed = nullptr); + static QPointF sequentialPointAt(const QPainterPath &path, const qreal &pathLength, const QList<AttributePoint> &attributePoints, QQuickCachedBezier &prevBez, qreal p, qreal *angle = nullptr); }; QT_END_NAMESPACE diff --git a/src/quick/util/qquickpath_p_p.h b/src/quick/util/qquickpath_p_p.h index 8ce85dbf0f..9735d51264 100644 --- a/src/quick/util/qquickpath_p_p.h +++ b/src/quick/util/qquickpath_p_p.h @@ -72,7 +72,7 @@ public: static QQuickPathPrivate* get(QQuickPath *path) { return path->d_func(); } static const QQuickPathPrivate* get(const QQuickPath *path) { return path->d_func(); } - QQuickPathPrivate() : pathLength(0), closed(false), componentComplete(true) { } + QQuickPathPrivate() {} QPainterPath _path; QList<QQuickPathElement*> _pathElements; @@ -83,9 +83,10 @@ public: mutable QQuickCachedBezier prevBez; QQmlNullableValue<qreal> startX; QQmlNullableValue<qreal> startY; - qreal pathLength; - bool closed; - bool componentComplete; + qreal pathLength = 0; + bool closed = false; + bool componentComplete = true; + bool isShapePath = false; }; QT_END_NAMESPACE diff --git a/src/quick/util/qquickpathinterpolator.cpp b/src/quick/util/qquickpathinterpolator.cpp index 838213042e..bb47ca0205 100644 --- a/src/quick/util/qquickpathinterpolator.cpp +++ b/src/quick/util/qquickpathinterpolator.cpp @@ -59,7 +59,7 @@ QT_BEGIN_NAMESPACE */ QQuickPathInterpolator::QQuickPathInterpolator(QObject *parent) : - QObject(parent), _path(0), _x(0), _y(0), _angle(0), _progress(0) + QObject(parent), _path(nullptr), _x(0), _y(0), _angle(0), _progress(0) { } diff --git a/src/quick/util/qquickpathinterpolator_p.h b/src/quick/util/qquickpathinterpolator_p.h index 0fdb1a444f..60a9ff2e22 100644 --- a/src/quick/util/qquickpathinterpolator_p.h +++ b/src/quick/util/qquickpathinterpolator_p.h @@ -70,7 +70,7 @@ class Q_AUTOTEST_EXPORT QQuickPathInterpolator : public QObject Q_PROPERTY(qreal y READ y NOTIFY yChanged) Q_PROPERTY(qreal angle READ angle NOTIFY angleChanged) public: - explicit QQuickPathInterpolator(QObject *parent = 0); + explicit QQuickPathInterpolator(QObject *parent = nullptr); QQuickPath *path() const; void setPath(QQuickPath *path); diff --git a/src/quick/util/qquickpixmapcache.cpp b/src/quick/util/qquickpixmapcache.cpp index e218b84fff..4237ec3edf 100644 --- a/src/quick/util/qquickpixmapcache.cpp +++ b/src/quick/util/qquickpixmapcache.cpp @@ -244,8 +244,8 @@ public: : refCount(1), inCache(false), pixmapStatus(QQuickPixmap::Error), url(u), errorString(e), requestSize(s), providerOptions(po), appliedTransform(QQuickImageProviderOptions::UsePluginDefaultTransform), - textureFactory(0), reply(0), prevUnreferenced(0), - prevUnreferencedPtr(0), nextUnreferenced(0) + textureFactory(nullptr), reply(nullptr), prevUnreferenced(nullptr), + prevUnreferencedPtr(nullptr), nextUnreferenced(nullptr) { declarativePixmaps.insert(pixmap); } @@ -254,8 +254,8 @@ public: : refCount(1), inCache(false), pixmapStatus(QQuickPixmap::Loading), url(u), requestSize(r), providerOptions(po), appliedTransform(aTransform), - textureFactory(0), reply(0), prevUnreferenced(0), prevUnreferencedPtr(0), - nextUnreferenced(0) + textureFactory(nullptr), reply(nullptr), prevUnreferenced(nullptr), prevUnreferencedPtr(nullptr), + nextUnreferenced(nullptr) { declarativePixmaps.insert(pixmap); } @@ -265,8 +265,8 @@ public: : refCount(1), inCache(false), pixmapStatus(QQuickPixmap::Ready), url(u), implicitSize(s), requestSize(r), providerOptions(po), appliedTransform(aTransform), - textureFactory(texture), reply(0), prevUnreferenced(0), - prevUnreferencedPtr(0), nextUnreferenced(0) + textureFactory(texture), reply(nullptr), prevUnreferenced(nullptr), + prevUnreferencedPtr(nullptr), nextUnreferenced(nullptr) { declarativePixmaps.insert(pixmap); } @@ -274,8 +274,8 @@ public: QQuickPixmapData(QQuickPixmap *pixmap, QQuickTextureFactory *texture) : refCount(1), inCache(false), pixmapStatus(QQuickPixmap::Ready), appliedTransform(QQuickImageProviderOptions::UsePluginDefaultTransform), - textureFactory(texture), reply(0), prevUnreferenced(0), - prevUnreferencedPtr(0), nextUnreferenced(0) + textureFactory(texture), reply(nullptr), prevUnreferenced(nullptr), + prevUnreferencedPtr(nullptr), nextUnreferenced(nullptr) { if (texture) requestSize = implicitSize = texture->textureSize(); @@ -287,7 +287,7 @@ public: while (!declarativePixmaps.isEmpty()) { QQuickPixmap *referencer = declarativePixmaps.first(); declarativePixmaps.remove(referencer); - referencer->d = 0; + referencer->d = nullptr; } delete textureFactory; } @@ -414,10 +414,54 @@ static bool readImage(const QUrl& url, QIODevice *dev, QImage *image, QString *e } } +static QStringList fromLatin1List(const QList<QByteArray> &list) +{ + QStringList res; + res.reserve(list.size()); + for (const QByteArray &item : list) + res.append(QString::fromLatin1(item)); + return res; +} + +class BackendSupport +{ +public: + BackendSupport() + { + delete QSGContext::createTextureFactoryFromImage(QImage()); // Force init of backend data + hasOpenGL = QQuickWindow::sceneGraphBackend().isEmpty(); // i.e. default + QList<QByteArray> list; + if (hasOpenGL) + list.append(QSGTextureReader::supportedFileFormats()); + list.append(QImageReader::supportedImageFormats()); + fileSuffixes = fromLatin1List(list); + } + bool hasOpenGL; + QStringList fileSuffixes; +}; +Q_GLOBAL_STATIC(BackendSupport, backendSupport); + +static QString existingImageFileForPath(const QString &localFile) +{ + // Do nothing if given filepath exists or already has a suffix + QFileInfo fi(localFile); + if (!fi.suffix().isEmpty() || fi.exists()) + return localFile; + + QString tryFile = localFile + QStringLiteral(".xxxx"); + const int suffixIdx = localFile.length() + 1; + for (const QString &suffix : backendSupport()->fileSuffixes) { + tryFile.replace(suffixIdx, 10, suffix); + if (QFileInfo::exists(tryFile)) + return tryFile; + } + return localFile; +} + QQuickPixmapReader::QQuickPixmapReader(QQmlEngine *eng) -: QThread(eng), engine(eng), threadObject(0) +: QThread(eng), engine(eng), threadObject(nullptr) #if QT_CONFIG(qml_network) -, accessManager(0) +, accessManager(nullptr) #endif { eventLoopQuitHack = new QObject; @@ -436,7 +480,7 @@ QQuickPixmapReader::~QQuickPixmapReader() // manually cancel all outstanding jobs. for (QQuickPixmapReply *reply : qAsConst(jobs)) { if (reply->data && reply->data->reply == reply) - reply->data->reply = 0; + reply->data->reply = nullptr; delete reply; } jobs.clear(); @@ -445,7 +489,7 @@ QQuickPixmapReader::~QQuickPixmapReader() const auto cancelJob = [this](QQuickPixmapReply *reply) { if (reply->loading) { cancelled.append(reply); - reply->data = 0; + reply->data = nullptr; } }; @@ -519,7 +563,7 @@ void QQuickPixmapReader::asyncResponseFinished(QQuickImageResponse *response) QQuickPixmapReply *job = asyncResponses.take(response); if (job) { - QQuickTextureFactory *t = 0; + QQuickTextureFactory *t = nullptr; QQuickPixmapReply::ReadError error = QQuickPixmapReply::NoError; QString errorString; if (!response->errorString().isEmpty()) { @@ -618,7 +662,7 @@ void QQuickPixmapReader::processJobs() const QUrl url = job->url; QString localFile; QQuickImageProvider::ImageType imageType = QQuickImageProvider::Invalid; - QQuickImageProvider *provider = 0; + QQuickImageProvider *provider = nullptr; if (url.scheme() == QLatin1String("image")) { provider = static_cast<QQuickImageProvider *>(engine->imageProvider(imageProviderId(url))); @@ -667,7 +711,7 @@ void QQuickPixmapReader::processJob(QQuickPixmapReply *runningJob, const QUrl &u QString errorStr = QQuickPixmap::tr("Invalid image provider: %1").arg(url.toString()); mutex.lock(); if (!cancelled.contains(runningJob)) - runningJob->postReply(QQuickPixmapReply::Loading, errorStr, readSize, 0); + runningJob->postReply(QQuickPixmapReply::Loading, errorStr, readSize, nullptr); mutex.unlock(); return; } @@ -769,18 +813,18 @@ void QQuickPixmapReader::processJob(QQuickPixmapReply *runningJob, const QUrl &u QImage image; QQuickPixmapReply::ReadError errorCode = QQuickPixmapReply::NoError; QString errorStr; - QFile f(localFile); + QFile f(existingImageFileForPath(localFile)); QSize readSize; if (f.open(QIODevice::ReadOnly)) { - - // for now, purely use suffix information to determine whether we are working with a compressed texture - QByteArray suffix = QFileInfo(f).suffix().toLower().toLatin1(); - if (QSGTextureReader::isTexture(&f, suffix)) { - QQuickTextureFactory *factory = QSGTextureReader::read(&f, suffix); + QSGTextureReader texReader(&f, localFile); + if (backendSupport()->hasOpenGL && texReader.isTexture()) { + QQuickTextureFactory *factory = texReader.read(); if (factory) { readSize = factory->textureSize(); } else { errorStr = QQuickPixmap::tr("Error decoding: %1").arg(url.toString()); + if (f.fileName() != localFile) + errorStr += QString::fromLatin1(" (%1)").arg(f.fileName()); errorCode = QQuickPixmapReply::Decoding; } mutex.lock(); @@ -789,8 +833,11 @@ void QQuickPixmapReader::processJob(QQuickPixmapReply *runningJob, const QUrl &u mutex.unlock(); return; } else { - if (!readImage(url, &f, &image, &errorStr, &readSize, runningJob->requestSize, runningJob->providerOptions)) + if (!readImage(url, &f, &image, &errorStr, &readSize, runningJob->requestSize, runningJob->providerOptions)) { errorCode = QQuickPixmapReply::Loading; + if (f.fileName() != localFile) + errorStr += QString::fromLatin1(" (%1)").arg(f.fileName()); + } } } else { errorStr = QQuickPixmap::tr("Cannot open: %1").arg(url.toString()); @@ -853,7 +900,7 @@ void QQuickPixmapReader::cancel(QQuickPixmapReply *reply) mutex.lock(); if (reply->loading) { cancelled.append(reply); - reply->data = 0; + reply->data = nullptr; // XXX if (threadObject) threadObject->processJobs(); } else { @@ -887,7 +934,7 @@ void QQuickPixmapReader::run() exec(); delete threadObject; - threadObject = 0; + threadObject = nullptr; } class QQuickPixmapKey @@ -940,7 +987,7 @@ Q_GLOBAL_STATIC(QQuickPixmapStore, pixmapStore); QQuickPixmapStore::QQuickPixmapStore() - : m_unreferencedPixmaps(0), m_lastUnreferencedPixmap(0), m_unreferencedCost(0), m_timerId(-1), m_destroying(false) + : m_unreferencedPixmaps(nullptr), m_lastUnreferencedPixmap(nullptr), m_unreferencedCost(0), m_timerId(-1), m_destroying(false) { } @@ -983,9 +1030,9 @@ QQuickPixmapStore::~QQuickPixmapStore() void QQuickPixmapStore::unreferencePixmap(QQuickPixmapData *data) { - Q_ASSERT(data->prevUnreferenced == 0); - Q_ASSERT(data->prevUnreferencedPtr == 0); - Q_ASSERT(data->nextUnreferenced == 0); + Q_ASSERT(data->prevUnreferenced == nullptr); + Q_ASSERT(data->prevUnreferencedPtr == nullptr); + Q_ASSERT(data->nextUnreferenced == nullptr); data->nextUnreferenced = m_unreferencedPixmaps; data->prevUnreferencedPtr = &m_unreferencedPixmaps; @@ -1021,9 +1068,9 @@ void QQuickPixmapStore::referencePixmap(QQuickPixmapData *data) if (m_lastUnreferencedPixmap == data) m_lastUnreferencedPixmap = data->prevUnreferenced; - data->nextUnreferenced = 0; - data->prevUnreferencedPtr = 0; - data->prevUnreferenced = 0; + data->nextUnreferenced = nullptr; + data->prevUnreferencedPtr = nullptr; + data->prevUnreferenced = nullptr; m_unreferencedCost -= data->cost(); } @@ -1032,12 +1079,12 @@ void QQuickPixmapStore::shrinkCache(int remove) { while ((remove > 0 || m_unreferencedCost > cache_limit) && m_lastUnreferencedPixmap) { QQuickPixmapData *data = m_lastUnreferencedPixmap; - Q_ASSERT(data->nextUnreferenced == 0); + Q_ASSERT(data->nextUnreferenced == nullptr); - *data->prevUnreferencedPtr = 0; + *data->prevUnreferencedPtr = nullptr; m_lastUnreferencedPixmap = data->prevUnreferenced; - data->prevUnreferencedPtr = 0; - data->prevUnreferenced = 0; + data->prevUnreferencedPtr = nullptr; + data->prevUnreferenced = nullptr; if (!m_destroying) { remove -= data->cost(); @@ -1054,7 +1101,7 @@ void QQuickPixmapStore::timerEvent(QTimerEvent *) shrinkCache(removalCost); - if (m_unreferencedPixmaps == 0) { + if (m_unreferencedPixmaps == nullptr) { killTimer(m_timerId); m_timerId = -1; } @@ -1071,7 +1118,7 @@ void QQuickPixmap::purgeCache() } QQuickPixmapReply::QQuickPixmapReply(QQuickPixmapData *d) -: data(d), engineForReader(0), requestSize(d->requestSize), url(d->url), loading(false), providerOptions(d->providerOptions), redirectCount(0) +: data(d), engineForReader(nullptr), requestSize(d->requestSize), url(d->url), loading(false), providerOptions(d->providerOptions), redirectCount(0) { if (finishedIndex == -1) { finishedIndex = QMetaMethod::fromSignal(&QQuickPixmapReply::finished).methodIndex(); @@ -1094,10 +1141,10 @@ bool QQuickPixmapReply::event(QEvent *event) data->pixmapStatus = (de->error == NoError) ? QQuickPixmap::Ready : QQuickPixmap::Error; if (data->pixmapStatus == QQuickPixmap::Ready) { data->textureFactory = de->textureFactory; - de->textureFactory = 0; + de->textureFactory = nullptr; data->implicitSize = de->implicitSize; PIXMAP_PROFILE(pixmapLoadingFinished(data->url, - data->textureFactory != 0 && data->textureFactory->textureSize().isValid() ? + data->textureFactory != nullptr && data->textureFactory->textureSize().isValid() ? data->textureFactory->textureSize() : (data->requestSize.isValid() ? data->requestSize : data->implicitSize))); } else { @@ -1106,7 +1153,7 @@ bool QQuickPixmapReply::event(QEvent *event) data->removeFromCache(); // We don't continue to cache error'd pixmaps } - data->reply = 0; + data->reply = nullptr; emit finished(); } else { PIXMAP_PROFILE(pixmapStateChanged<QQuickProfiler::PixmapLoadingError>(url)); @@ -1142,8 +1189,8 @@ void QQuickPixmapData::release() if (refCount == 0) { if (reply) { QQuickPixmapReply *cancelReply = reply; - reply->data = 0; - reply = 0; + reply->data = nullptr; + reply = nullptr; QQuickPixmapReader::readerMutex.lock(); QQuickPixmapReader *reader = QQuickPixmapReader::existingInstance(cancelReply->engineForReader); if (reader) @@ -1245,22 +1292,23 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q QString localFile = QQmlFile::urlToLocalFileOrQrc(url); if (localFile.isEmpty()) - return 0; + return nullptr; - QFile f(localFile); + QFile f(existingImageFileForPath(localFile)); QSize readSize; QString errorString; if (f.open(QIODevice::ReadOnly)) { - // for now, purely use suffix information to determine whether we are working with a compressed texture - QByteArray suffix = QFileInfo(f).suffix().toLower().toLatin1(); - if (QSGTextureReader::isTexture(&f, suffix)) { - QQuickTextureFactory *factory = QSGTextureReader::read(&f, suffix); + QSGTextureReader texReader(&f, localFile); + if (backendSupport()->hasOpenGL && texReader.isTexture()) { + QQuickTextureFactory *factory = texReader.read(); if (factory) { *ok = true; - return new QQuickPixmapData(declarativePixmap, factory); + return new QQuickPixmapData(declarativePixmap, url, factory, factory->textureSize(), requestSize, providerOptions, QQuickImageProviderOptions::UsePluginDefaultTransform); } else { errorString = QQuickPixmap::tr("Error decoding: %1").arg(url.toString()); + if (f.fileName() != localFile) + errorString += QString::fromLatin1(" (%1)").arg(f.fileName()); } } else { QImage image; @@ -1268,6 +1316,8 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q if (readImage(url, &f, &image, &errorString, &readSize, requestSize, providerOptions, &appliedTransform)) { *ok = true; return new QQuickPixmapData(declarativePixmap, url, QQuickTextureFactory::textureFactoryForImage(image), readSize, requestSize, providerOptions, appliedTransform); + } else if (f.fileName() != localFile) { + errorString += QString::fromLatin1(" (%1)").arg(f.fileName()); } } } else { @@ -1284,18 +1334,18 @@ struct QQuickPixmapNull { Q_GLOBAL_STATIC(QQuickPixmapNull, nullPixmap); QQuickPixmap::QQuickPixmap() -: d(0) +: d(nullptr) { } QQuickPixmap::QQuickPixmap(QQmlEngine *engine, const QUrl &url) -: d(0) +: d(nullptr) { load(engine, url); } QQuickPixmap::QQuickPixmap(QQmlEngine *engine, const QUrl &url, const QSize &size) -: d(0) +: d(nullptr) { load(engine, url, size); } @@ -1311,13 +1361,13 @@ QQuickPixmap::~QQuickPixmap() if (d) { d->declarativePixmaps.remove(this); d->release(); - d = 0; + d = nullptr; } } bool QQuickPixmap::isNull() const { - return d == 0; + return d == nullptr; } bool QQuickPixmap::isReady() const @@ -1388,7 +1438,7 @@ QQuickTextureFactory *QQuickPixmap::textureFactory() const if (d) return d->textureFactory; - return 0; + return nullptr; } QImage QQuickPixmap::image() const @@ -1466,7 +1516,7 @@ void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QSize &reques if (d) { d->declarativePixmaps.remove(this); d->release(); - d = 0; + d = nullptr; } QQuickPixmapKey key = { &url, &requestSize, providerOptions }; @@ -1538,7 +1588,7 @@ void QQuickPixmap::clear() if (d) { d->declarativePixmaps.remove(this); d->release(); - d = 0; + d = nullptr; } } @@ -1546,10 +1596,10 @@ void QQuickPixmap::clear(QObject *obj) { if (d) { if (d->reply) - QObject::disconnect(d->reply, 0, obj, 0); + QObject::disconnect(d->reply, nullptr, obj, nullptr); d->declarativePixmaps.remove(this); d->release(); - d = 0; + d = nullptr; } } diff --git a/src/quick/util/qquickprofiler.cpp b/src/quick/util/qquickprofiler.cpp index 402cd44ff0..bd9f04e562 100644 --- a/src/quick/util/qquickprofiler.cpp +++ b/src/quick/util/qquickprofiler.cpp @@ -47,12 +47,12 @@ QT_BEGIN_NAMESPACE // instance will be set, unset in constructor. Allows static methods to be inlined. -QQuickProfiler *QQuickProfiler::s_instance = 0; +QQuickProfiler *QQuickProfiler::s_instance = nullptr; quint64 QQuickProfiler::featuresEnabled = 0; void QQuickProfiler::initialize(QObject *parent) { - Q_ASSERT(s_instance == 0); + Q_ASSERT(s_instance == nullptr); s_instance = new QQuickProfiler(parent); } @@ -99,7 +99,7 @@ QQuickProfiler::~QQuickProfiler() { QMutexLocker lock(&m_dataMutex); featuresEnabled = 0; - s_instance = 0; + s_instance = nullptr; } void QQuickProfiler::startProfilingImpl(quint64 features) diff --git a/src/quick/util/qquickprofiler_p.h b/src/quick/util/qquickprofiler_p.h index 38027a6abf..d699ddf371 100644 --- a/src/quick/util/qquickprofiler_p.h +++ b/src/quick/util/qquickprofiler_p.h @@ -333,7 +333,7 @@ public: static void initialize(QObject *parent); - virtual ~QQuickProfiler(); + ~QQuickProfiler() override; signals: void dataReady(const QVector<QQuickProfilerData> &data); diff --git a/src/quick/util/qquickpropertychanges.cpp b/src/quick/util/qquickpropertychanges.cpp index 4a9b4a95c1..a3a598621f 100644 --- a/src/quick/util/qquickpropertychanges.cpp +++ b/src/quick/util/qquickpropertychanges.cpp @@ -213,13 +213,15 @@ public: class ExpressionChange { public: ExpressionChange(const QString &_name, + const QV4::CompiledData::Binding *_binding, QQmlBinding::Identifier _id, const QString& _expr, const QUrl &_url, int _line, int _column) - : name(_name), id(_id), expression(_expr), url(_url), line(_line), column(_column) {} + : name(_name), binding(_binding), id(_id), expression(_expr), url(_url), line(_line), column(_column) {} QString name; + const QV4::CompiledData::Binding *binding; QQmlBinding::Identifier id; QString expression; QUrl url; @@ -281,19 +283,22 @@ void QQuickPropertyChangesPrivate::decodeBinding(const QString &propertyPrefix, return; } - QQmlProperty prop = property(propertyName); //### better way to check for signal property? - - if (prop.type() & QQmlProperty::SignalProperty) { - QQuickReplaceSignalHandler *handler = new QQuickReplaceSignalHandler; - handler->property = prop; - handler->expression.take(new QQmlBoundSignalExpression(object, QQmlPropertyPrivate::get(prop)->signalIndex(), - QQmlContextData::get(qmlContext(q)), object, compilationUnit->runtimeFunctions.at(binding->value.compiledScriptIndex))); - signalReplacements << handler; - return; + if (propertyName.count() >= 3 && + propertyName.at(0) == QLatin1Char('o') && + propertyName.at(1) == QLatin1Char('n') && + propertyName.at(2).isUpper()) { + QQmlProperty prop = property(propertyName); + if (prop.isSignalProperty()) { + QQuickReplaceSignalHandler *handler = new QQuickReplaceSignalHandler; + handler->property = prop; + handler->expression.take(new QQmlBoundSignalExpression(object, QQmlPropertyPrivate::get(prop)->signalIndex(), + QQmlContextData::get(qmlContext(q)), object, compilationUnit->runtimeFunctions.at(binding->value.compiledScriptIndex))); + signalReplacements << handler; + return; + } } - if (binding->type == QV4::CompiledData::Binding::Type_Script) { - QString expression = binding->valueAsString(qmlUnit); + if (binding->type == QV4::CompiledData::Binding::Type_Script || binding->containsTranslations()) { QUrl url = QUrl(); int line = -1; int column = -1; @@ -305,16 +310,23 @@ void QQuickPropertyChangesPrivate::decodeBinding(const QString &propertyPrefix, column = ddata->columnNumber; } - expressions << ExpressionChange(propertyName, binding->value.compiledScriptIndex, expression, url, line, column); + QString expression; + QQmlBinding::Identifier id = QQmlBinding::Invalid; + + if (!binding->containsTranslations()) { + expression = binding->valueAsString(qmlUnit); + id = binding->value.compiledScriptIndex; + } + expressions << ExpressionChange(propertyName, binding, id, expression, url, line, column); return; } QVariant var; switch (binding->type) { case QV4::CompiledData::Binding::Type_Script: - Q_UNREACHABLE(); case QV4::CompiledData::Binding::Type_Translation: case QV4::CompiledData::Binding::Type_TranslationById: + Q_UNREACHABLE(); case QV4::CompiledData::Binding::Type_String: var = binding->valueAsString(qmlUnit); break; @@ -395,7 +407,10 @@ QQmlProperty QQuickPropertyChangesPrivate::property(const QString &property) { Q_Q(QQuickPropertyChanges); - QQmlProperty prop(object, property, qmlContext(q)); + QQmlContextData *context = nullptr; + if (QQmlData *ddata = QQmlData::get(q)) + context = ddata->outerContext; + QQmlProperty prop = QQmlPropertyPrivate::create(object, property, context); if (!prop.isValid()) { qmlWarning(q) << QQuickPropertyChanges::tr("Cannot assign to non-existent property \"%1\"").arg(property); return QQmlProperty(); @@ -415,9 +430,10 @@ QQuickPropertyChanges::ActionList QQuickPropertyChanges::actions() ActionList list; for (int ii = 0; ii < d->properties.count(); ++ii) { + QQmlProperty prop = d->property(d->properties.at(ii).first); - QQuickStateAction a(d->object, d->properties.at(ii).first, - qmlContext(this), d->properties.at(ii).second); + QQuickStateAction a(d->object, prop, d->properties.at(ii).first, + d->properties.at(ii).second); if (a.property.isValid()) { a.restore = restoreEntryValues(); @@ -426,7 +442,6 @@ QQuickPropertyChanges::ActionList QQuickPropertyChanges::actions() } for (int ii = 0; ii < d->signalReplacements.count(); ++ii) { - QQuickReplaceSignalHandler *handler = d->signalReplacements.at(ii); if (handler->property.isValid()) { @@ -452,14 +467,15 @@ QQuickPropertyChanges::ActionList QQuickPropertyChanges::actions() QQmlContextData *context = QQmlContextData::get(qmlContext(this)); - QQmlBinding *newBinding = 0; - if (e.id != QQmlBinding::Invalid) { - QV4::Scope scope(QQmlEnginePrivate::getV4Engine(qmlEngine(this))); + QQmlBinding *newBinding = nullptr; + if (e.binding && e.binding->containsTranslations()) { + newBinding = QQmlBinding::createTranslationBinding(d->compilationUnit, e.binding, object(), context); + } else if (e.id != QQmlBinding::Invalid) { + QV4::Scope scope(qmlEngine(this)->handle()); QV4::Scoped<QV4::QmlContext> qmlContext(scope, QV4::QmlContext::create(scope.engine->rootContext(), context, object())); newBinding = QQmlBinding::create(&QQmlPropertyPrivate::get(prop)->core, d->compilationUnit->runtimeFunctions.at(e.id), object(), context, qmlContext); } -// QQmlBinding *newBinding = e.id != QQmlBinding::Invalid ? QQmlBinding::createBinding(e.id, object(), qmlContext(this)) : 0; if (!newBinding) newBinding = QQmlBinding::create(&QQmlPropertyPrivate::get(prop)->core, e.expression, object(), context, e.url.toString(), e.line); @@ -638,7 +654,7 @@ void QQuickPropertyChanges::changeExpression(const QString &name, const QString } // adding a new expression. - expressionIterator.insert(ExpressionEntry(name, QQmlBinding::Invalid, expression, QUrl(), -1, -1)); + expressionIterator.insert(ExpressionEntry(name, nullptr, QQmlBinding::Invalid, expression, QUrl(), -1, -1)); if (state() && state()->isStateActive()) { if (hadValue) { diff --git a/src/quick/util/qquickshortcut.cpp b/src/quick/util/qquickshortcut.cpp index 2fe4962b1a..78dc855326 100644 --- a/src/quick/util/qquickshortcut.cpp +++ b/src/quick/util/qquickshortcut.cpp @@ -41,6 +41,7 @@ #include <QtQuick/qquickitem.h> #include <QtQuick/qquickwindow.h> +#include <QtQuick/qquickrendercontrol.h> #include <QtQuick/private/qtquickglobal_p.h> #include <QtGui/private/qguiapplication_p.h> @@ -102,6 +103,8 @@ static bool qQuickShortcutContextMatcher(QObject *obj, Qt::ShortcutContext conte if (QQuickItem *item = qobject_cast<QQuickItem *>(obj)) obj = item->window(); } + if (QWindow *renderWindow = QQuickRenderControl::renderWindowFor(qobject_cast<QQuickWindow *>(obj))) + obj = renderWindow; return obj && obj == QGuiApplication::focusWindow(); default: return false; @@ -119,7 +122,8 @@ Q_QUICK_PRIVATE_EXPORT ContextMatcher qt_quick_shortcut_context_matcher() Q_QUICK_PRIVATE_EXPORT void qt_quick_set_shortcut_context_matcher(ContextMatcher matcher) { - *ctxMatcher() = matcher; + if (!ctxMatcher.isDestroyed()) + *ctxMatcher() = matcher; } QT_BEGIN_NAMESPACE diff --git a/src/quick/util/qquicksmoothedanimation_p.h b/src/quick/util/qquicksmoothedanimation_p.h index 2f0e3bc0d8..7bceba387c 100644 --- a/src/quick/util/qquicksmoothedanimation_p.h +++ b/src/quick/util/qquicksmoothedanimation_p.h @@ -73,7 +73,7 @@ public: enum ReversingMode { Eased, Immediate, Sync }; Q_ENUM(ReversingMode) - QQuickSmoothedAnimation(QObject *parent = 0); + QQuickSmoothedAnimation(QObject *parent = nullptr); ~QQuickSmoothedAnimation(); ReversingMode reversingMode() const; @@ -91,7 +91,7 @@ public: QAbstractAnimationJob* transition(QQuickStateActions &actions, QQmlProperties &modified, TransitionDirection direction, - QObject *defaultTarget = 0) override; + QObject *defaultTarget = nullptr) override; Q_SIGNALS: void velocityChanged(); void reversingModeChanged(); diff --git a/src/quick/util/qquicksmoothedanimation_p_p.h b/src/quick/util/qquicksmoothedanimation_p_p.h index a415fdb55f..7850562594 100644 --- a/src/quick/util/qquicksmoothedanimation_p_p.h +++ b/src/quick/util/qquicksmoothedanimation_p_p.h @@ -65,7 +65,7 @@ class QSmoothedAnimationTimer : public QTimer { Q_OBJECT public: - explicit QSmoothedAnimationTimer(QSmoothedAnimation *animation, QObject *parent = 0); + explicit QSmoothedAnimationTimer(QSmoothedAnimation *animation, QObject *parent = nullptr); ~QSmoothedAnimationTimer(); public Q_SLOTS: void stopAnimation(); @@ -78,7 +78,7 @@ class Q_AUTOTEST_EXPORT QSmoothedAnimation : public QAbstractAnimationJob { Q_DISABLE_COPY(QSmoothedAnimation) public: - QSmoothedAnimation(QQuickSmoothedAnimationPrivate * = 0); + QSmoothedAnimation(QQuickSmoothedAnimationPrivate * = nullptr); ~QSmoothedAnimation(); qreal to; @@ -98,7 +98,7 @@ public: void init(); void prepareForRestart(); - void clearTemplate() { animationTemplate = 0; } + void clearTemplate() { animationTemplate = nullptr; } protected: void updateCurrentTime(int) override; diff --git a/src/quick/util/qquickspringanimation.cpp b/src/quick/util/qquickspringanimation.cpp index bf844589ba..4389d941fd 100644 --- a/src/quick/util/qquickspringanimation.cpp +++ b/src/quick/util/qquickspringanimation.cpp @@ -58,7 +58,7 @@ class Q_AUTOTEST_EXPORT QSpringAnimation : public QAbstractAnimationJob { Q_DISABLE_COPY(QSpringAnimation) public: - QSpringAnimation(QQuickSpringAnimationPrivate * = 0); + QSpringAnimation(QQuickSpringAnimationPrivate * = nullptr); ~QSpringAnimation(); int duration() const override; @@ -94,7 +94,7 @@ public: typedef QHash<QQmlProperty, QSpringAnimation*> ActiveAnimationHash; typedef ActiveAnimationHash::Iterator ActiveAnimationHashIt; - void clearTemplate() { animationTemplate = 0; } + void clearTemplate() { animationTemplate = nullptr; } protected: void updateCurrentTime(int time) override; diff --git a/src/quick/util/qquickspringanimation_p.h b/src/quick/util/qquickspringanimation_p.h index ffb2c41e6b..2014a4311a 100644 --- a/src/quick/util/qquickspringanimation_p.h +++ b/src/quick/util/qquickspringanimation_p.h @@ -73,7 +73,7 @@ class Q_AUTOTEST_EXPORT QQuickSpringAnimation : public QQuickNumberAnimation Q_PROPERTY(qreal mass READ mass WRITE setMass NOTIFY massChanged) public: - QQuickSpringAnimation(QObject *parent=0); + QQuickSpringAnimation(QObject *parent=nullptr); ~QQuickSpringAnimation(); qreal velocity() const; @@ -97,7 +97,7 @@ public: QAbstractAnimationJob* transition(QQuickStateActions &actions, QQmlProperties &modified, TransitionDirection direction, - QObject *defaultTarget = 0) override; + QObject *defaultTarget = nullptr) override; Q_SIGNALS: void modulusChanged(); diff --git a/src/quick/util/qquickstate.cpp b/src/quick/util/qquickstate.cpp index 65e51feb81..be8300f531 100644 --- a/src/quick/util/qquickstate.cpp +++ b/src/quick/util/qquickstate.cpp @@ -52,8 +52,8 @@ QT_BEGIN_NAMESPACE DEFINE_BOOL_CONFIG_OPTION(stateChangeDebug, STATECHANGE_DEBUG); QQuickStateAction::QQuickStateAction() -: restore(true), actionDone(false), reverseEvent(false), deletableToBinding(false), fromBinding(0), event(0), - specifiedObject(0) +: restore(true), actionDone(false), reverseEvent(false), deletableToBinding(false), fromBinding(nullptr), event(nullptr), + specifiedObject(nullptr) { } @@ -61,18 +61,17 @@ QQuickStateAction::QQuickStateAction(QObject *target, const QString &propertyNam const QVariant &value) : restore(true), actionDone(false), reverseEvent(false), deletableToBinding(false), property(target, propertyName, qmlEngine(target)), toValue(value), - fromBinding(0), event(0), + fromBinding(nullptr), event(nullptr), specifiedObject(target), specifiedProperty(propertyName) { if (property.isValid()) fromValue = property.read(); } -QQuickStateAction::QQuickStateAction(QObject *target, const QString &propertyName, - QQmlContext *context, const QVariant &value) +QQuickStateAction::QQuickStateAction(QObject *target, const QQmlProperty &property, const QString &propertyName, const QVariant &value) : restore(true), actionDone(false), reverseEvent(false), deletableToBinding(false), - property(target, propertyName, context), toValue(value), - fromBinding(0), event(0), + property(property), toValue(value), + fromBinding(nullptr), event(nullptr), specifiedObject(target), specifiedProperty(propertyName) { if (property.isValid()) @@ -193,7 +192,7 @@ bool QQuickState::isNamed() const bool QQuickState::isWhenKnown() const { Q_D(const QQuickState); - return d->when != 0; + return d->when != nullptr; } /*! @@ -363,7 +362,7 @@ void QQuickStateAction::deleteFromBinding() { if (fromBinding) { QQmlPropertyPrivate::removeBinding(property); - fromBinding = 0; + fromBinding = nullptr; } } @@ -531,7 +530,7 @@ QQmlAbstractBinding *QQuickState::bindingInRevertList(QObject *target, const QSt } } - return 0; + return nullptr; } bool QQuickState::isStateActive() const diff --git a/src/quick/util/qquickstate_p.h b/src/quick/util/qquickstate_p.h index ac720f4189..79874ee78e 100644 --- a/src/quick/util/qquickstate_p.h +++ b/src/quick/util/qquickstate_p.h @@ -69,8 +69,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickStateAction public: QQuickStateAction(); QQuickStateAction(QObject *, const QString &, const QVariant &); - QQuickStateAction(QObject *, const QString &, - QQmlContext *, const QVariant &); + QQuickStateAction(QObject *, const QQmlProperty &property, const QString &, + const QVariant &); bool restore:1; bool actionDone:1; @@ -126,7 +126,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickStateOperation : public QObject { Q_OBJECT public: - QQuickStateOperation(QObject *parent = 0) + QQuickStateOperation(QObject *parent = nullptr) : QObject(parent) {} typedef QList<QQuickStateAction> ActionList; @@ -136,7 +136,7 @@ public: void setState(QQuickState *state); protected: - QQuickStateOperation(QObjectPrivate &dd, QObject *parent = 0); + QQuickStateOperation(QObjectPrivate &dd, QObject *parent = nullptr); private: Q_DECLARE_PRIVATE(QQuickStateOperation) @@ -159,8 +159,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickState : public QObject Q_CLASSINFO("DeferredPropertyNames", "changes") public: - QQuickState(QObject *parent=0); - virtual ~QQuickState(); + QQuickState(QObject *parent=nullptr); + ~QQuickState() override; QString name() const; void setName(const QString &); diff --git a/src/quick/util/qquickstate_p_p.h b/src/quick/util/qquickstate_p_p.h index eba1dabecf..f1bc24c558 100644 --- a/src/quick/util/qquickstate_p_p.h +++ b/src/quick/util/qquickstate_p_p.h @@ -178,8 +178,8 @@ private: class QQuickRevertAction { public: - QQuickRevertAction() : event(0) {} - QQuickRevertAction(const QQmlProperty &prop) : property(prop), event(0) {} + QQuickRevertAction() : event(nullptr) {} + QQuickRevertAction(const QQmlProperty &prop) : property(prop), event(nullptr) {} QQuickRevertAction(QQuickStateActionEvent *e) : event(e) {} QQmlProperty property; QQuickStateActionEvent *event; @@ -192,7 +192,7 @@ class QQuickStateOperationPrivate : public QObjectPrivate public: QQuickStateOperationPrivate() - : m_state(0) {} + : m_state(nullptr) {} QQuickState *m_state; }; @@ -203,7 +203,7 @@ class QQuickStatePrivate : public QObjectPrivate public: QQuickStatePrivate() - : when(0), named(false), inState(false), group(0) {} + : when(nullptr), named(false), inState(false), group(nullptr) {} typedef QList<QQuickSimpleAction> SimpleActionList; @@ -233,7 +233,7 @@ public: QList<OperationGuard> *list = static_cast<QList<OperationGuard> *>(prop->data); QMutableListIterator<OperationGuard> listIterator(*list); while(listIterator.hasNext()) - listIterator.next()->setState(0); + listIterator.next()->setState(nullptr); list->clear(); } static int operations_count(QQmlListProperty<QQuickStateOperation> *prop) { diff --git a/src/quick/util/qquickstatechangescript_p.h b/src/quick/util/qquickstatechangescript_p.h index a1315ae2ef..ff509a7cf5 100644 --- a/src/quick/util/qquickstatechangescript_p.h +++ b/src/quick/util/qquickstatechangescript_p.h @@ -66,7 +66,7 @@ class Q_AUTOTEST_EXPORT QQuickStateChangeScript : public QQuickStateOperation, p Q_PROPERTY(QString name READ name WRITE setName) public: - QQuickStateChangeScript(QObject *parent=0); + QQuickStateChangeScript(QObject *parent=nullptr); ~QQuickStateChangeScript(); ActionList actions() override; diff --git a/src/quick/util/qquickstategroup.cpp b/src/quick/util/qquickstategroup.cpp index ebcbbf93ed..1b99baed9a 100644 --- a/src/quick/util/qquickstategroup.cpp +++ b/src/quick/util/qquickstategroup.cpp @@ -60,7 +60,7 @@ class QQuickStateGroupPrivate : public QObjectPrivate Q_DECLARE_PUBLIC(QQuickStateGroup) public: QQuickStateGroupPrivate() - : nullState(0), componentComplete(true), + : nullState(nullptr), componentComplete(true), ignoreTrans(false), applyingState(false), unnamedCount(0) {} QString currentState; @@ -129,7 +129,7 @@ QQuickStateGroup::~QQuickStateGroup() { Q_D(const QQuickStateGroup); for (int i = 0; i < d->states.count(); ++i) - d->states.at(i)->setStateGroup(0); + d->states.at(i)->setStateGroup(nullptr); } QList<QQuickState *> QQuickStateGroup::states() const @@ -194,7 +194,7 @@ void QQuickStateGroupPrivate::clear_states(QQmlListProperty<QQuickState> *list) QQuickStateGroup *_this = static_cast<QQuickStateGroup *>(list->object); _this->d_func()->setCurrentStateInternal(QString(), true); for (int i = 0; i < _this->d_func()->states.count(); ++i) { - _this->d_func()->states.at(i)->setStateGroup(0); + _this->d_func()->states.at(i)->setStateGroup(nullptr); } _this->d_func()->states.clear(); } @@ -364,7 +364,7 @@ bool QQuickStateGroupPrivate::updateAutoState() QQuickTransition *QQuickStateGroupPrivate::findTransition(const QString &from, const QString &to) { - QQuickTransition *highest = 0; + QQuickTransition *highest = nullptr; int score = 0; bool reversed = false; bool done = false; @@ -444,7 +444,7 @@ void QQuickStateGroupPrivate::setCurrentStateInternal(const QString &state, applyingState = true; - QQuickTransition *transition = ignoreTrans ? 0 : findTransition(currentState, state); + QQuickTransition *transition = ignoreTrans ? nullptr : findTransition(currentState, state); if (stateChangeDebug()) { qWarning() << this << "Changing state. From" << currentState << ". To" << state; if (transition) @@ -452,7 +452,7 @@ void QQuickStateGroupPrivate::setCurrentStateInternal(const QString &state, << transition->toState(); } - QQuickState *oldState = 0; + QQuickState *oldState = nullptr; if (!currentState.isEmpty()) { for (int ii = 0; ii < states.count(); ++ii) { if (states.at(ii)->name() == currentState) { @@ -465,7 +465,7 @@ void QQuickStateGroupPrivate::setCurrentStateInternal(const QString &state, currentState = state; emit q->stateChanged(currentState); - QQuickState *newState = 0; + QQuickState *newState = nullptr; for (int ii = 0; ii < states.count(); ++ii) { if (states.at(ii)->name() == currentState) { newState = states.at(ii); @@ -473,7 +473,7 @@ void QQuickStateGroupPrivate::setCurrentStateInternal(const QString &state, } } - if (oldState == 0 || newState == 0) { + if (oldState == nullptr || newState == nullptr) { if (!nullState) { nullState = new QQuickState; QQml_setParent_noEvent(nullState, q); @@ -496,7 +496,7 @@ QQuickState *QQuickStateGroup::findState(const QString &name) const return state; } - return 0; + return nullptr; } void QQuickStateGroup::removeState(QQuickState *state) diff --git a/src/quick/util/qquickstategroup_p.h b/src/quick/util/qquickstategroup_p.h index eebe3a9e56..7235066d99 100644 --- a/src/quick/util/qquickstategroup_p.h +++ b/src/quick/util/qquickstategroup_p.h @@ -67,7 +67,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickStateGroup : public QObject, public QQmlParse Q_PROPERTY(QQmlListProperty<QQuickTransition> transitions READ transitionsProperty DESIGNABLE false) public: - QQuickStateGroup(QObject * = 0); + QQuickStateGroup(QObject * = nullptr); virtual ~QQuickStateGroup(); QString state() const; diff --git a/src/quick/util/qquickstyledtext.cpp b/src/quick/util/qquickstyledtext.cpp index ae8719341d..762d49f2d2 100644 --- a/src/quick/util/qquickstyledtext.cpp +++ b/src/quick/util/qquickstyledtext.cpp @@ -695,7 +695,7 @@ void QQuickStyledTextPrivate::parseImageAttributes(const QChar *&ch, const QStri image->size = image->pix->implicitSize(); } else { delete image->pix; - image->pix = 0; + image->pix = nullptr; } } } diff --git a/src/quick/util/qquickstyledtext_p.h b/src/quick/util/qquickstyledtext_p.h index 2a2e234224..51f1b7d8f9 100644 --- a/src/quick/util/qquickstyledtext_p.h +++ b/src/quick/util/qquickstyledtext_p.h @@ -67,9 +67,7 @@ class QQmlContext; class Q_AUTOTEST_EXPORT QQuickStyledTextImgTag { public: - QQuickStyledTextImgTag() - : position(0), offset(0.0), align(QQuickStyledTextImgTag::Bottom), pix(0) - { } + QQuickStyledTextImgTag() { } ~QQuickStyledTextImgTag() { delete pix; } @@ -82,10 +80,10 @@ public: QUrl url; QPointF pos; QSize size; - int position; - qreal offset; // this offset allows us to compensate for flooring reserved space - Align align; - QQuickPixmap *pix; + int position = 0; + qreal offset = 0.0; // this offset allows us to compensate for flooring reserved space + Align align = QQuickStyledTextImgTag::Bottom; + QQuickPixmap *pix = nullptr; }; class Q_AUTOTEST_EXPORT QQuickStyledText diff --git a/src/quick/util/qquicksvgparser.cpp b/src/quick/util/qquicksvgparser.cpp index 086c6d0b28..2bf9c121d3 100644 --- a/src/quick/util/qquicksvgparser.cpp +++ b/src/quick/util/qquicksvgparser.cpp @@ -126,7 +126,7 @@ static qreal toDouble(const QChar *&str) val = -val; } else { bool ok = false; - val = qstrtod(temp, 0, &ok); + val = qstrtod(temp, nullptr, &ok); } return val; diff --git a/src/quick/util/qquicksystempalette_p.h b/src/quick/util/qquicksystempalette_p.h index 086fb31993..9a3a520ed1 100644 --- a/src/quick/util/qquicksystempalette_p.h +++ b/src/quick/util/qquicksystempalette_p.h @@ -81,7 +81,7 @@ class Q_AUTOTEST_EXPORT QQuickSystemPalette : public QObject Q_PROPERTY(QColor highlightedText READ highlightedText NOTIFY paletteChanged) public: - QQuickSystemPalette(QObject *parent=0); + QQuickSystemPalette(QObject *parent=nullptr); ~QQuickSystemPalette(); enum ColorGroup { Active = QPalette::Active, Inactive = QPalette::Inactive, Disabled = QPalette::Disabled }; diff --git a/src/quick/util/qquicktimeline.cpp b/src/quick/util/qquicktimeline.cpp index b3f0caa2b3..ac9f75979e 100644 --- a/src/quick/util/qquicktimeline.cpp +++ b/src/quick/util/qquicktimeline.cpp @@ -57,7 +57,7 @@ struct Update { Update(QQuickTimeLineValue *_g, qreal _v) : g(_g), v(_v) {} Update(const QQuickTimeLineCallback &_e) - : g(0), v(0), e(_e) {} + : g(nullptr), v(0), e(_e) {} QQuickTimeLineValue *g; qreal v; @@ -104,11 +104,11 @@ struct QQuickTimeLinePrivate }; struct TimeLine { - TimeLine() : length(0), consumedOpLength(0), base(0.) {} + TimeLine() {} QList<Op> ops; - int length; - int consumedOpLength; - qreal base; + int length = 0; + int consumedOpLength = 0; + qreal base = 0.; }; int length; @@ -133,7 +133,7 @@ struct QQuickTimeLinePrivate }; QQuickTimeLinePrivate::QQuickTimeLinePrivate(QQuickTimeLine *parent) -: length(0), syncPoint(0), q(parent), clockRunning(false), prevTime(0), order(0), syncMode(QQuickTimeLine::LocalSync), syncAdj(0), updateQueue(0) +: length(0), syncPoint(0), q(parent), clockRunning(false), prevTime(0), order(0), syncMode(QQuickTimeLine::LocalSync), syncAdj(0), updateQueue(nullptr) { } @@ -326,9 +326,9 @@ QQuickTimeLine::~QQuickTimeLine() for (QQuickTimeLinePrivate::Ops::Iterator iter = d->ops.begin(); iter != d->ops.end(); ++iter) - iter.key()->_t = 0; + iter.key()->_t = nullptr; - delete d; d = 0; + delete d; d = nullptr; } /*! @@ -514,7 +514,7 @@ void QQuickTimeLine::reset(QQuickTimeLineValue &timeLineValue) return; } remove(&timeLineValue); - timeLineValue._t = 0; + timeLineValue._t = nullptr; } int QQuickTimeLine::duration() const @@ -666,7 +666,7 @@ void QQuickTimeLine::complete() void QQuickTimeLine::clear() { for (QQuickTimeLinePrivate::Ops::const_iterator iter = d->ops.cbegin(), cend = d->ops.cend(); iter != cend; ++iter) - iter.key()->_t = 0; + iter.key()->_t = nullptr; d->ops.clear(); d->length = 0; d->syncPoint = 0; @@ -800,7 +800,7 @@ int QQuickTimeLinePrivate::advance(int t) if (tl.ops.isEmpty()) { iter = ops.erase(iter); - v->_t = 0; + v->_t = nullptr; } else { if (tl.ops.first().type == Op::Pause && pauseTime != 0) { int opPauseTime = tl.ops.first().length - tl.consumedOpLength; @@ -826,7 +826,7 @@ int QQuickTimeLinePrivate::advance(int t) v.e.d0(v.e.d1); } } - updateQueue = 0; + updateQueue = nullptr; } while(t); return pauseTime; @@ -854,7 +854,7 @@ void QQuickTimeLine::remove(QQuickTimeLineObject *v) if (d->ops.isEmpty()) { stop(); d->clockRunning = false; - } else if (/*!GfxClock::isActive()*/ state() != Running) { + } else if (state() != Running) { // was !GfxClock::isActive() stop(); d->prevTime = 0; d->clockRunning = true; @@ -913,7 +913,7 @@ void QQuickTimeLine::remove(QQuickTimeLineObject *v) QQuickTimeLineObject::QQuickTimeLineObject() -: _t(0) +: _t(nullptr) { } @@ -921,12 +921,12 @@ QQuickTimeLineObject::~QQuickTimeLineObject() { if (_t) { _t->remove(this); - _t = 0; + _t = nullptr; } } QQuickTimeLineCallback::QQuickTimeLineCallback() -: d0(0), d1(0), d2(0) +: d0(nullptr), d1(nullptr), d2(nullptr) { } diff --git a/src/quick/util/qquicktimeline_p_p.h b/src/quick/util/qquicktimeline_p_p.h index ae1087487b..abb5369b7b 100644 --- a/src/quick/util/qquicktimeline_p_p.h +++ b/src/quick/util/qquicktimeline_p_p.h @@ -65,7 +65,7 @@ class Q_AUTOTEST_EXPORT QQuickTimeLine : public QObject, QAbstractAnimationJob { Q_OBJECT public: - QQuickTimeLine(QObject *parent = 0); + QQuickTimeLine(QObject *parent = nullptr); ~QQuickTimeLine(); enum SyncMode { LocalSync, GlobalSync }; @@ -152,7 +152,7 @@ public: typedef void (*Callback)(void *); QQuickTimeLineCallback(); - QQuickTimeLineCallback(QQuickTimeLineObject *b, Callback, void * = 0); + QQuickTimeLineCallback(QQuickTimeLineObject *b, Callback, void * = nullptr); QQuickTimeLineCallback(const QQuickTimeLineCallback &o); QQuickTimeLineCallback &operator=(const QQuickTimeLineCallback &o); @@ -170,7 +170,7 @@ class QQuickTimeLineValueProxy : public QQuickTimeLineValue { public: QQuickTimeLineValueProxy(T *cls, void (T::*func)(qreal), qreal v = 0.) - : QQuickTimeLineValue(v), _class(cls), _setFunctionReal(func), _setFunctionInt(0) + : QQuickTimeLineValue(v), _class(cls), _setFunctionReal(func), _setFunctionInt(nullptr) { Q_ASSERT(_class); } diff --git a/src/quick/util/qquicktransition.cpp b/src/quick/util/qquicktransition.cpp index 29690a4857..fd6415dffb 100644 --- a/src/quick/util/qquicktransition.cpp +++ b/src/quick/util/qquicktransition.cpp @@ -109,7 +109,7 @@ protected: void updateState(QAbstractAnimationJob::State newState, QAbstractAnimationJob::State oldState) override; }; -class QQuickTransitionPrivate : public QObjectPrivate, QAnimationJobChangeListener +class QQuickTransitionPrivate : public QObjectPrivate { Q_DECLARE_PUBLIC(QQuickTransition) public: @@ -120,11 +120,8 @@ public: { } - void removeStateChangeListener(QAbstractAnimationJob *anim) - { - if (anim) - anim->removeAnimationChangeListener(this, QAbstractAnimationJob::StateChange); - } + static QQuickTransitionPrivate *get(QQuickTransition *q) { return q->d_func(); } + void animationStateChanged(QAbstractAnimationJob::State newState); QString fromState; QString toState; @@ -134,7 +131,6 @@ public: bool reversible; bool enabled; protected: - void animationStateChanged(QAbstractAnimationJob *, QAbstractAnimationJob::State, QAbstractAnimationJob::State) override; static void append_animation(QQmlListProperty<QQuickAbstractAnimation> *list, QQuickAbstractAnimation *a); static int animation_count(QQmlListProperty<QQuickAbstractAnimation> *list); @@ -171,7 +167,16 @@ void QQuickTransitionPrivate::clear_animations(QQmlListProperty<QQuickAbstractAn } } -void QQuickTransitionPrivate::animationStateChanged(QAbstractAnimationJob *, QAbstractAnimationJob::State newState, QAbstractAnimationJob::State) +void QQuickTransitionInstance::animationStateChanged(QAbstractAnimationJob *, QAbstractAnimationJob::State newState, QAbstractAnimationJob::State) +{ + if (!m_transition) + return; + + QQuickTransitionPrivate *transition = QQuickTransitionPrivate::get(m_transition); + transition->animationStateChanged(newState); +} + +void QQuickTransitionPrivate::animationStateChanged(QAbstractAnimationJob::State newState) { Q_Q(QQuickTransition); @@ -197,15 +202,16 @@ void ParallelAnimationWrapper::updateState(QAbstractAnimationJob::State newState } } -QQuickTransitionInstance::QQuickTransitionInstance(QQuickTransitionPrivate *transition, QAbstractAnimationJob *anim) +QQuickTransitionInstance::QQuickTransitionInstance(QQuickTransition *transition, QAbstractAnimationJob *anim) : m_transition(transition) , m_anim(anim) { + anim->addAnimationChangeListener(this, QAbstractAnimationJob::StateChange); } QQuickTransitionInstance::~QQuickTransitionInstance() { - m_transition->removeStateChangeListener(m_anim); + removeStateChangeListener(); delete m_anim; } @@ -257,7 +263,7 @@ QQuickTransitionInstance *QQuickTransition::prepare(QQuickStateOperation::Action int start = d->reversed ? d->animations.count() - 1 : 0; int end = d->reversed ? -1 : d->animations.count(); - QAbstractAnimationJob *anim = 0; + QAbstractAnimationJob *anim = nullptr; for (int i = start; i != end;) { anim = d->animations.at(i)->transition(actions, after, direction, defaultTarget); if (anim) { @@ -270,8 +276,7 @@ QQuickTransitionInstance *QQuickTransition::prepare(QQuickStateOperation::Action group->setDirection(d->reversed ? QAbstractAnimationJob::Backward : QAbstractAnimationJob::Forward); - group->addAnimationChangeListener(d, QAbstractAnimationJob::StateChange); - QQuickTransitionInstance *wrapper = new QQuickTransitionInstance(d, group); + QQuickTransitionInstance *wrapper = new QQuickTransitionInstance(this, group); return wrapper; } diff --git a/src/quick/util/qquicktransition_p.h b/src/quick/util/qquicktransition_p.h index d6f365f99e..c7d06b8832 100644 --- a/src/quick/util/qquicktransition_p.h +++ b/src/quick/util/qquicktransition_p.h @@ -53,6 +53,7 @@ #include "qquickstate_p.h" #include <private/qabstractanimationjob_p.h> +#include <private/qqmlguard_p.h> #include <qqml.h> #include <QtCore/qobject.h> @@ -64,10 +65,10 @@ class QQuickTransitionPrivate; class QQuickTransitionManager; class QQuickTransition; -class QQuickTransitionInstance +class QQuickTransitionInstance : QAnimationJobChangeListener { public: - QQuickTransitionInstance(QQuickTransitionPrivate *transition, QAbstractAnimationJob *anim); + QQuickTransitionInstance(QQuickTransition *transition, QAbstractAnimationJob *anim); ~QQuickTransitionInstance(); void start(); @@ -75,8 +76,16 @@ public: bool isRunning() const; +protected: + void animationStateChanged(QAbstractAnimationJob *, QAbstractAnimationJob::State, QAbstractAnimationJob::State) override; + + void removeStateChangeListener() + { + m_anim->removeAnimationChangeListener(this, QAbstractAnimationJob::StateChange); + } + private: - QQuickTransitionPrivate *m_transition; + QQmlGuard<QQuickTransition> m_transition; QAbstractAnimationJob *m_anim; friend class QQuickTransition; }; @@ -96,7 +105,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickTransition : public QObject Q_CLASSINFO("DeferredPropertyNames", "animations") public: - QQuickTransition(QObject *parent=0); + QQuickTransition(QObject *parent=nullptr); ~QQuickTransition(); QString fromState() const; diff --git a/src/quick/util/qquicktransitionmanager.cpp b/src/quick/util/qquicktransitionmanager.cpp index 714e6d62b6..a1367249c6 100644 --- a/src/quick/util/qquicktransitionmanager.cpp +++ b/src/quick/util/qquicktransitionmanager.cpp @@ -56,7 +56,7 @@ class QQuickTransitionManagerPrivate { public: QQuickTransitionManagerPrivate() - : state(0), transitionInstance(0) {} + : state(nullptr), transitionInstance(nullptr) {} void applyBindings(); typedef QList<QQuickSimpleAction> SimpleActionList; @@ -79,7 +79,7 @@ void QQuickTransitionManager::setState(QQuickState *s) QQuickTransitionManager::~QQuickTransitionManager() { delete d->transitionInstance; - delete d; d = 0; + delete d; d = nullptr; } bool QQuickTransitionManager::isRunning() const @@ -274,7 +274,7 @@ void QQuickTransitionManager::cancel() QQuickStateAction action = d->bindingsList[i]; if (action.toBinding && action.deletableToBinding) { QQmlPropertyPrivate::removeBinding(action.property); - action.toBinding = 0; + action.toBinding = nullptr; action.deletableToBinding = false; } else if (action.event) { //### what do we do here? diff --git a/src/quick/util/qquicktransitionmanager_p_p.h b/src/quick/util/qquicktransitionmanager_p_p.h index 68daf6db3c..89317e1e07 100644 --- a/src/quick/util/qquicktransitionmanager_p_p.h +++ b/src/quick/util/qquicktransitionmanager_p_p.h @@ -66,7 +66,7 @@ public: bool isRunning() const; - void transition(const QList<QQuickStateAction> &, QQuickTransition *transition, QObject *defaultTarget = 0); + void transition(const QList<QQuickStateAction> &, QQuickTransition *transition, QObject *defaultTarget = nullptr); void cancel(); diff --git a/src/quick/util/qquickvalidator_p.h b/src/quick/util/qquickvalidator_p.h index ba188e947a..812e552d8e 100644 --- a/src/quick/util/qquickvalidator_p.h +++ b/src/quick/util/qquickvalidator_p.h @@ -62,7 +62,7 @@ class Q_AUTOTEST_EXPORT QQuickIntValidator : public QIntValidator Q_OBJECT Q_PROPERTY(QString locale READ localeName WRITE setLocaleName RESET resetLocaleName NOTIFY localeNameChanged) public: - QQuickIntValidator(QObject *parent = 0); + QQuickIntValidator(QObject *parent = nullptr); QString localeName() const; void setLocaleName(const QString &name); @@ -77,7 +77,7 @@ class Q_AUTOTEST_EXPORT QQuickDoubleValidator : public QDoubleValidator Q_OBJECT Q_PROPERTY(QString locale READ localeName WRITE setLocaleName RESET resetLocaleName NOTIFY localeNameChanged) public: - QQuickDoubleValidator(QObject *parent = 0); + QQuickDoubleValidator(QObject *parent = nullptr); QString localeName() const; void setLocaleName(const QString &name); |