diff options
Diffstat (limited to 'src/quicktemplates2')
33 files changed, 561 insertions, 67 deletions
diff --git a/src/quicktemplates2/qquickabstractbutton.cpp b/src/quicktemplates2/qquickabstractbutton.cpp index b8c6eb84..238669c6 100644 --- a/src/quicktemplates2/qquickabstractbutton.cpp +++ b/src/quicktemplates2/qquickabstractbutton.cpp @@ -355,13 +355,19 @@ void QQuickAbstractButtonPrivate::toggle(bool value) static inline QString indicatorName() { return QStringLiteral("indicator"); } +void QQuickAbstractButtonPrivate::cancelIndicator() +{ + Q_Q(QQuickAbstractButton); + quickCancelDeferred(q, indicatorName()); +} + void QQuickAbstractButtonPrivate::executeIndicator(bool complete) { - Q_Q(QQuickControl); + Q_Q(QQuickAbstractButton); if (indicator.wasExecuted()) return; - if (!indicator) + if (!indicator || complete) quickBeginDeferred(q, indicatorName(), indicator); if (complete) quickCompleteDeferred(q, indicatorName(), indicator); @@ -682,6 +688,9 @@ void QQuickAbstractButton::setIndicator(QQuickItem *indicator) if (d->indicator == indicator) return; + if (!d->indicator.isExecuting()) + d->cancelIndicator(); + delete d->indicator; d->indicator = indicator; if (indicator) { diff --git a/src/quicktemplates2/qquickabstractbutton_p_p.h b/src/quicktemplates2/qquickabstractbutton_p_p.h index d5afc4cf..1c493cd8 100644 --- a/src/quicktemplates2/qquickabstractbutton_p_p.h +++ b/src/quicktemplates2/qquickabstractbutton_p_p.h @@ -100,6 +100,7 @@ public: void trigger(); void toggle(bool value); + void cancelIndicator(); void executeIndicator(bool complete = false); QString text; diff --git a/src/quicktemplates2/qquickapplicationwindow.cpp b/src/quicktemplates2/qquickapplicationwindow.cpp index 94b0de98..687b4233 100644 --- a/src/quicktemplates2/qquickapplicationwindow.cpp +++ b/src/quicktemplates2/qquickapplicationwindow.cpp @@ -166,6 +166,7 @@ public: static void contentData_append(QQmlListProperty<QObject> *prop, QObject *obj); + void cancelBackground(); void executeBackground(bool complete = false); bool complete; @@ -334,13 +335,19 @@ void QQuickApplicationWindowPrivate::contentData_append(QQmlListProperty<QObject static inline QString backgroundName() { return QStringLiteral("background"); } +void QQuickApplicationWindowPrivate::cancelBackground() +{ + Q_Q(QQuickApplicationWindow); + quickCancelDeferred(q, backgroundName()); +} + void QQuickApplicationWindowPrivate::executeBackground(bool complete) { Q_Q(QQuickApplicationWindow); if (background.wasExecuted()) return; - if (!background) + if (!background || complete) quickBeginDeferred(q, backgroundName(), background); if (complete) quickCompleteDeferred(q, backgroundName(), background); @@ -404,6 +411,9 @@ void QQuickApplicationWindow::setBackground(QQuickItem *background) if (d->background == background) return; + if (!d->background.isExecuting()) + d->cancelBackground(); + delete d->background; d->background = background; if (background) { diff --git a/src/quicktemplates2/qquickcombobox.cpp b/src/quicktemplates2/qquickcombobox.cpp index 3b37900d..f1e05b7e 100644 --- a/src/quicktemplates2/qquickcombobox.cpp +++ b/src/quicktemplates2/qquickcombobox.cpp @@ -256,7 +256,10 @@ public: void handleRelease(const QPointF &point) override; void handleUngrab() override; + void cancelIndicator(); void executeIndicator(bool complete = false); + + void cancelPopup(); void executePopup(bool complete = false); bool flat; @@ -704,13 +707,19 @@ void QQuickComboBoxPrivate::handleUngrab() static inline QString indicatorName() { return QStringLiteral("indicator"); } +void QQuickComboBoxPrivate::cancelIndicator() +{ + Q_Q(QQuickComboBox); + quickCancelDeferred(q, indicatorName()); +} + void QQuickComboBoxPrivate::executeIndicator(bool complete) { Q_Q(QQuickComboBox); if (indicator.wasExecuted()) return; - if (!indicator) + if (!indicator || complete) quickBeginDeferred(q, indicatorName(), indicator); if (complete) quickCompleteDeferred(q, indicatorName(), indicator); @@ -718,13 +727,19 @@ void QQuickComboBoxPrivate::executeIndicator(bool complete) static inline QString popupName() { return QStringLiteral("popup"); } +void QQuickComboBoxPrivate::cancelPopup() +{ + Q_Q(QQuickComboBox); + quickCancelDeferred(q, popupName()); +} + void QQuickComboBoxPrivate::executePopup(bool complete) { Q_Q(QQuickComboBox); if (popup.wasExecuted()) return; - if (!popup) + if (!popup || complete) quickBeginDeferred(q, popupName(), popup); if (complete) quickCompleteDeferred(q, popupName(), popup); @@ -1048,6 +1063,9 @@ void QQuickComboBox::setIndicator(QQuickItem *indicator) if (d->indicator == indicator) return; + if (!d->indicator.isExecuting()) + d->cancelIndicator(); + delete d->indicator; d->indicator = indicator; if (indicator) { @@ -1085,6 +1103,9 @@ void QQuickComboBox::setPopup(QQuickPopup *popup) if (d->popup == popup) return; + if (!d->popup.isExecuting()) + d->cancelPopup(); + if (d->popup) { QObjectPrivate::disconnect(d->popup.data(), &QQuickPopup::visibleChanged, d, &QQuickComboBoxPrivate::popupVisibleChanged); delete d->popup; diff --git a/src/quicktemplates2/qquickcontrol.cpp b/src/quicktemplates2/qquickcontrol.cpp index 950ec384..9bb122fe 100644 --- a/src/quicktemplates2/qquickcontrol.cpp +++ b/src/quicktemplates2/qquickcontrol.cpp @@ -52,7 +52,6 @@ #include <QtGui/private/qguiapplication_p.h> #include <QtGui/qpa/qplatformtheme.h> -#include <QtQml/private/qqmlincubator_p.h> #if QT_CONFIG(accessibility) #include <QtQuick/private/qquickaccessibleattached_p.h> @@ -291,6 +290,9 @@ void QQuickControlPrivate::setContentItem_helper(QQuickItem *item, bool notify) if (contentItem == item) return; + if (!contentItem.isExecuting()) + cancelContentItem(); + q->contentItemChange(item, contentItem); delete contentItem; contentItem = item; @@ -649,13 +651,19 @@ bool QQuickControlPrivate::calcHoverEnabled(const QQuickItem *item) static inline QString contentItemName() { return QStringLiteral("contentItem"); } +void QQuickControlPrivate::cancelContentItem() +{ + Q_Q(QQuickControl); + quickCancelDeferred(q, contentItemName()); +} + void QQuickControlPrivate::executeContentItem(bool complete) { Q_Q(QQuickControl); if (contentItem.wasExecuted()) return; - if (!contentItem) + if (!contentItem || complete) quickBeginDeferred(q, contentItemName(), contentItem); if (complete) quickCompleteDeferred(q, contentItemName(), contentItem); @@ -663,40 +671,24 @@ void QQuickControlPrivate::executeContentItem(bool complete) static inline QString backgroundName() { return QStringLiteral("background"); } +void QQuickControlPrivate::cancelBackground() +{ + Q_Q(QQuickControl); + quickCancelDeferred(q, backgroundName()); +} + void QQuickControlPrivate::executeBackground(bool complete) { Q_Q(QQuickControl); if (background.wasExecuted()) return; - if (!background) + if (!background || complete) quickBeginDeferred(q, backgroundName(), background); if (complete) quickCompleteDeferred(q, backgroundName(), background); } -/* - Cancels incubation recursively to avoid "Object destroyed during incubation" (QTBUG-50992) -*/ -static void cancelIncubation(QObject *object, QQmlContext *context) -{ - const auto children = object->children(); - for (QObject *child : children) - cancelIncubation(child, context); - QQmlIncubatorPrivate::cancel(object, context); -} - -void QQuickControlPrivate::destroyDelegate(QObject *delegate, QObject *parent) -{ - if (!delegate) - return; - - QQmlContext *context = parent ? qmlContext(parent) : nullptr; - if (context) - cancelIncubation(delegate, context); - delete delegate; -} - QQuickControl::QQuickControl(QQuickItem *parent) : QQuickItem(*(new QQuickControlPrivate), parent) { @@ -1313,6 +1305,9 @@ void QQuickControl::setBackground(QQuickItem *background) if (d->background == background) return; + if (!d->background.isExecuting()) + d->cancelBackground(); + delete d->background; d->background = background; if (background) { diff --git a/src/quicktemplates2/qquickcontrol_p_p.h b/src/quicktemplates2/qquickcontrol_p_p.h index f159c96d..7d040ded 100644 --- a/src/quicktemplates2/qquickcontrol_p_p.h +++ b/src/quicktemplates2/qquickcontrol_p_p.h @@ -140,10 +140,11 @@ public: static bool calcHoverEnabled(const QQuickItem *item); #endif - void executeContentItem(bool complete = false); - void executeBackground(bool complete = false); + virtual void cancelContentItem(); + virtual void executeContentItem(bool complete = false); - static void destroyDelegate(QObject *object, QObject *parent); + virtual void cancelBackground(); + virtual void executeBackground(bool complete = false); struct ExtraData { ExtraData(); diff --git a/src/quicktemplates2/qquickdeferredexecute.cpp b/src/quicktemplates2/qquickdeferredexecute.cpp index 802ed3d0..ca6953bc 100644 --- a/src/quicktemplates2/qquickdeferredexecute.cpp +++ b/src/quicktemplates2/qquickdeferredexecute.cpp @@ -55,13 +55,24 @@ static inline uint qHash(QObject *object, const QString &propertyName) Q_GLOBAL_STATIC(DeferredStates, deferredStates) -static void beginDeferred(QQmlEnginePrivate *enginePriv, const QQmlProperty &property, QQmlComponentPrivate::DeferredState *deferredState) +static void cancelDeferred(QObject *object, int propertyIndex) +{ + QQmlData *ddata = QQmlData::get(object); + auto dit = ddata->deferredData.rbegin(); + while (dit != ddata->deferredData.rend()) { + (*dit)->bindings.remove(propertyIndex); + ++dit; + } +} + +static bool beginDeferred(QQmlEnginePrivate *enginePriv, const QQmlProperty &property, QQmlComponentPrivate::DeferredState *deferredState) { QObject *object = property.object(); QQmlData *ddata = QQmlData::get(object); Q_ASSERT(!ddata->deferredData.isEmpty()); int propertyIndex = property.index(); + int wasInProgress = enginePriv->inProgressCreations; for (auto dit = ddata->deferredData.rbegin(); dit != ddata->deferredData.rend(); ++dit) { QQmlData::DeferredData *deferData = *dit; @@ -91,12 +102,11 @@ static void beginDeferred(QQmlEnginePrivate *enginePriv, const QQmlProperty &pro // Cleanup any remaining deferred bindings for this property, also in inner contexts, // to avoid executing them later and overriding the property that was just populated. - while (dit != ddata->deferredData.rend()) { - (*dit)->bindings.remove(propertyIndex); - ++dit; - } + cancelDeferred(object, propertyIndex); break; } + + return enginePriv->inProgressCreations > wasInProgress; } void beginDeferred(QObject *object, const QString &property) @@ -106,15 +116,21 @@ void beginDeferred(QObject *object, const QString &property) QQmlEnginePrivate *ep = QQmlEnginePrivate::get(data->context->engine); QQmlComponentPrivate::DeferredState *state = new QQmlComponentPrivate::DeferredState; - beginDeferred(ep, QQmlProperty(object, property), state); + if (beginDeferred(ep, QQmlProperty(object, property), state)) + deferredStates()->insert(qHash(object, property), state); + else + delete state; // Release deferred data for those compilation units that no longer have deferred bindings data->releaseDeferredData(); - - deferredStates()->insert(qHash(object, property), state); } } +void cancelDeferred(QObject *object, const QString &property) +{ + cancelDeferred(object, QQmlProperty(object, property).index()); +} + void completeDeferred(QObject *object, const QString &property) { QQmlData *data = QQmlData::get(object); diff --git a/src/quicktemplates2/qquickdeferredexecute_p_p.h b/src/quicktemplates2/qquickdeferredexecute_p_p.h index 87124e48..400c5734 100644 --- a/src/quicktemplates2/qquickdeferredexecute_p_p.h +++ b/src/quicktemplates2/qquickdeferredexecute_p_p.h @@ -58,25 +58,28 @@ class QObject; namespace QtQuickPrivate { void beginDeferred(QObject *object, const QString &property); + void cancelDeferred(QObject *object, const QString &property); void completeDeferred(QObject *object, const QString &property); } template<typename T> void quickBeginDeferred(QObject *object, const QString &property, QQuickDeferredPointer<T> &delegate) { - Q_ASSERT(delegate.isNull()); delegate.setExecuting(true); QtQuickPrivate::beginDeferred(object, property); delegate.setExecuting(false); } +inline void quickCancelDeferred(QObject *object, const QString &property) +{ + QtQuickPrivate::cancelDeferred(object, property); +} + template<typename T> void quickCompleteDeferred(QObject *object, const QString &property, QQuickDeferredPointer<T> &delegate) { Q_ASSERT(!delegate.wasExecuted()); - delegate.setExecuting(true); QtQuickPrivate::completeDeferred(object, property); - delegate.setExecuting(false); delegate.setExecuted(); } diff --git a/src/quicktemplates2/qquickdial.cpp b/src/quicktemplates2/qquickdial.cpp index 964cefe1..b5957069 100644 --- a/src/quicktemplates2/qquickdial.cpp +++ b/src/quicktemplates2/qquickdial.cpp @@ -123,6 +123,7 @@ public: void handleRelease(const QPointF &point) override; void handleUngrab() override; + void cancelHandle(); void executeHandle(bool complete = false); qreal from; @@ -258,13 +259,19 @@ void QQuickDialPrivate::handleUngrab() static inline QString handleName() { return QStringLiteral("handle"); } +void QQuickDialPrivate::cancelHandle() +{ + Q_Q(QQuickDial); + quickCancelDeferred(q, handleName()); +} + void QQuickDialPrivate::executeHandle(bool complete) { Q_Q(QQuickDial); if (handle.wasExecuted()) return; - if (!handle) + if (!handle || complete) quickBeginDeferred(q, handleName(), handle); if (complete) quickCompleteDeferred(q, handleName(), handle); @@ -553,6 +560,9 @@ void QQuickDial::setHandle(QQuickItem *handle) if (handle == d->handle) return; + if (!d->handle.isExecuting()) + d->cancelHandle(); + delete d->handle; d->handle = handle; if (d->handle && !d->handle->parentItem()) diff --git a/src/quicktemplates2/qquickdrawer.cpp b/src/quicktemplates2/qquickdrawer.cpp index 022c9dbf..202d02d1 100644 --- a/src/quicktemplates2/qquickdrawer.cpp +++ b/src/quicktemplates2/qquickdrawer.cpp @@ -79,6 +79,11 @@ QT_BEGIN_NAMESPACE id: drawer width: 0.66 * window.width height: window.height + + Label { + text: "Content goes here!" + anchors.centerIn: parent + } } } \endcode diff --git a/src/quicktemplates2/qquickgroupbox.cpp b/src/quicktemplates2/qquickgroupbox.cpp index c127192c..4f4c5eed 100644 --- a/src/quicktemplates2/qquickgroupbox.cpp +++ b/src/quicktemplates2/qquickgroupbox.cpp @@ -91,6 +91,7 @@ class QQuickGroupBoxPrivate : public QQuickFramePrivate public: QQuickGroupBoxPrivate() : label(nullptr) { } + void cancelLabel(); void executeLabel(bool complete = false); QString title; @@ -99,13 +100,19 @@ public: static inline QString labelName() { return QStringLiteral("label"); } +void QQuickGroupBoxPrivate::cancelLabel() +{ + Q_Q(QQuickGroupBox); + quickCancelDeferred(q, labelName()); +} + void QQuickGroupBoxPrivate::executeLabel(bool complete) { Q_Q(QQuickGroupBox); if (label.wasExecuted()) return; - if (!label) + if (!label || complete) quickBeginDeferred(q, labelName(), label); if (complete) quickCompleteDeferred(q, labelName(), label); @@ -162,6 +169,9 @@ void QQuickGroupBox::setLabel(QQuickItem *label) if (d->label == label) return; + if (!d->label.isExecuting()) + d->cancelLabel(); + delete d->label; d->label = label; if (label && !label->parentItem()) diff --git a/src/quicktemplates2/qquicklabel.cpp b/src/quicktemplates2/qquicklabel.cpp index d27393ae..41b2d93a 100644 --- a/src/quicktemplates2/qquicklabel.cpp +++ b/src/quicktemplates2/qquicklabel.cpp @@ -205,13 +205,19 @@ QAccessible::Role QQuickLabelPrivate::accessibleRole() const static inline QString backgroundName() { return QStringLiteral("background"); } +void QQuickLabelPrivate::cancelBackground() +{ + Q_Q(QQuickLabel); + quickCancelDeferred(q, backgroundName()); +} + void QQuickLabelPrivate::executeBackground(bool complete) { Q_Q(QQuickLabel); if (background.wasExecuted()) return; - if (!background) + if (!background || complete) quickBeginDeferred(q, backgroundName(), background); if (complete) quickCompleteDeferred(q, backgroundName(), background); @@ -264,6 +270,9 @@ void QQuickLabel::setBackground(QQuickItem *background) if (d->background == background) return; + if (!d->background.isExecuting()) + d->cancelBackground(); + delete d->background; d->background = background; if (background) { diff --git a/src/quicktemplates2/qquicklabel_p_p.h b/src/quicktemplates2/qquicklabel_p_p.h index 5f432a22..bcd1aca6 100644 --- a/src/quicktemplates2/qquicklabel_p_p.h +++ b/src/quicktemplates2/qquicklabel_p_p.h @@ -99,6 +99,7 @@ public: QAccessible::Role accessibleRole() const override; #endif + void cancelBackground(); void executeBackground(bool complete = false); struct ExtraData { diff --git a/src/quicktemplates2/qquickmenu.cpp b/src/quicktemplates2/qquickmenu.cpp index 7ebeb344..5dbfe3d9 100644 --- a/src/quicktemplates2/qquickmenu.cpp +++ b/src/quicktemplates2/qquickmenu.cpp @@ -1013,6 +1013,9 @@ QVariant QQuickMenu::contentModel() const */ QQmlListProperty<QObject> QQuickMenu::contentData() { + Q_D(QQuickMenu); + if (!d->contentItem) + QQuickControlPrivate::get(d->popupItem)->executeContentItem(); return QQmlListProperty<QObject>(this, nullptr, QQuickMenuPrivate::contentData_append, QQuickMenuPrivate::contentData_count, diff --git a/src/quicktemplates2/qquickmenuitem.cpp b/src/quicktemplates2/qquickmenuitem.cpp index f71b9c35..6693d4f8 100644 --- a/src/quicktemplates2/qquickmenuitem.cpp +++ b/src/quicktemplates2/qquickmenuitem.cpp @@ -37,6 +37,7 @@ #include "qquickmenuitem_p.h" #include "qquickmenuitem_p_p.h" #include "qquickmenu_p.h" +#include "qquickdeferredexecute_p_p.h" #include <QtGui/qpa/qplatformtheme.h> #include <QtQuick/private/qquickevents_p_p.h> @@ -134,6 +135,26 @@ void QQuickMenuItemPrivate::updateEnabled() q->setEnabled(subMenu && subMenu->isEnabled()); } +static inline QString arrowName() { return QStringLiteral("arrow"); } + +void QQuickMenuItemPrivate::cancelArrow() +{ + Q_Q(QQuickAbstractButton); + quickCancelDeferred(q, arrowName()); +} + +void QQuickMenuItemPrivate::executeArrow(bool complete) +{ + Q_Q(QQuickMenuItem); + if (arrow.wasExecuted()) + return; + + if (!arrow || complete) + quickBeginDeferred(q, arrowName(), arrow); + if (complete) + quickCompleteDeferred(q, arrowName(), arrow); +} + /*! \qmlsignal void QtQuick.Controls::MenuItem::triggered() @@ -183,7 +204,9 @@ void QQuickMenuItem::setHighlighted(bool highlighted) */ QQuickItem *QQuickMenuItem::arrow() const { - Q_D(const QQuickMenuItem); + QQuickMenuItemPrivate *d = const_cast<QQuickMenuItemPrivate *>(d_func()); + if (!d->arrow) + d->executeArrow(); return d->arrow; } @@ -193,11 +216,15 @@ void QQuickMenuItem::setArrow(QQuickItem *arrow) if (d->arrow == arrow) return; - QQuickControlPrivate::destroyDelegate(d->arrow, this); + if (!d->arrow.isExecuting()) + d->cancelArrow(); + + delete d->arrow; d->arrow = arrow; if (arrow && !arrow->parentItem()) arrow->setParentItem(this); - emit arrowChanged(); + if (!d->arrow.isExecuting()) + emit arrowChanged(); } /*! @@ -228,6 +255,13 @@ QQuickMenu *QQuickMenuItem::subMenu() const return d->subMenu; } +void QQuickMenuItem::componentComplete() +{ + Q_D(QQuickMenuItem); + d->executeArrow(true); + QQuickAbstractButton::componentComplete(); +} + QFont QQuickMenuItem::defaultFont() const { return QQuickControlPrivate::themeFont(QPlatformTheme::MenuItemFont); diff --git a/src/quicktemplates2/qquickmenuitem_p.h b/src/quicktemplates2/qquickmenuitem_p.h index 8af3cbd1..7cffd97b 100644 --- a/src/quicktemplates2/qquickmenuitem_p.h +++ b/src/quicktemplates2/qquickmenuitem_p.h @@ -63,6 +63,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickMenuItem : public QQuickAbstractBut Q_PROPERTY(QQuickItem *arrow READ arrow WRITE setArrow NOTIFY arrowChanged FINAL REVISION 3) Q_PROPERTY(QQuickMenu *menu READ menu NOTIFY menuChanged FINAL REVISION 3) Q_PROPERTY(QQuickMenu *subMenu READ subMenu NOTIFY subMenuChanged FINAL REVISION 3) + Q_CLASSINFO("DeferredPropertyNames", "arrow,background,contentItem,indicator") public: explicit QQuickMenuItem(QQuickItem *parent = nullptr); @@ -86,6 +87,8 @@ Q_SIGNALS: Q_REVISION(3) void subMenuChanged(); protected: + void componentComplete() override; + QFont defaultFont() const override; QPalette defaultPalette() const override; diff --git a/src/quicktemplates2/qquickmenuitem_p_p.h b/src/quicktemplates2/qquickmenuitem_p_p.h index e0e90ff1..5deea6e3 100644 --- a/src/quicktemplates2/qquickmenuitem_p_p.h +++ b/src/quicktemplates2/qquickmenuitem_p_p.h @@ -72,8 +72,11 @@ public: void updateEnabled(); + void cancelArrow(); + void executeArrow(bool complete = false); + bool highlighted; - QQuickItem *arrow; + QQuickDeferredPointer<QQuickItem> arrow; QQuickMenu *menu; QQuickMenu *subMenu; }; diff --git a/src/quicktemplates2/qquickpagelayout.cpp b/src/quicktemplates2/qquickpagelayout.cpp index 99d4fe23..595db560 100644 --- a/src/quicktemplates2/qquickpagelayout.cpp +++ b/src/quicktemplates2/qquickpagelayout.cpp @@ -36,6 +36,7 @@ #include "qquickpagelayout_p_p.h" #include "qquickcontrol_p.h" +#include "qquickcontrol_p_p.h" #include "qquicktoolbar_p.h" #include "qquicktabbar_p.h" #include "qquickdialogbuttonbox_p.h" @@ -140,17 +141,19 @@ bool QQuickPageLayout::setFooter(QQuickItem *footer) void QQuickPageLayout::update() { - QQuickItem *content = m_control->contentItem(); + QQuickItem *content = QQuickControlPrivate::get(m_control)->contentItem; const qreal hh = m_header && m_header->isVisible() ? m_header->height() : 0; const qreal fh = m_footer && m_footer->isVisible() ? m_footer->height() : 0; const qreal hsp = hh > 0 ? m_control->spacing() : 0; const qreal fsp = fh > 0 ? m_control->spacing() : 0; - content->setY(m_control->topPadding() + hh + hsp); - content->setX(m_control->leftPadding()); - content->setWidth(m_control->availableWidth()); - content->setHeight(m_control->availableHeight() - hh - fh - hsp - fsp); + if (content) { + content->setY(m_control->topPadding() + hh + hsp); + content->setX(m_control->leftPadding()); + content->setWidth(m_control->availableWidth()); + content->setHeight(m_control->availableHeight() - hh - fh - hsp - fsp); + } if (m_header) m_header->setWidth(m_control->width()); diff --git a/src/quicktemplates2/qquickpaletteprovider.cpp b/src/quicktemplates2/qquickpaletteprovider.cpp new file mode 100644 index 00000000..d925fcae --- /dev/null +++ b/src/quicktemplates2/qquickpaletteprovider.cpp @@ -0,0 +1,175 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickpaletteprovider_p.h" +#include "qquickpalette_p.h" + +#include <QtQml/private/qqmlvaluetype_p.h> + +QT_BEGIN_NAMESPACE + +static QQmlValueTypeProvider *instance() +{ + static QQuickPaletteProvider provider; + return &provider; +} + +void QQuickPaletteProvider::init() +{ + QQml_addValueTypeProvider(instance()); +} + +void QQuickPaletteProvider::cleanup() +{ + QQml_removeValueTypeProvider(instance()); +} + +#if defined(QT_NO_DEBUG) && !defined(QT_FORCE_ASSERTS) + #define ASSERT_VALID_SIZE(size, min) Q_UNUSED(size) +#else + #define ASSERT_VALID_SIZE(size, min) Q_ASSERT(size >= min) +#endif + +const QMetaObject *QQuickPaletteProvider::getMetaObjectForMetaType(int type) +{ + switch (type) { + case QMetaType::QPalette: + return &QQuickPalette::staticMetaObject; + default: + break; + } + + return nullptr; +} + +bool QQuickPaletteProvider::init(int type, QVariant& dst) +{ + switch (type) { + case QMetaType::QPalette: + dst.setValue<QPalette>(QPalette()); + return true; + default: break; + } + + return false; +} + +template<typename T> +bool typedEqual(const void *lhs, const QVariant& rhs) +{ + return (*(reinterpret_cast<const T *>(lhs)) == rhs.value<T>()); +} + +bool QQuickPaletteProvider::equal(int type, const void *lhs, const QVariant &rhs) +{ + switch (type) { + case QMetaType::QPalette: + return typedEqual<QPalette>(lhs, rhs); + default: break; + } + + return false; +} + +template<typename T> +bool typedStore(const void *src, void *dst, size_t dstSize) +{ + ASSERT_VALID_SIZE(dstSize, sizeof(T)); + const T *srcT = reinterpret_cast<const T *>(src); + T *dstT = reinterpret_cast<T *>(dst); + new (dstT) T(*srcT); + return true; +} + +bool QQuickPaletteProvider::store(int type, const void *src, void *dst, size_t dstSize) +{ + switch (type) { + case QMetaType::QPalette: + return typedStore<QPalette>(src, dst, dstSize); + default: break; + } + + return false; +} + +template<typename T> +bool typedRead(const QVariant& src, int dstType, void *dst) +{ + T *dstT = reinterpret_cast<T *>(dst); + if (src.type() == static_cast<uint>(dstType)) { + *dstT = src.value<T>(); + } else { + *dstT = T(); + } + return true; +} + +bool QQuickPaletteProvider::read(const QVariant &src, void *dst, int dstType) +{ + switch (dstType) { + case QMetaType::QPalette: + return typedRead<QPalette>(src, dstType, dst); + default: break; + } + + return false; +} + +template<typename T> +bool typedWrite(const void *src, QVariant& dst) +{ + const T *srcT = reinterpret_cast<const T *>(src); + if (dst.value<T>() != *srcT) { + dst = *srcT; + return true; + } + return false; +} + +bool QQuickPaletteProvider::write(int type, const void *src, QVariant& dst) +{ + switch (type) { + case QMetaType::QPalette: + return typedWrite<QPalette>(src, dst); + default: break; + } + + return false; +} + +#undef ASSERT_VALID_SIZE + +QT_END_NAMESPACE diff --git a/src/quicktemplates2/qquickpaletteprovider_p.h b/src/quicktemplates2/qquickpaletteprovider_p.h new file mode 100644 index 00000000..5b6e3796 --- /dev/null +++ b/src/quicktemplates2/qquickpaletteprovider_p.h @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKPALETTEPROVIDER_P_H +#define QQUICKPALETTEPROVIDER_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 <QtQuickTemplates2/private/qtquicktemplates2global_p.h> +#include <QtQml/private/qqmlglobal_p.h> + +QT_BEGIN_NAMESPACE + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickPaletteProvider : public QQmlValueTypeProvider +{ +public: + static void init(); + static void cleanup(); + + const QMetaObject *getMetaObjectForMetaType(int type) override; + bool init(int type, QVariant& dst) override; + bool equal(int type, const void *lhs, const QVariant &rhs) override; + bool store(int type, const void *src, void *dst, size_t dstSize) override; + bool read(const QVariant &src, void *dst, int dstType) override; + bool write(int type, const void *src, QVariant& dst) override; +}; + +QT_END_NAMESPACE + +#endif // QQUICKTEMPLATES2VALUETYPEPROVIDER_P_H diff --git a/src/quicktemplates2/qquickpopup.cpp b/src/quicktemplates2/qquickpopup.cpp index 472d2124..1a4c90a4 100644 --- a/src/quicktemplates2/qquickpopup.cpp +++ b/src/quicktemplates2/qquickpopup.cpp @@ -265,6 +265,7 @@ void QQuickPopupPrivate::init() q->setParentItem(qobject_cast<QQuickItem *>(parent)); QObject::connect(popupItem, &QQuickItem::enabledChanged, q, &QQuickPopup::enabledChanged); QObject::connect(popupItem, &QQuickControl::paddingChanged, q, &QQuickPopup::paddingChanged); + QObject::connect(popupItem, &QQuickControl::backgroundChanged, q, &QQuickPopup::backgroundChanged); QObject::connect(popupItem, &QQuickControl::contentItemChanged, q, &QQuickPopup::contentItemChanged); positioner = new QQuickPopupPositioner(q); } @@ -1605,11 +1606,7 @@ QQuickItem *QQuickPopup::background() const void QQuickPopup::setBackground(QQuickItem *background) { Q_D(QQuickPopup); - if (d->popupItem->background() == background) - return; - d->popupItem->setBackground(background); - emit backgroundChanged(); } /*! @@ -1662,6 +1659,9 @@ void QQuickPopup::setContentItem(QQuickItem *item) QQmlListProperty<QObject> QQuickPopup::contentData() { Q_D(QQuickPopup); + QQuickControlPrivate *p = QQuickControlPrivate::get(d->popupItem); + if (!p->contentItem) + p->executeContentItem(); return QQmlListProperty<QObject>(d->popupItem->contentItem(), nullptr, QQuickItemPrivate::data_append, QQuickItemPrivate::data_count, @@ -2110,6 +2110,9 @@ void QQuickPopup::classBegin() { Q_D(QQuickPopup); d->complete = false; + QQmlContext *context = qmlContext(this); + if (context) + QQmlEngine::setContextForObject(d->popupItem, context); d->popupItem->classBegin(); } diff --git a/src/quicktemplates2/qquickpopup_p.h b/src/quicktemplates2/qquickpopup_p.h index ada4b649..2a42ff27 100644 --- a/src/quicktemplates2/qquickpopup_p.h +++ b/src/quicktemplates2/qquickpopup_p.h @@ -121,6 +121,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickPopup : public QObject, public QQml Q_PROPERTY(bool mirrored READ isMirrored NOTIFY mirroredChanged FINAL REVISION 3) Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged FINAL REVISION 3) Q_PROPERTY(QPalette palette READ palette WRITE setPalette RESET resetPalette NOTIFY paletteChanged FINAL REVISION 3) + Q_CLASSINFO("DeferredPropertyNames", "background,contentItem") Q_CLASSINFO("DefaultProperty", "contentData") public: diff --git a/src/quicktemplates2/qquickpopupitem.cpp b/src/quicktemplates2/qquickpopupitem.cpp index af4d03a4..566a5245 100644 --- a/src/quicktemplates2/qquickpopupitem.cpp +++ b/src/quicktemplates2/qquickpopupitem.cpp @@ -39,6 +39,7 @@ #include "qquickshortcutcontext_p_p.h" #include "qquickcontrol_p_p.h" #include "qquickpopup_p_p.h" +#include "qquickdeferredexecute_p_p.h" #include <QtGui/private/qshortcutmap_p.h> #include <QtGui/private/qguiapplication_p.h> @@ -60,6 +61,12 @@ public: QQuickItem *getContentItem() override; + void cancelContentItem() override; + void executeContentItem(bool complete = false) override; + + void cancelBackground() override; + void executeBackground(bool complete = false) override; + int backId; int escapeId; QQuickPopup *popup; @@ -109,6 +116,42 @@ QQuickItem *QQuickPopupItemPrivate::getContentItem() return new QQuickItem(q); } +static inline QString contentItemName() { return QStringLiteral("contentItem"); } + +void QQuickPopupItemPrivate::cancelContentItem() +{ + quickCancelDeferred(popup, contentItemName()); +} + +void QQuickPopupItemPrivate::executeContentItem(bool complete) +{ + if (contentItem.wasExecuted()) + return; + + if (!contentItem || complete) + quickBeginDeferred(popup, contentItemName(), contentItem); + if (complete) + quickCompleteDeferred(popup, contentItemName(), contentItem); +} + +static inline QString backgroundName() { return QStringLiteral("background"); } + +void QQuickPopupItemPrivate::cancelBackground() +{ + quickCancelDeferred(popup, backgroundName()); +} + +void QQuickPopupItemPrivate::executeBackground(bool complete) +{ + if (background.wasExecuted()) + return; + + if (!background || complete) + quickBeginDeferred(popup, backgroundName(), background); + if (complete) + quickCompleteDeferred(popup, backgroundName(), background); +} + QQuickPopupItem::QQuickPopupItem(QQuickPopup *popup) : QQuickControl(*(new QQuickPopupItemPrivate(popup)), nullptr) { diff --git a/src/quicktemplates2/qquickrangeslider.cpp b/src/quicktemplates2/qquickrangeslider.cpp index 937de9c9..075306cf 100644 --- a/src/quicktemplates2/qquickrangeslider.cpp +++ b/src/quicktemplates2/qquickrangeslider.cpp @@ -110,6 +110,7 @@ public: void setPosition(qreal position, bool ignoreOtherPosition = false); void updatePosition(bool ignoreOtherPosition = false); + void cancelHandle(); void executeHandle(bool complete = false); static QQuickRangeSliderNodePrivate *get(QQuickRangeSliderNode *node); @@ -154,13 +155,19 @@ void QQuickRangeSliderNodePrivate::updatePosition(bool ignoreOtherPosition) static inline QString handleName() { return QStringLiteral("handle"); } +void QQuickRangeSliderNodePrivate::cancelHandle() +{ + Q_Q(QQuickRangeSliderNode); + quickCancelDeferred(q, handleName()); +} + void QQuickRangeSliderNodePrivate::executeHandle(bool complete) { Q_Q(QQuickRangeSliderNode); if (handle.wasExecuted()) return; - if (!handle) + if (!handle || complete) quickBeginDeferred(q, handleName(), handle); if (complete) quickCompleteDeferred(q, handleName(), handle); @@ -256,14 +263,17 @@ void QQuickRangeSliderNode::setHandle(QQuickItem *handle) if (d->handle == handle) return; + if (!d->handle.isExecuting()) + d->cancelHandle(); + delete d->handle; d->handle = handle; if (handle) { if (!handle->parentItem()) handle->setParentItem(d->slider); - QQuickItem *firstHandle = d->slider->first()->handle(); - QQuickItem *secondHandle = d->slider->second()->handle(); + QQuickItem *firstHandle = QQuickRangeSliderNodePrivate::get(d->slider->first())->handle; + QQuickItem *secondHandle = QQuickRangeSliderNodePrivate::get(d->slider->second())->handle; if (firstHandle && secondHandle) { // The order of property assignments in QML is undefined, // but we need the first handle to be before the second due diff --git a/src/quicktemplates2/qquickslider.cpp b/src/quicktemplates2/qquickslider.cpp index 21aeda39..ef2077af 100644 --- a/src/quicktemplates2/qquickslider.cpp +++ b/src/quicktemplates2/qquickslider.cpp @@ -113,6 +113,7 @@ public: void handleRelease(const QPointF &point) override; void handleUngrab() override; + void cancelHandle(); void executeHandle(bool complete = false); qreal from; @@ -240,13 +241,19 @@ void QQuickSliderPrivate::handleUngrab() static inline QString handleName() { return QStringLiteral("handle"); } +void QQuickSliderPrivate::cancelHandle() +{ + Q_Q(QQuickSlider); + quickCancelDeferred(q, handleName()); +} + void QQuickSliderPrivate::executeHandle(bool complete) { Q_Q(QQuickSlider); if (handle.wasExecuted()) return; - if (!handle) + if (!handle || complete) quickBeginDeferred(q, handleName(), handle); if (complete) quickCompleteDeferred(q, handleName(), handle); @@ -546,6 +553,9 @@ void QQuickSlider::setHandle(QQuickItem *handle) if (d->handle == handle) return; + if (!d->handle.isExecuting()) + d->cancelHandle(); + delete d->handle; d->handle = handle; if (handle && !handle->parentItem()) diff --git a/src/quicktemplates2/qquickspinbox.cpp b/src/quicktemplates2/qquickspinbox.cpp index f7af2015..5e74f6ef 100644 --- a/src/quicktemplates2/qquickspinbox.cpp +++ b/src/quicktemplates2/qquickspinbox.cpp @@ -184,6 +184,7 @@ public: return button->d_func(); } + void cancelIndicator(); void executeIndicator(bool complete = false); bool pressed; @@ -1048,13 +1049,19 @@ void QQuickSpinBox::accessibilityActiveChanged(bool active) static inline QString indicatorName() { return QStringLiteral("indicator"); } +void QQuickSpinButtonPrivate::cancelIndicator() +{ + Q_Q(QQuickSpinButton); + quickCancelDeferred(q, indicatorName()); +} + void QQuickSpinButtonPrivate::executeIndicator(bool complete) { Q_Q(QQuickSpinButton); if (indicator.wasExecuted()) return; - if (!indicator) + if (!indicator || complete) quickBeginDeferred(q, indicatorName(), indicator); if (complete) quickCompleteDeferred(q, indicatorName(), indicator); @@ -1095,6 +1102,9 @@ void QQuickSpinButton::setIndicator(QQuickItem *indicator) if (d->indicator == indicator) return; + if (!d->indicator.isExecuting()) + d->cancelIndicator(); + delete d->indicator; d->indicator = indicator; diff --git a/src/quicktemplates2/qquickstackview.cpp b/src/quicktemplates2/qquickstackview.cpp index 2f13b1a1..2aa41c0d 100644 --- a/src/quicktemplates2/qquickstackview.cpp +++ b/src/quicktemplates2/qquickstackview.cpp @@ -1068,6 +1068,13 @@ bool QQuickStackView::childMouseEventFilter(QQuickItem *item, QEvent *event) return window && !window->mouseGrabberItem(); } +#if QT_CONFIG(quicktemplates2_multitouch) +void QQuickStackView::touchEvent(QTouchEvent *event) +{ + event->ignore(); // QTBUG-65084 +} +#endif + #if QT_CONFIG(accessibility) QAccessible::Role QQuickStackView::accessibleRole() const { diff --git a/src/quicktemplates2/qquickstackview_p.h b/src/quicktemplates2/qquickstackview_p.h index 2cddb800..e347ba9d 100644 --- a/src/quicktemplates2/qquickstackview_p.h +++ b/src/quicktemplates2/qquickstackview_p.h @@ -160,6 +160,10 @@ protected: void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override; bool childMouseEventFilter(QQuickItem *, QEvent *) override; +#if QT_CONFIG(quicktemplates2_multitouch) + void touchEvent(QTouchEvent *event) override; +#endif + #if QT_CONFIG(accessibility) QAccessible::Role accessibleRole() const override; #endif diff --git a/src/quicktemplates2/qquicktextarea.cpp b/src/quicktemplates2/qquicktextarea.cpp index d2458c24..319f7bbe 100644 --- a/src/quicktemplates2/qquicktextarea.cpp +++ b/src/quicktemplates2/qquicktextarea.cpp @@ -440,13 +440,19 @@ QAccessible::Role QQuickTextAreaPrivate::accessibleRole() const static inline QString backgroundName() { return QStringLiteral("background"); } +void QQuickTextAreaPrivate::cancelBackground() +{ + Q_Q(QQuickTextArea); + quickCancelDeferred(q, backgroundName()); +} + void QQuickTextAreaPrivate::executeBackground(bool complete) { Q_Q(QQuickTextArea); if (background.wasExecuted()) return; - if (!background) + if (!background || complete) quickBeginDeferred(q, backgroundName(), background); if (complete) quickCompleteDeferred(q, backgroundName(), background); @@ -517,6 +523,9 @@ void QQuickTextArea::setBackground(QQuickItem *background) if (d->background == background) return; + if (!d->background.isExecuting()) + d->cancelBackground(); + delete d->background; d->background = background; if (background) { diff --git a/src/quicktemplates2/qquicktextarea_p_p.h b/src/quicktemplates2/qquicktextarea_p_p.h index d27af8f6..8621c61c 100644 --- a/src/quicktemplates2/qquicktextarea_p_p.h +++ b/src/quicktemplates2/qquicktextarea_p_p.h @@ -125,6 +125,7 @@ public: QAccessible::Role accessibleRole() const override; #endif + void cancelBackground(); void executeBackground(bool complete = false); #if QT_CONFIG(quicktemplates2_hover) diff --git a/src/quicktemplates2/qquicktextfield.cpp b/src/quicktemplates2/qquicktextfield.cpp index 03da9323..49f9b4c8 100644 --- a/src/quicktemplates2/qquicktextfield.cpp +++ b/src/quicktemplates2/qquicktextfield.cpp @@ -314,13 +314,19 @@ QAccessible::Role QQuickTextFieldPrivate::accessibleRole() const static inline QString backgroundName() { return QStringLiteral("background"); } +void QQuickTextFieldPrivate::cancelBackground() +{ + Q_Q(QQuickTextField); + quickCancelDeferred(q, backgroundName()); +} + void QQuickTextFieldPrivate::executeBackground(bool complete) { Q_Q(QQuickTextField); if (background.wasExecuted()) return; - if (!background) + if (!background || complete) quickBeginDeferred(q, backgroundName(), background); if (complete) quickCompleteDeferred(q, backgroundName(), background); @@ -379,6 +385,9 @@ void QQuickTextField::setBackground(QQuickItem *background) if (d->background == background) return; + if (!d->background.isExecuting()) + d->cancelBackground(); + delete d->background; d->background = background; if (background) { diff --git a/src/quicktemplates2/qquicktextfield_p_p.h b/src/quicktemplates2/qquicktextfield_p_p.h index 5ae79b7f..41843370 100644 --- a/src/quicktemplates2/qquicktextfield_p_p.h +++ b/src/quicktemplates2/qquicktextfield_p_p.h @@ -113,6 +113,7 @@ public: QAccessible::Role accessibleRole() const override; #endif + void cancelBackground(); void executeBackground(bool complete = false); #if QT_CONFIG(quicktemplates2_hover) diff --git a/src/quicktemplates2/quicktemplates2.pri b/src/quicktemplates2/quicktemplates2.pri index ee51f995..b2193ec0 100644 --- a/src/quicktemplates2/quicktemplates2.pri +++ b/src/quicktemplates2/quicktemplates2.pri @@ -50,6 +50,7 @@ HEADERS += \ $$PWD/qquickpageindicator_p.h \ $$PWD/qquickpagelayout_p_p.h \ $$PWD/qquickpalette_p.h \ + $$PWD/qquickpaletteprovider_p.h \ $$PWD/qquickpane_p.h \ $$PWD/qquickpane_p_p.h \ $$PWD/qquickpopup_p.h \ @@ -125,6 +126,7 @@ SOURCES += \ $$PWD/qquickpageindicator.cpp \ $$PWD/qquickpagelayout.cpp \ $$PWD/qquickpalette.cpp \ + $$PWD/qquickpaletteprovider.cpp \ $$PWD/qquickpane.cpp \ $$PWD/qquickpopup.cpp \ $$PWD/qquickpopupitem.cpp \ |