diff options
-rw-r--r-- | src/imports/controls/ComboBox.qml | 6 | ||||
-rw-r--r-- | src/imports/controls/material/ComboBox.qml | 6 | ||||
-rw-r--r-- | src/imports/controls/universal/ComboBox.qml | 6 | ||||
-rw-r--r-- | src/quicktemplates2/qquickcombobox.cpp | 106 | ||||
-rw-r--r-- | src/quicktemplates2/qquickcombobox_p.h | 1 | ||||
-rw-r--r-- | tests/auto/auto.pro | 2 | ||||
-rw-r--r-- | tests/auto/controls/data/tst_combobox.qml | 1 | ||||
-rw-r--r-- | tests/auto/customization/data/styles/empty/ComboBox.qml | 57 | ||||
-rw-r--r-- | tests/auto/customization/data/styles/incomplete/ComboBox.qml | 61 | ||||
-rw-r--r-- | tests/auto/customization/data/styles/override/ComboBox.qml | 61 | ||||
-rw-r--r-- | tests/auto/customization/data/styles/simple/ComboBox.qml | 81 | ||||
-rw-r--r-- | tests/auto/customization/tst_customization.cpp | 49 |
12 files changed, 400 insertions, 37 deletions
diff --git a/src/imports/controls/ComboBox.qml b/src/imports/controls/ComboBox.qml index 6a885320..8d1a28be 100644 --- a/src/imports/controls/ComboBox.qml +++ b/src/imports/controls/ComboBox.qml @@ -80,7 +80,7 @@ T.ComboBox { enabled: control.editable autoScroll: control.editable - readOnly: control.popup.visible + readOnly: control.down inputMethodHints: control.inputMethodHints validator: control.validator @@ -104,7 +104,7 @@ T.ComboBox { implicitHeight: 40 color: !control.editable && control.visualFocus ? (control.pressed ? Default.focusPressedColor : Default.focusLightColor) : - (control.down || popup.visible ? Default.buttonPressedColor : Default.buttonColor) + (control.down ? Default.buttonPressedColor : Default.buttonColor) border.color: Default.focusColor border.width: !control.editable && control.visualFocus ? 2 : 0 visible: !control.flat || control.down @@ -120,7 +120,7 @@ T.ComboBox { contentItem: ListView { clip: true implicitHeight: contentHeight - model: control.popup.visible ? control.delegateModel : null + model: control.delegateModel currentIndex: control.highlightedIndex highlightRangeMode: ListView.ApplyRange highlightMoveDuration: 0 diff --git a/src/imports/controls/material/ComboBox.qml b/src/imports/controls/material/ComboBox.qml index da9fd73c..d2ca7679 100644 --- a/src/imports/controls/material/ComboBox.qml +++ b/src/imports/controls/material/ComboBox.qml @@ -84,7 +84,7 @@ T.ComboBox { enabled: control.editable autoScroll: control.editable - readOnly: control.popup.visible + readOnly: control.down inputMethodHints: control.inputMethodHints validator: control.validator @@ -161,7 +161,7 @@ T.ComboBox { contentItem: ListView { clip: true implicitHeight: contentHeight - model: control.popup.visible ? control.delegateModel : null + model: control.delegateModel currentIndex: control.highlightedIndex highlightRangeMode: ListView.ApplyRange highlightMoveDuration: 0 @@ -171,7 +171,7 @@ T.ComboBox { background: Rectangle { radius: 2 - color: control.popup.Material.dialogColor + color: parent.Material.dialogColor layer.enabled: control.enabled layer.effect: ElevationEffect { diff --git a/src/imports/controls/universal/ComboBox.qml b/src/imports/controls/universal/ComboBox.qml index a2ba0236..596dcf5b 100644 --- a/src/imports/controls/universal/ComboBox.qml +++ b/src/imports/controls/universal/ComboBox.qml @@ -91,7 +91,7 @@ T.ComboBox { enabled: control.editable autoScroll: control.editable - readOnly: control.popup.visible + readOnly: control.down inputMethodHints: control.inputMethodHints validator: control.validator @@ -111,7 +111,7 @@ T.ComboBox { border.width: control.flat ? 0 : 2 // ComboBoxBorderThemeThickness border.color: !control.enabled ? control.Universal.baseLowColor : control.editable && control.activeFocus ? control.Universal.accent : - control.down || popup.visible ? control.Universal.baseMediumLowColor : + control.down ? control.Universal.baseMediumLowColor : control.hovered ? control.Universal.baseMediumColor : control.Universal.baseMediumLowColor color: !control.enabled ? control.Universal.baseLowColor : control.down ? control.Universal.listMediumColor : @@ -143,7 +143,7 @@ T.ComboBox { contentItem: ListView { clip: true implicitHeight: contentHeight - model: control.popup.visible ? control.delegateModel : null + model: control.delegateModel currentIndex: control.highlightedIndex highlightRangeMode: ListView.ApplyRange highlightMoveDuration: 0 diff --git a/src/quicktemplates2/qquickcombobox.cpp b/src/quicktemplates2/qquickcombobox.cpp index d22e09d5..dde27e2a 100644 --- a/src/quicktemplates2/qquickcombobox.cpp +++ b/src/quicktemplates2/qquickcombobox.cpp @@ -38,6 +38,7 @@ #include "qquickcontrol_p_p.h" #include "qquickabstractbutton_p.h" #include "qquickpopup_p_p.h" +#include "qquickdeferredexecute_p_p.h" #include <QtCore/qregexp.h> #include <QtCore/qabstractitemmodel.h> @@ -252,6 +253,11 @@ public: void handleRelease(const QPointF &point) override; void handleUngrab() override; + QQuickItem *getContentItem() override; + + void executeIndicator(bool complete = false); + void executePopup(bool complete = false); + bool flat; bool down; bool hasDown; @@ -268,8 +274,8 @@ public: QQuickItem *pressedItem; QQmlInstanceModel *delegateModel; QQmlComponent *delegate; - QQuickItem *indicator; - QQuickPopup *popup; + QQuickDeferredPointer<QQuickItem> indicator; + QQuickDeferredPointer<QQuickPopup> popup; struct ExtraData { ExtraData() @@ -313,6 +319,9 @@ bool QQuickComboBoxPrivate::isPopupVisible() const void QQuickComboBoxPrivate::showPopup() { + if (!popup) + executePopup(true); + if (popup && !popup->isVisible()) popup->open(); } @@ -330,13 +339,10 @@ void QQuickComboBoxPrivate::hidePopup(bool accept) void QQuickComboBoxPrivate::togglePopup(bool accept) { - if (!popup) - return; - - if (popup->isVisible()) - hidePopup(accept); - else + if (!popup || !popup->isVisible()) showPopup(); + else + hidePopup(accept); } void QQuickComboBoxPrivate::popupVisibleChanged() @@ -366,8 +372,11 @@ void QQuickComboBoxPrivate::createdItem(int index, QObject *object) { Q_Q(QQuickComboBox); QQuickItem *item = qobject_cast<QQuickItem *>(object); - if (popup && item && !item->parentItem()) { - item->setParentItem(popup->contentItem()); + if (item && !item->parentItem()) { + if (popup) + item->setParentItem(popup->contentItem()); + else + item->setParentItem(q); QQuickItemPrivate::get(item)->setCulled(true); } @@ -662,6 +671,41 @@ void QQuickComboBoxPrivate::handleUngrab() q->setPressed(false); } +QQuickItem *QQuickComboBoxPrivate::getContentItem() +{ + if (!contentItem) + executeContentItem(); + return contentItem; +} + +static inline QString indicatorName() { return QStringLiteral("indicator"); } + +void QQuickComboBoxPrivate::executeIndicator(bool complete) +{ + Q_Q(QQuickComboBox); + if (indicator.wasExecuted()) + return; + + if (!indicator) + quickBeginDeferred(q, indicatorName(), indicator); + if (complete) + quickCompleteDeferred(q, indicatorName(), indicator); +} + +static inline QString popupName() { return QStringLiteral("popup"); } + +void QQuickComboBoxPrivate::executePopup(bool complete) +{ + Q_Q(QQuickComboBox); + if (popup.wasExecuted()) + return; + + if (!popup) + quickBeginDeferred(q, popupName(), popup); + if (complete) + quickCompleteDeferred(q, popupName(), popup); +} + QQuickComboBox::QQuickComboBox(QQuickItem *parent) : QQuickControl(*(new QQuickComboBoxPrivate), parent) { @@ -677,14 +721,13 @@ QQuickComboBox::QQuickComboBox(QQuickItem *parent) QQuickComboBox::~QQuickComboBox() { Q_D(QQuickComboBox); - // Disconnect visibleChanged() to avoid a spurious highlightedIndexChanged() signal - // emission during the destruction of the (visible) popup. (QTBUG-57650) - QObjectPrivate::disconnect(d->popup, &QQuickPopup::visibleChanged, d, &QQuickComboBoxPrivate::popupVisibleChanged); - - // Delete the popup directly instead of calling setPopup(nullptr) to avoid calling - // destroyDelegate(popup) and potentially accessing a destroyed QML context. (QTBUG-50992) - delete d->popup; - d->popup = nullptr; + if (d->popup) { + // Disconnect visibleChanged() to avoid a spurious highlightedIndexChanged() signal + // emission during the destruction of the (visible) popup. (QTBUG-57650) + QObjectPrivate::disconnect(d->popup.data(), &QQuickPopup::visibleChanged, d, &QQuickComboBoxPrivate::popupVisibleChanged); + delete d->popup; + d->popup = nullptr; + } } /*! @@ -969,7 +1012,9 @@ void QQuickComboBox::setDelegate(QQmlComponent* delegate) */ QQuickItem *QQuickComboBox::indicator() const { - Q_D(const QQuickComboBox); + QQuickComboBoxPrivate *d = const_cast<QQuickComboBoxPrivate *>(d_func()); + if (!d->indicator) + d->executeIndicator(); return d->indicator; } @@ -979,13 +1024,14 @@ void QQuickComboBox::setIndicator(QQuickItem *indicator) if (d->indicator == indicator) return; - QQuickControlPrivate::destroyDelegate(d->indicator, this); + delete d->indicator; d->indicator = indicator; if (indicator) { if (!indicator->parentItem()) indicator->setParentItem(this); } - emit indicatorChanged(); + if (!d->indicator.isExecuting()) + emit indicatorChanged(); } /*! @@ -1003,7 +1049,9 @@ void QQuickComboBox::setIndicator(QQuickItem *indicator) */ QQuickPopup *QQuickComboBox::popup() const { - Q_D(const QQuickComboBox); + QQuickComboBoxPrivate *d = const_cast<QQuickComboBoxPrivate *>(d_func()); + if (!d->popup) + d->executePopup(isComponentComplete()); return d->popup; } @@ -1014,8 +1062,8 @@ void QQuickComboBox::setPopup(QQuickPopup *popup) return; if (d->popup) { - QObjectPrivate::disconnect(d->popup, &QQuickPopup::visibleChanged, d, &QQuickComboBoxPrivate::popupVisibleChanged); - QQuickControlPrivate::destroyDelegate(d->popup, this); + QObjectPrivate::disconnect(d->popup.data(), &QQuickPopup::visibleChanged, d, &QQuickComboBoxPrivate::popupVisibleChanged); + delete d->popup; } if (popup) { QQuickPopupPrivate::get(popup)->allowVerticalFlip = true; @@ -1023,7 +1071,8 @@ void QQuickComboBox::setPopup(QQuickPopup *popup) QObjectPrivate::connect(popup, &QQuickPopup::visibleChanged, d, &QQuickComboBoxPrivate::popupVisibleChanged); } d->popup = popup; - emit popupChanged(); + if (!d->popup.isExecuting()) + emit popupChanged(); } /*! @@ -1494,7 +1543,7 @@ void QQuickComboBox::keyReleaseEvent(QKeyEvent *event) { Q_D(QQuickComboBox); QQuickControl::keyReleaseEvent(event); - if (!d->popup || event->isAutoRepeat()) + if (event->isAutoRepeat()) return; switch (event->key()) { @@ -1541,6 +1590,11 @@ void QQuickComboBox::wheelEvent(QWheelEvent *event) void QQuickComboBox::componentComplete() { Q_D(QQuickComboBox); + d->executeIndicator(true); + d->executeBackground(true); + d->executeContentItem(true); + if (d->popup) + d->executePopup(true); QQuickControl::componentComplete(); if (d->delegateModel && d->ownModel) diff --git a/src/quicktemplates2/qquickcombobox_p.h b/src/quicktemplates2/qquickcombobox_p.h index 030d068b..7c27ca99 100644 --- a/src/quicktemplates2/qquickcombobox_p.h +++ b/src/quicktemplates2/qquickcombobox_p.h @@ -82,6 +82,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickComboBox : public QQuickControl Q_PROPERTY(Qt::InputMethodHints inputMethodHints READ inputMethodHints WRITE setInputMethodHints NOTIFY inputMethodHintsChanged FINAL REVISION 2) Q_PROPERTY(bool inputMethodComposing READ isInputMethodComposing NOTIFY inputMethodComposingChanged FINAL REVISION 2) Q_PROPERTY(bool acceptableInput READ hasAcceptableInput NOTIFY acceptableInputChanged FINAL REVISION 2) + Q_CLASSINFO("DeferredPropertyNames", "background,contentItem,indicator,popup") public: explicit QQuickComboBox(QQuickItem *parent = nullptr); diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index 17613796..4660a695 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -24,7 +24,7 @@ SUBDIRS += \ snippets # QTBUG-60268 -boot2qt: SUBDIRS -= qquickapplicationwindow calendar controls cursor \ +boot2qt: SUBDIRS -= qquickapplicationwindow calendar controls cursor customization \ qquickdrawer focus font qquickmenu platform qquickpopup qquickmaterialstyle \ qquickmaterialstyleconf qquickuniversalstyle \ qquickuniversalstyleconf snippets diff --git a/tests/auto/controls/data/tst_combobox.qml b/tests/auto/controls/data/tst_combobox.qml index abdfd51a..00e1a2cc 100644 --- a/tests/auto/controls/data/tst_combobox.qml +++ b/tests/auto/controls/data/tst_combobox.qml @@ -1466,7 +1466,6 @@ TestCase { var control = createTemporaryObject(comboBox, testCase, { model: 1 }) verify(control) compare(control.popup.implicitHeight, 0) - compare(control.popup.height, 0) // Ensure that it's open so that the popup's implicitHeight changes when we increase the model count. control.popup.open() diff --git a/tests/auto/customization/data/styles/empty/ComboBox.qml b/tests/auto/customization/data/styles/empty/ComboBox.qml new file mode 100644 index 00000000..5e7e9b14 --- /dev/null +++ b/tests/auto/customization/data/styles/empty/ComboBox.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite 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.Templates 2.2 as T + +T.ComboBox { + id: control + objectName: "combobox-empty" +} diff --git a/tests/auto/customization/data/styles/incomplete/ComboBox.qml b/tests/auto/customization/data/styles/incomplete/ComboBox.qml new file mode 100644 index 00000000..7dd92b74 --- /dev/null +++ b/tests/auto/customization/data/styles/incomplete/ComboBox.qml @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite 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.Templates 2.2 as T + +T.ComboBox { + id: control + objectName: "combobox-incomplete" + + contentItem: Item { + objectName: "combobox-contentItem-incomplete" + } +} diff --git a/tests/auto/customization/data/styles/override/ComboBox.qml b/tests/auto/customization/data/styles/override/ComboBox.qml new file mode 100644 index 00000000..e87a4640 --- /dev/null +++ b/tests/auto/customization/data/styles/override/ComboBox.qml @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite 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 "../simple" as Simple + +Simple.ComboBox { + id: control + objectName: "combobox-override" + + background: Rectangle { + objectName: "combobox-background-override" + } +} diff --git a/tests/auto/customization/data/styles/simple/ComboBox.qml b/tests/auto/customization/data/styles/simple/ComboBox.qml new file mode 100644 index 00000000..ac46cf62 --- /dev/null +++ b/tests/auto/customization/data/styles/simple/ComboBox.qml @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite 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.Templates 2.2 as T + +T.ComboBox { + id: control + objectName: "combobox-simple" + + implicitWidth: Math.max(contentItem.implicitWidth, background.implicitWidth) + implicitHeight: Math.max(contentItem.implicitHeight, background.implicitHeight) + + indicator: Text { + objectName: "combobox-indicator-simple" + text: control.comboed ? "V" : "" + } + + contentItem: Text { + objectName: "combobox-contentItem-simple" + text: control.currentText + } + + background: Rectangle { + objectName: "combobox-background-simple" + implicitWidth: 20 + implicitHeight: 20 + color: control.down ? "red" : "green" + } + + popup: T.Popup { + objectName: "combobox-popup-simple" + } +} diff --git a/tests/auto/customization/tst_customization.cpp b/tests/auto/customization/tst_customization.cpp index 20914b61..51ae3650 100644 --- a/tests/auto/customization/tst_customization.cpp +++ b/tests/auto/customization/tst_customization.cpp @@ -39,6 +39,8 @@ #include <QtCore/qregularexpression.h> #include <QtQml/qqmlengine.h> #include <QtQml/qqmlcomponent.h> +#include <QtQuick/qquickitem.h> +#include <QtQuick/qquickwindow.h> #include <QtQuickControls2/qquickstyle.h> #include "../shared/visualtestutil.h" @@ -55,6 +57,8 @@ private slots: void creation_data(); void creation(); + void comboPopup(); + private: void reset(); void addHooks(); @@ -131,6 +135,7 @@ void tst_customization::creation_data() QTest::newRow("empty:ApplicationWindow") << "empty" << "ApplicationWindow"<< (QStringList() << "applicationwindow-empty"); QTest::newRow("empty:Button") << "empty" << "Button"<< (QStringList() << "button-empty"); QTest::newRow("empty:CheckBox") << "empty" << "CheckBox" << (QStringList() << "checkbox-empty"); + QTest::newRow("empty:ComboBox") << "empty" << "ComboBox" << (QStringList() << "combobox-empty"); QTest::newRow("empty:Dial") << "empty" << "Dial" << (QStringList() << "dial-empty"); QTest::newRow("empty:Label") << "empty" << "Label"<< (QStringList() << "label-empty"); QTest::newRow("empty:RadioButton") << "empty" << "RadioButton" << (QStringList() << "radiobutton-empty"); @@ -142,6 +147,7 @@ void tst_customization::creation_data() // the "incomplete" style is missing most delegates QTest::newRow("incomplete:Button") << "incomplete" << "Button" << (QStringList() << "button-incomplete" << "button-background-incomplete"); QTest::newRow("incomplete:CheckBox") << "incomplete" << "CheckBox" << (QStringList() << "checkbox-incomplete" << "checkbox-contentItem-incomplete"); + QTest::newRow("incomplete:ComboBox") << "incomplete" << "ComboBox" << (QStringList() << "combobox-incomplete" << "combobox-contentItem-incomplete"); QTest::newRow("incomplete:Dial") << "incomplete" << "Dial" << (QStringList() << "dial-incomplete" << "dial-handle-incomplete"); QTest::newRow("incomplete:RadioButton") << "incomplete" << "RadioButton" << (QStringList() << "radiobutton-incomplete" << "radiobutton-indicator-incomplete"); QTest::newRow("incomplete:RangeSlider") << "incomplete" << "RangeSlider" << (QStringList() << "rangeslider-incomplete" << "rangeslider-first-handle-incomplete" << "rangeslider-second-handle-incomplete"); @@ -151,6 +157,7 @@ void tst_customization::creation_data() QTest::newRow("simple:ApplicationWindow") << "simple" << "ApplicationWindow" << (QStringList() << "applicationwindow-simple" << "applicationwindow-background-simple"); QTest::newRow("simple:Button") << "simple" << "Button" << (QStringList() << "button-simple" << "button-background-simple" << "button-contentItem-simple"); QTest::newRow("simple:CheckBox") << "simple" << "CheckBox" << (QStringList() << "checkbox-simple" << "checkbox-contentItem-simple" << "checkbox-indicator-simple"); + QTest::newRow("simple:ComboBox") << "simple" << "ComboBox" << (QStringList() << "combobox-simple" << "combobox-background-simple" << "combobox-contentItem-simple" << "combobox-indicator-simple"); QTest::newRow("simple:Dial") << "simple" << "Dial" << (QStringList() << "dial-simple" << "dial-background-simple" << "dial-handle-simple"); QTest::newRow("simple:Label") << "simple" << "Label" << (QStringList() << "label-simple" << "label-background-simple"); QTest::newRow("simple:RadioButton") << "simple" << "RadioButton" << (QStringList() << "radiobutton-simple" << "radiobutton-contentItem-simple" << "radiobutton-indicator-simple"); @@ -163,6 +170,7 @@ void tst_customization::creation_data() QTest::newRow("override:ApplicationWindow") << "override" << "ApplicationWindow" << (QStringList() << "applicationwindow-override" << "applicationwindow-background-override" << "applicationwindow-simple"); // overrides "simple" QTest::newRow("override:Button") << "override" << "Button" << (QStringList() << "button-override" << "button-background-override" << "button-contentItem-override" << "button-empty"); // overrides "empty" QTest::newRow("override:CheckBox") << "override" << "CheckBox" << (QStringList() << "checkbox-override" << "checkbox-background-override" << "checkbox-contentItem-incomplete" << "checkbox-incomplete"); // overrides "incomplete" + QTest::newRow("override:ComboBox") << "override" << "ComboBox" << (QStringList() << "combobox-override" << "combobox-background-override" << "combobox-contentItem-simple" << "combobox-indicator-simple" << "combobox-simple"); // overrides "simple" QTest::newRow("override:Dial") << "override" << "Dial" << (QStringList() << "dial-override" << "dial-background-override" << "dial-handle-override" << "dial-incomplete"); // overrides "incomplete" QTest::newRow("override:Label") << "override" << "Label" << (QStringList() << "label-override" << "label-background-override" << "label-simple"); // overrides "simple" QTest::newRow("override:RadioButton") << "override" << "RadioButton" << (QStringList() << "radiobutton-override" << "radiobutton-background-override" << "radiobutton-contentItem-simple" << "radiobutton-indicator-override" << "radiobutton-simple"); // overrides "simple" @@ -190,6 +198,47 @@ void tst_customization::creation() QVERIFY2(qt_destroyedQObjects()->isEmpty(), qPrintable("unexpectedly destroyed: " + qt_destroyedQObjects->join(", ") + " were unexpectedly destroyed")); } +void tst_customization::comboPopup() +{ + QQuickStyle::setStyle(testFile("styles/simple")); + + { + // test that ComboBox::popup is created when accessed + QQmlComponent component(engine); + component.setData("import QtQuick.Controls 2.2; ComboBox { }", QUrl()); + QScopedPointer<QQuickItem> comboBox(qobject_cast<QQuickItem *>(component.create())); + QVERIFY(comboBox); + + QVERIFY(!qt_createdQObjects()->contains("combobox-popup-simple")); + + QObject *popup = comboBox->property("popup").value<QObject *>(); + QVERIFY(popup); + QVERIFY(qt_createdQObjects()->contains("combobox-popup-simple")); + } + + reset(); + + { + // test that ComboBox::popup is created when it becomes visible + QQuickWindow window; + window.resize(300, 300); + window.show(); + window.requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(&window)); + + QQmlComponent component(engine); + component.setData("import QtQuick.Controls 2.2; ComboBox { }", QUrl()); + QScopedPointer<QQuickItem> comboBox(qobject_cast<QQuickItem *>(component.create())); + QVERIFY(comboBox); + + comboBox->setParentItem(window.contentItem()); + QVERIFY(!qt_createdQObjects()->contains("combobox-popup-simple")); + + QTest::mouseClick(&window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1)); + QVERIFY(qt_createdQObjects()->contains("combobox-popup-simple")); + } +} + QTEST_MAIN(tst_customization) #include "tst_customization.moc" |