From 3ec6d04d976249d162f6ec92666d9008f4c21c34 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Wed, 13 Dec 2017 13:35:52 +0100 Subject: ComboBox: use deferred execution As a special case, ComboBox defers the execution of the popup until the popup is either accessed or made visible. This gives a nice boost in creation time benchmarks (20->25, ~25%). The old optimization of setting the delegate model only when the popup is visible is no longer needed. Task-number: QTBUG-50992 Change-Id: Ifeaceb759ab676bb54c6bc09dc97810eade72ca1 Reviewed-by: Mitch Curtis --- tests/auto/auto.pro | 2 +- tests/auto/controls/data/tst_combobox.qml | 1 - .../customization/data/styles/empty/ComboBox.qml | 57 +++++++++++++++ .../data/styles/incomplete/ComboBox.qml | 61 ++++++++++++++++ .../data/styles/override/ComboBox.qml | 61 ++++++++++++++++ .../customization/data/styles/simple/ComboBox.qml | 81 ++++++++++++++++++++++ tests/auto/customization/tst_customization.cpp | 49 +++++++++++++ 7 files changed, 310 insertions(+), 2 deletions(-) create mode 100644 tests/auto/customization/data/styles/empty/ComboBox.qml create mode 100644 tests/auto/customization/data/styles/incomplete/ComboBox.qml create mode 100644 tests/auto/customization/data/styles/override/ComboBox.qml create mode 100644 tests/auto/customization/data/styles/simple/ComboBox.qml (limited to 'tests') 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 #include #include +#include +#include #include #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 comboBox(qobject_cast(component.create())); + QVERIFY(comboBox); + + QVERIFY(!qt_createdQObjects()->contains("combobox-popup-simple")); + + QObject *popup = comboBox->property("popup").value(); + 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 comboBox(qobject_cast(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" -- cgit v1.2.3