From 283457b64dcd178ca5aa8f15d845a47455b709c1 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Fri, 29 Jan 2016 09:53:22 +0100 Subject: Default SpinBox: sync colors with TextField and TextArea Change-Id: Ibbc6dda27172425250e0543817b4ab5b303bded5 Reviewed-by: Mitch Curtis --- src/imports/controls/SpinBox.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/imports/controls/SpinBox.qml b/src/imports/controls/SpinBox.qml index 947ec74a..77f89206 100644 --- a/src/imports/controls/SpinBox.qml +++ b/src/imports/controls/SpinBox.qml @@ -69,8 +69,8 @@ T.SpinBox { font: control.font color: "#353637" -// selectionColor: TODO -// selectedTextColor: TODO + selectionColor: "#fddd5c" + selectedTextColor: color horizontalAlignment: Qt.AlignHCenter verticalAlignment: Qt.AlignVCenter -- cgit v1.2.3 From 584b768cd051deb1da28cad5b9aaa15975c05b8d Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Fri, 29 Jan 2016 10:37:37 +0100 Subject: Tweak default style tabs Remove the explicit font size leftover, and tweak the implicit size bindings so that neither tst_accessibility nor tst_snippets throws any binding loop warnings. Change-Id: Ib60dc8a1fca33b14171320db3f37e65c046f5898 Reviewed-by: J-P Nurmi --- src/imports/controls/TabBar.qml | 7 ++----- src/imports/controls/TabButton.qml | 2 -- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/imports/controls/TabBar.qml b/src/imports/controls/TabBar.qml index b1a9009c..f43975f2 100644 --- a/src/imports/controls/TabBar.qml +++ b/src/imports/controls/TabBar.qml @@ -50,7 +50,7 @@ T.TabBar { //! [contentItem] contentItem: ListView { implicitWidth: contentWidth - implicitHeight: contentHeight + implicitHeight: 40 model: control.contentModel currentIndex: control.currentIndex @@ -63,9 +63,6 @@ T.TabBar { //! [contentItem] //! [background] - background: Rectangle { - implicitWidth: 40 - implicitHeight: 40 - } + background: Rectangle { } //! [background] } diff --git a/src/imports/controls/TabButton.qml b/src/imports/controls/TabButton.qml index ef11e405..178a0a7f 100644 --- a/src/imports/controls/TabButton.qml +++ b/src/imports/controls/TabButton.qml @@ -48,8 +48,6 @@ T.TabButton { padding: 6 - font.pointSize: 10 - //! [label] label: Text { x: control.leftPadding -- cgit v1.2.3 From 1f146d982b36e0113558806f580da0d32cefef49 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Fri, 29 Jan 2016 09:46:25 +0100 Subject: QQuickSpinBox: create JS callbacks lazily Calling QJSEngine::evaluate() is a heavy operation. Only one of them, namely textFromValue, is used from QML, so there's a good chance that valueFromText doesn't need to be evaluated at component creation time. This change postpones the initial evaluation to the point where either callback is requested. Before: RESULT : tst_CreationTime::controls():"SpinBox": 0.53 msecs per iteration (total: 68, iterations: 128) After: RESULT : tst_CreationTime::controls():"SpinBox": 0.39 msecs per iteration (total: 51, iterations: 128) Change-Id: I1730dc4024d0a556ca2da765ac3c52ba8a29f743 Reviewed-by: Mitch Curtis --- src/templates/qquickspinbox.cpp | 27 ++++++++++++--------------- src/templates/qquickspinbox_p.h | 1 - 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/src/templates/qquickspinbox.cpp b/src/templates/qquickspinbox.cpp index 33ea6e79..bda955d0 100644 --- a/src/templates/qquickspinbox.cpp +++ b/src/templates/qquickspinbox.cpp @@ -116,8 +116,8 @@ public: QQuickSpinButton *up; QQuickSpinButton *down; QValidator *validator; - QJSValue textFromValue; - QJSValue valueFromText; + mutable QJSValue textFromValue; + mutable QJSValue valueFromText; }; int QQuickSpinBoxPrivate::boundValue(int value) const @@ -384,6 +384,11 @@ void QQuickSpinBox::setValidator(QValidator *validator) QJSValue QQuickSpinBox::textFromValue() const { Q_D(const QQuickSpinBox); + if (!d->textFromValue.isCallable()) { + QQmlEngine *engine = qmlEngine(this); + if (engine) + d->textFromValue = engine->evaluate(QStringLiteral("function(value, locale) { return Number(value).toLocaleString(locale, 'f', 0); }")); + } return d->textFromValue; } @@ -420,6 +425,11 @@ void QQuickSpinBox::setTextFromValue(const QJSValue &callback) QJSValue QQuickSpinBox::valueFromText() const { Q_D(const QQuickSpinBox); + if (!d->valueFromText.isCallable()) { + QQmlEngine *engine = qmlEngine(this); + if (engine) + d->valueFromText = engine->evaluate(QStringLiteral("function(text, locale) { return Number.fromLocaleString(locale, text); }")); + } return d->valueFromText; } @@ -587,19 +597,6 @@ void QQuickSpinBox::timerEvent(QTimerEvent *event) } } -void QQuickSpinBox::componentComplete() -{ - Q_D(QQuickSpinBox); - QQuickControl::componentComplete(); - QQmlEngine *engine = qmlEngine(this); - if (engine) { - if (!d->textFromValue.isCallable()) - setTextFromValue(engine->evaluate(QStringLiteral("function(value, locale) { return Number(value).toLocaleString(locale, 'f', 0); }"))); - if (!d->valueFromText.isCallable()) - setValueFromText(engine->evaluate(QStringLiteral("function(text, locale) { return Number.fromLocaleString(locale, text); }"))); - } -} - void QQuickSpinBox::itemChange(ItemChange change, const ItemChangeData &value) { Q_D(QQuickSpinBox); diff --git a/src/templates/qquickspinbox_p.h b/src/templates/qquickspinbox_p.h index 0ad5e70d..c7d1f6c6 100644 --- a/src/templates/qquickspinbox_p.h +++ b/src/templates/qquickspinbox_p.h @@ -121,7 +121,6 @@ protected: void mouseUngrabEvent() Q_DECL_OVERRIDE; void timerEvent(QTimerEvent *event) Q_DECL_OVERRIDE; - void componentComplete() Q_DECL_OVERRIDE; void itemChange(ItemChange change, const ItemChangeData &value) Q_DECL_OVERRIDE; void contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) Q_DECL_OVERRIDE; -- cgit v1.2.3 From eb61b50ffc8e3f6640de14b4b256f2ed858100a1 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Fri, 29 Jan 2016 16:23:01 +0100 Subject: ComboBox: enable scroll indicators For some reason this crashes: ScrollIndicator.vertical: ScrollIndicator { } But using the attached property via template works: T.ScrollIndicator.vertical: ScrollIndicator { } Good enough solution for now. :) Change-Id: I7a631a66ad24b1ddf7852c7c11d3850e49a52c9b Task-number: QTBUG-50757 Reviewed-by: J-P Nurmi --- src/imports/controls/ComboBox.qml | 2 +- src/imports/controls/material/ComboBox.qml | 2 +- src/imports/controls/universal/ComboBox.qml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/imports/controls/ComboBox.qml b/src/imports/controls/ComboBox.qml index adbf8aad..e0e8d76f 100644 --- a/src/imports/controls/ComboBox.qml +++ b/src/imports/controls/ComboBox.qml @@ -117,7 +117,7 @@ T.ComboBox { color: "transparent" } -// ScrollIndicator.vertical: ScrollIndicator { } + T.ScrollIndicator.vertical: ScrollIndicator { } } background: Rectangle { } diff --git a/src/imports/controls/material/ComboBox.qml b/src/imports/controls/material/ComboBox.qml index b822bfd2..f556107c 100644 --- a/src/imports/controls/material/ComboBox.qml +++ b/src/imports/controls/material/ComboBox.qml @@ -129,7 +129,7 @@ T.ComboBox { model: control.popup.visible ? control.delegateModel : null currentIndex: control.highlightedIndex -// ScrollIndicator.vertical: ScrollIndicator { } + T.ScrollIndicator.vertical: ScrollIndicator { } } background: Rectangle { diff --git a/src/imports/controls/universal/ComboBox.qml b/src/imports/controls/universal/ComboBox.qml index 30dac42a..e450685f 100644 --- a/src/imports/controls/universal/ComboBox.qml +++ b/src/imports/controls/universal/ComboBox.qml @@ -118,7 +118,7 @@ T.ComboBox { model: control.popup.visible ? control.delegateModel : null currentIndex: control.highlightedIndex -// ScrollIndicator.vertical: ScrollIndicator { } + T.ScrollIndicator.vertical: ScrollIndicator { } } background: Rectangle { -- cgit v1.2.3 From 8d622ea022298b5296962475aec486a38e8c0d03 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Thu, 28 Jan 2016 15:46:51 +0100 Subject: QQuickStyleSelector: merge select() overloads Only one is used. Cleanup the API a bit by merging the two. Change-Id: I90d72e754442aef45e9d1bc3f86004cad511a726 Reviewed-by: Liang Qi --- src/controls/qquickstyleselector.cpp | 28 +++++++++++----------------- src/controls/qquickstyleselector_p.h | 2 -- 2 files changed, 11 insertions(+), 19 deletions(-) diff --git a/src/controls/qquickstyleselector.cpp b/src/controls/qquickstyleselector.cpp index 49b2aa17..85b54045 100644 --- a/src/controls/qquickstyleselector.cpp +++ b/src/controls/qquickstyleselector.cpp @@ -74,12 +74,6 @@ QQuickStyleSelector::~QQuickStyleSelector() { } -QString QQuickStyleSelector::select(const QString &filePath) const -{ - Q_D(const QQuickStyleSelector); - return select(QUrl(d->baseUrl.toString() + filePath)).toString(); -} - static bool isLocalScheme(const QString &file) { bool local = file == QLatin1String("qrc"); @@ -89,20 +83,20 @@ static bool isLocalScheme(const QString &file) return local; } -QUrl QQuickStyleSelector::select(const QUrl &filePath) const +QString QQuickStyleSelector::select(const QString &filePath) const { Q_D(const QQuickStyleSelector); - if (!isLocalScheme(filePath.scheme()) && !filePath.isLocalFile()) - return filePath; - QUrl ret(filePath); - if (isLocalScheme(filePath.scheme())) { - QString equivalentPath = QLatin1Char(':') + filePath.path(); - QString selectedPath = d->select(equivalentPath, allSelectors()); - ret.setPath(selectedPath.remove(0, 1)); - } else { - ret = QUrl::fromLocalFile(d->select(ret.toLocalFile(), allSelectors())); + QUrl url(d->baseUrl.toString() + filePath); + if (isLocalScheme(url.scheme()) || url.isLocalFile()) { + if (isLocalScheme(url.scheme())) { + QString equivalentPath = QLatin1Char(':') + url.path(); + QString selectedPath = d->select(equivalentPath, allSelectors()); + url.setPath(selectedPath.remove(0, 1)); + } else { + url = QUrl::fromLocalFile(d->select(url.toLocalFile(), allSelectors())); + } } - return ret; + return url.toString(); } static QString selectionHelper(const QString &path, const QString &fileName, const QStringList &selectors) diff --git a/src/controls/qquickstyleselector_p.h b/src/controls/qquickstyleselector_p.h index 64319098..17204c32 100644 --- a/src/controls/qquickstyleselector_p.h +++ b/src/controls/qquickstyleselector_p.h @@ -70,8 +70,6 @@ public: QUrl baseUrl() const; private: - QUrl select(const QUrl &filePath) const; - Q_DECLARE_PRIVATE(QQuickStyleSelector) QScopedPointer d_ptr; }; -- cgit v1.2.3 From 992766754ed7216f0347cb581d4756cfe114646d Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Thu, 28 Jan 2016 15:49:45 +0100 Subject: Move QQuickStyleSelector::allSelector() to private Change-Id: I6ba9d1c41b2ab6766faef6cdbdfb780e6ca37dfd Reviewed-by: Liang Qi --- src/controls/qquickstyleselector.cpp | 17 ++++++++--------- src/controls/qquickstyleselector_p.h | 3 --- src/controls/qquickstyleselector_p_p.h | 4 +++- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/src/controls/qquickstyleselector.cpp b/src/controls/qquickstyleselector.cpp index 85b54045..b8a15ee9 100644 --- a/src/controls/qquickstyleselector.cpp +++ b/src/controls/qquickstyleselector.cpp @@ -90,10 +90,10 @@ QString QQuickStyleSelector::select(const QString &filePath) const if (isLocalScheme(url.scheme()) || url.isLocalFile()) { if (isLocalScheme(url.scheme())) { QString equivalentPath = QLatin1Char(':') + url.path(); - QString selectedPath = d->select(equivalentPath, allSelectors()); + QString selectedPath = d->select(equivalentPath); url.setPath(selectedPath.remove(0, 1)); } else { - url = QUrl::fromLocalFile(d->select(url.toLocalFile(), allSelectors())); + url = QUrl::fromLocalFile(d->select(url.toLocalFile())); } } return url.toString(); @@ -125,7 +125,7 @@ static QString selectionHelper(const QString &path, const QString &fileName, con return path + fileName; } -QString QQuickStyleSelectorPrivate::select(const QString &filePath, const QStringList &allSelectors) const +QString QQuickStyleSelectorPrivate::select(const QString &filePath) const { QFileInfo fi(filePath); // If file doesn't exist, don't select @@ -133,7 +133,7 @@ QString QQuickStyleSelectorPrivate::select(const QString &filePath, const QStrin return filePath; QString ret = selectionHelper(fi.path().isEmpty() ? QString() : fi.path() + QLatin1Char('/'), - fi.fileName(), allSelectors); + fi.fileName(), allSelectors()); if (!ret.isEmpty()) return ret; @@ -152,14 +152,13 @@ void QQuickStyleSelector::setStyle(const QString &s) d->style = s; } -QStringList QQuickStyleSelector::allSelectors() const +QStringList QQuickStyleSelectorPrivate::allSelectors() const { - Q_D(const QQuickStyleSelector); QMutexLocker locker(&sharedDataMutex); - QQuickStyleSelectorPrivate::updateSelectors(); + updateSelectors(); QStringList selectors = sharedData->staticSelectors; - if (!d->style.isEmpty()) - selectors.prepend(d->style); + if (!style.isEmpty()) + selectors.prepend(style); return selectors; } diff --git a/src/controls/qquickstyleselector_p.h b/src/controls/qquickstyleselector_p.h index 17204c32..2ca6ea3a 100644 --- a/src/controls/qquickstyleselector_p.h +++ b/src/controls/qquickstyleselector_p.h @@ -47,7 +47,6 @@ // #include -#include #include QT_BEGIN_NAMESPACE @@ -64,8 +63,6 @@ public: QString style() const; void setStyle(const QString &s); - QStringList allSelectors() const; - void setBaseUrl(const QUrl &base); QUrl baseUrl() const; diff --git a/src/controls/qquickstyleselector_p_p.h b/src/controls/qquickstyleselector_p_p.h index b0de326b..e4df1035 100644 --- a/src/controls/qquickstyleselector_p_p.h +++ b/src/controls/qquickstyleselector_p_p.h @@ -49,6 +49,7 @@ #include #include #include +#include #include "qquickstyleselector_p.h" @@ -67,7 +68,8 @@ public: static QStringList platformSelectors(); static void addStatics(const QStringList &); //For loading GUI statics from other Qt modules QQuickStyleSelectorPrivate(); - QString select(const QString &filePath, const QStringList &allSelectors) const; + QString select(const QString &filePath) const; + QStringList allSelectors() const; QString style; QUrl baseUrl; -- cgit v1.2.3 From 5199f3e4f0c4aa08d6713beebb8c7b90f5c29e42 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Fri, 29 Jan 2016 08:59:02 +0100 Subject: Update TabBar and TabButton screenshots Change-Id: I5aec1c2a08b24e1779e62b9580a740fb102c1561 Reviewed-by: J-P Nurmi --- .../controls/doc/images/qtlabscontrols-tabbar.gif | Bin 5932 -> 8590 bytes .../controls/doc/images/qtlabscontrols-tabbar.png | Bin 3463 -> 4725 bytes .../controls/doc/images/qtlabscontrols-tabbutton.png | Bin 3477 -> 4728 bytes tests/manual/gifs/data/qtlabscontrols-tabbar.qml | 2 +- 4 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/imports/controls/doc/images/qtlabscontrols-tabbar.gif b/src/imports/controls/doc/images/qtlabscontrols-tabbar.gif index 0dccecb3..31db1f9e 100644 Binary files a/src/imports/controls/doc/images/qtlabscontrols-tabbar.gif and b/src/imports/controls/doc/images/qtlabscontrols-tabbar.gif differ diff --git a/src/imports/controls/doc/images/qtlabscontrols-tabbar.png b/src/imports/controls/doc/images/qtlabscontrols-tabbar.png index 100092f8..44a91d63 100644 Binary files a/src/imports/controls/doc/images/qtlabscontrols-tabbar.png and b/src/imports/controls/doc/images/qtlabscontrols-tabbar.png differ diff --git a/src/imports/controls/doc/images/qtlabscontrols-tabbutton.png b/src/imports/controls/doc/images/qtlabscontrols-tabbutton.png index ab05c1db..76d1e35c 100644 Binary files a/src/imports/controls/doc/images/qtlabscontrols-tabbutton.png and b/src/imports/controls/doc/images/qtlabscontrols-tabbutton.png differ diff --git a/tests/manual/gifs/data/qtlabscontrols-tabbar.qml b/tests/manual/gifs/data/qtlabscontrols-tabbar.qml index 55bf5e27..8ca14721 100644 --- a/tests/manual/gifs/data/qtlabscontrols-tabbar.qml +++ b/tests/manual/gifs/data/qtlabscontrols-tabbar.qml @@ -43,7 +43,7 @@ import QtQuick.Window 2.0 import Qt.labs.controls 1.0 Window { - width: 200 + width: 300 height: tabBar.height visible: true -- cgit v1.2.3 From 509b610267fd1f9eef5e22267a0cab6fae4a3752 Mon Sep 17 00:00:00 2001 From: Nikita Krupenko Date: Fri, 29 Jan 2016 00:06:43 +0200 Subject: Material: adjust sizes of checkable controls Made Switch indicator and handle smaller to be more like the native switch on Android. Also, increased the sizes of Switch and its Ripple CheckBox, and RadioButton to to correspond minimum touch target size 48x48. Change-Id: Icce70215910b677d989182fbb3b40161033601f8 Reviewed-by: J-P Nurmi Reviewed-by: Nikita Krupenko Reviewed-by: Mitch Curtis --- src/imports/controls/material/CheckBox.qml | 7 +++++-- src/imports/controls/material/RadioButton.qml | 7 +++++-- src/imports/controls/material/Switch.qml | 16 ++++++++-------- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/imports/controls/material/CheckBox.qml b/src/imports/controls/material/CheckBox.qml index 939d5a31..e7fbadaa 100644 --- a/src/imports/controls/material/CheckBox.qml +++ b/src/imports/controls/material/CheckBox.qml @@ -50,8 +50,11 @@ T.CheckBox { indicator ? indicator.implicitHeight : 0) + topPadding + bottomPadding) baselineOffset: label ? label.y + label.baselineOffset : 0 - padding: 6 - spacing: 6 + spacing: 8 + topPadding: 14 + leftPadding: 8 + rightPadding: 8 + bottomPadding: 14 //! [indicator] indicator: Rectangle { diff --git a/src/imports/controls/material/RadioButton.qml b/src/imports/controls/material/RadioButton.qml index 96605311..25d91a5c 100644 --- a/src/imports/controls/material/RadioButton.qml +++ b/src/imports/controls/material/RadioButton.qml @@ -50,8 +50,11 @@ T.RadioButton { indicator ? indicator.implicitHeight : 0) + topPadding + bottomPadding) baselineOffset: label ? label.y + label.baselineOffset : 0 - padding: 6 - spacing: 6 + spacing: 8 + topPadding: 14 + leftPadding: 8 + rightPadding: 8 + bottomPadding: 14 //! [indicator] indicator: Rectangle { diff --git a/src/imports/controls/material/Switch.qml b/src/imports/controls/material/Switch.qml index 7c8e4395..f44fb31a 100644 --- a/src/imports/controls/material/Switch.qml +++ b/src/imports/controls/material/Switch.qml @@ -51,20 +51,20 @@ T.Switch { indicator ? indicator.implicitHeight : 0) + topPadding + bottomPadding) baselineOffset: label ? label.y + label.baselineOffset : 0 - padding: 6 - spacing: 6 + padding: 8 + spacing: 8 //! [indicator] indicator: Item { x: text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 y: control.topPadding + (control.availableHeight - height) / 2 - implicitWidth: 40 - implicitHeight: 20 + implicitWidth: 38 + implicitHeight: 32 Ripple { x: handle.x + handle.width / 2 - width / 2 y: handle.y + handle.height / 2 - height / 2 - width: handle.width - 4 + width: handle.width height: width control: control colored: control.checked @@ -73,7 +73,7 @@ T.Switch { Rectangle { width: parent.width - height: 16 + height: 14 radius: height / 2 y: parent.height / 2 - height / 2 color: control.enabled ? (control.checked ? control.Material.switchCheckedTrackColor : control.Material.switchUncheckedTrackColor) @@ -84,8 +84,8 @@ T.Switch { id: handle x: Math.max(0, Math.min(parent.width - width, control.visualPosition * parent.width - (width / 2))) y: (parent.height - height) / 2 - width: 24 - height: 24 + width: 20 + height: 20 radius: width / 2 color: control.enabled ? (control.checked ? control.Material.switchCheckedHandleColor : control.Material.switchUncheckedHandleColor) : control.Material.switchDisabledHandleColor -- cgit v1.2.3 From 30fcc7358b9e7db905d99355091eb3e44fcee840 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Sat, 30 Jan 2016 12:47:03 +0100 Subject: tst_applicationwindow: a temporary workaround to unblock CI Change-Id: Ia28054f5860bf65c87a0c8cfcc09f7c9a769c7cf Reviewed-by: J-P Nurmi --- tests/auto/applicationwindow/tst_applicationwindow.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/auto/applicationwindow/tst_applicationwindow.cpp b/tests/auto/applicationwindow/tst_applicationwindow.cpp index 34493ea0..d2937a6d 100644 --- a/tests/auto/applicationwindow/tst_applicationwindow.cpp +++ b/tests/auto/applicationwindow/tst_applicationwindow.cpp @@ -437,6 +437,11 @@ void tst_applicationwindow::attachedProperties() QVERIFY(!childItem->property("attached_header").value()); QVERIFY(!childItem->property("attached_footer").value()); QVERIFY(!childItem->property("attached_overlay").value()); + + // ### A temporary workaround to unblock the CI until the crash caused + // by https://codereview.qt-project.org/#/c/108517/ has been fixed... + window->hide(); + qApp->processEvents(); } void tst_applicationwindow::font() -- cgit v1.2.3 From 8ba12ed7f25d8cfb7619b6eb0a26fe4ae3e823b1 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Fri, 29 Jan 2016 19:23:28 +0100 Subject: AbstractButton: set automatically as checkable when being checked This makes it more convenient to create a bunch of checkable buttons where one is checked: Column { Button { checked: true } Button { checkable: true } Button { checkable: true } } Change-Id: I797d0d08256a4006194bc8db0ddfe4d2c7902d85 Reviewed-by: Mitch Curtis --- src/templates/qquickabstractbutton.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/templates/qquickabstractbutton.cpp b/src/templates/qquickabstractbutton.cpp index 664efce5..44526add 100644 --- a/src/templates/qquickabstractbutton.cpp +++ b/src/templates/qquickabstractbutton.cpp @@ -257,6 +257,9 @@ bool QQuickAbstractButton::isChecked() const void QQuickAbstractButton::setChecked(bool checked) { Q_D(QQuickAbstractButton); + if (checked && !d->checkable) + setCheckable(true); + if (d->checked != checked) { d->checked = checked; setAccessibleProperty("checked", checked); -- cgit v1.2.3 From bb06d8913c4e781a37db100e2619a236a93b38a9 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Fri, 29 Jan 2016 19:39:27 +0100 Subject: Material CheckBox: fix disabled state Change-Id: Ia0b95ed25cad55477d90038db39ac22a6a3932ed Reviewed-by: Mitch Curtis --- src/imports/controls/material/CheckBox.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/imports/controls/material/CheckBox.qml b/src/imports/controls/material/CheckBox.qml index e7fbadaa..1c3e254b 100644 --- a/src/imports/controls/material/CheckBox.qml +++ b/src/imports/controls/material/CheckBox.qml @@ -64,7 +64,7 @@ T.CheckBox { implicitWidth: 20 implicitHeight: 20 color: "transparent" - border.color: control.checked ? control.Material.accentColor : control.Material.secondaryTextColor + border.color: control.checked && control.enabled ? control.Material.accentColor : control.Material.secondaryTextColor border.width: control.checked ? width / 2 : 2 radius: 2 -- cgit v1.2.3 From 6bfcaea4c2d7d2efee9aab3bf3e20bf63f65abf3 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Sat, 30 Jan 2016 09:45:43 +0100 Subject: Update README.md Change-Id: I323f708c857366c0b50d143d67b96bee3f7a1a98 Reviewed-by: J-P Nurmi --- README.md | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 03d9724f..1c67b728 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,14 @@ oriented Qt Quick Controls 1, the experimental Qt Labs Controls are an order of magnitude simpler, lighter and faster, and are primarily targeting embedded and mobile platforms. +Qt Labs Controls are based on a flexible template system that enables rapid +development of entire custom styles and user experiences. Qt Labs Controls +comes with a selection of built-in styles: + +- Default style - a simple and minimal all-round style that offers the maximum performance +- Material style - a style based on the Google Material Design Guidelines +- Universal style - a style based on the Microsoft Universal Design Guidelines + More information can be found in the following blog posts: - http://blog.qt.io/blog/2015/03/31/qt-quick-controls-for-embedded/ @@ -16,24 +24,24 @@ More information can be found in the following blog posts: If you have problems or questions, don't hesitate to: -- ask on the Qt Interest mailing list interest@qt-project.org +- ask on the Qt Interest mailing list http://lists.qt-project.org/mailman/listinfo/interest - ask on the Qt Forum http://forum.qt.io/category/12/qt-quick -- report issues to the Qt Bug Tracker https://bugreports.qt.io (component Qt Quick: Controls 2) +- report issues to the Qt Bug Tracker https://bugreports.qt.io (component: *Qt Quick: Controls 2*) ## Installation The MINIMUM REQUIREMENT for building this project is to use the same branch -of Qt 5. The dependencies are qtbase, qtxmlpatterns and qtdeclarative. Other -optional dependencies are qtgraphicaleffects for the Material style and -qtquickcontrols for the Qt Quick Layouts. +of Qt 5. The dependencies are *qtbase*, *qtxmlpatterns* and *qtdeclarative*. +Other optional dependencies include *qtgraphicaleffects* for the Material +style and *qtquickcontrols* for the Qt Quick Layouts. -To install the controls into your Qt directory (QTDIR/qml): +To install the controls into your Qt directory (```QTDIR/qml```): qmake make make install -If you are compiling against a system Qt on linux, you might have to use +If you are compiling against a system Qt on Linux, you might have to use ```sudo make install``` to install the project. ## Usage -- cgit v1.2.3 From e8f1c609bf612c39bd45778bd22b693c39e3d059 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Fri, 29 Jan 2016 19:37:45 +0100 Subject: CheckBox: support partially checked state for Default & Universal Change-Id: Id2614c2f441718ef21445ef42c7d64ff64e072ce Task-number: QTBUG-49961 Reviewed-by: J-P Nurmi --- src/imports/controls/CheckBox.qml | 11 ++++++++++- src/imports/controls/material/CheckBox.qml | 22 ++++++++++++++++++---- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/src/imports/controls/CheckBox.qml b/src/imports/controls/CheckBox.qml index 20d8ef1c..4b7af3b1 100644 --- a/src/imports/controls/CheckBox.qml +++ b/src/imports/controls/CheckBox.qml @@ -67,7 +67,16 @@ T.CheckBox { x: (parent.width - width) / 2 y: (parent.height - height) / 2 source: "qrc:/qt-project.org/imports/Qt/labs/controls/images/check.png" - visible: control.checked + visible: control.checkState === Qt.Checked + } + + Rectangle { + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + width: 16 + height: 3 + color: "#353637" + visible: control.checkState === Qt.PartiallyChecked } } //! [indicator] diff --git a/src/imports/controls/material/CheckBox.qml b/src/imports/controls/material/CheckBox.qml index 1c3e254b..5becfc5c 100644 --- a/src/imports/controls/material/CheckBox.qml +++ b/src/imports/controls/material/CheckBox.qml @@ -100,15 +100,29 @@ T.CheckBox { source: "qrc:/qt-project.org/imports/Qt/labs/controls/material/images/check.png" fillMode: Image.PreserveAspectFit - scale: control.checked ? 1 : 0 + scale: control.checkState === Qt.Checked ? 1 : 0 Behavior on scale { NumberAnimation { duration: 100 } } } - states: State { - name: "checked" - when: control.checked + Rectangle { + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + width: 12 + height: 3 + visible: control.checkState === Qt.PartiallyChecked } + states: [ + State { + name: "checked" + when: control.checkState === Qt.Checked + }, + State { + name: "partiallychecked" + when: control.checkState === Qt.PartiallyChecked + } + ] + transitions: Transition { SequentialAnimation { NumberAnimation { -- cgit v1.2.3 From 3d246f823273518b594c17c17827ce165fd116e1 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Sat, 30 Jan 2016 10:11:28 +0100 Subject: Material ComboBox: round popup corners Change-Id: I644ab29bd814119cd3b631925cded8fc5bda4244 Reviewed-by: J-P Nurmi --- src/imports/controls/material/ComboBox.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/imports/controls/material/ComboBox.qml b/src/imports/controls/material/ComboBox.qml index f556107c..1aecaa3f 100644 --- a/src/imports/controls/material/ComboBox.qml +++ b/src/imports/controls/material/ComboBox.qml @@ -133,6 +133,7 @@ T.ComboBox { } background: Rectangle { + radius: 3 color: control.Material.dialogColor layer.enabled: control.enabled -- cgit v1.2.3 From 165578534d9b1a0e09f4374852ad12bd153a6889 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Sat, 30 Jan 2016 10:45:28 +0100 Subject: Popup: improve positioning Don't spend time repositioning while hidden, but make sure to reposition when the popup item is resized, or when the popup itself becomes visible. This fixes the issue that a ComboBox popup wasn't positioned inside the window when shown initially, until the ComboBox itself moved. Change-Id: I1456dc647e35b6eb9ec2c60dbe9bc9229f932e24 Reviewed-by: J-P Nurmi --- src/templates/qquickpopup.cpp | 13 +++++++++---- src/templates/qquickpopup_p_p.h | 4 ++-- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/templates/qquickpopup.cpp b/src/templates/qquickpopup.cpp index 2db7488c..b1987b25 100644 --- a/src/templates/qquickpopup.cpp +++ b/src/templates/qquickpopup.cpp @@ -323,7 +323,8 @@ void QQuickPopupPositioner::setX(qreal x) { if (m_x != x) { m_x = x; - repositionPopup(); + if (m_popup->overlay) // isVisible + repositionPopup(); } } @@ -336,7 +337,8 @@ void QQuickPopupPositioner::setY(qreal y) { if (m_y != y) { m_y = y; - repositionPopup(); + if (m_popup->overlay) // isVisible + repositionPopup(); } } @@ -363,12 +365,14 @@ void QQuickPopupPositioner::setParentItem(QQuickItem *parent) QQuickItemPrivate::get(parent)->addItemChangeListener(this, ItemChangeTypes); addAncestorListeners(parent->parentItem()); - repositionPopup(); + if (m_popup->overlay) // isVisible + repositionPopup(); } void QQuickPopupPositioner::itemGeometryChanged(QQuickItem *, const QRectF &, const QRectF &) { - repositionPopup(); + if (m_popup->overlay) // isVisible + repositionPopup(); } void QQuickPopupPositioner::itemParentChanged(QQuickItem *, QQuickItem *parent) @@ -1295,6 +1299,7 @@ void QQuickPopup::geometryChanged(const QRectF &newGeometry, const QRectF &oldGe Q_D(QQuickPopup); d->resizeBackground(); d->resizeContent(); + d->positioner.repositionPopup(); if (!qFuzzyCompare(newGeometry.width(), oldGeometry.width())) { emit widthChanged(); emit availableWidthChanged(); diff --git a/src/templates/qquickpopup_p_p.h b/src/templates/qquickpopup_p_p.h index f5aac221..447f1612 100644 --- a/src/templates/qquickpopup_p_p.h +++ b/src/templates/qquickpopup_p_p.h @@ -124,6 +124,8 @@ public: QQuickItem *parentItem() const; void setParentItem(QQuickItem *parent); + void repositionPopup(); + protected: void itemGeometryChanged(QQuickItem *, const QRectF &, const QRectF &); void itemParentChanged(QQuickItem *, QQuickItem *parent); @@ -131,8 +133,6 @@ protected: void itemDestroyed(QQuickItem *item); private: - void repositionPopup(); - void removeAncestorListeners(QQuickItem *item); void addAncestorListeners(QQuickItem *item); -- cgit v1.2.3 From d101dd653eae63797def798c05bbb7ff29739d68 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Sat, 30 Jan 2016 10:24:30 +0100 Subject: Add Popup::margins Allow specifying margins around the popup that are taken into account while positioning the popup. For example, the Material style draws a drop shadow that goes outside the popups bounds. This allows it to specify margins so that the drop shadow doesn't get clipped. Other use case is to specify the margins so that the popup doesn't overlap with window header or footer. Change-Id: I018d961259fa8b960d86b77de01413eefb75a59b Reviewed-by: J-P Nurmi --- src/templates/qquickpopup.cpp | 226 +++++++++++++++++++++++++++++++++++++++- src/templates/qquickpopup_p.h | 31 ++++++ src/templates/qquickpopup_p_p.h | 16 +++ 3 files changed, 271 insertions(+), 2 deletions(-) diff --git a/src/templates/qquickpopup.cpp b/src/templates/qquickpopup.cpp index b1987b25..185ad073 100644 --- a/src/templates/qquickpopup.cpp +++ b/src/templates/qquickpopup.cpp @@ -71,10 +71,19 @@ QQuickPopupPrivate::QQuickPopupPrivate() : QObjectPrivate() , focus(false) , modal(false) + , hasTopMargin(false) + , hasLeftMargin(false) + , hasRightMargin(false) + , hasBottomMargin(false) , hasTopPadding(false) , hasLeftPadding(false) , hasRightPadding(false) , hasBottomPadding(false) + , margins(0) + , topMargin(0) + , leftMargin(0) + , rightMargin(0) + , bottomMargin(0) , padding(0) , topPadding(0) , leftPadding(0) @@ -143,6 +152,64 @@ void QQuickPopupPrivate::resizeContent() } } +QMarginsF QQuickPopupPrivate::getMargins() const +{ + Q_Q(const QQuickPopup); + return QMarginsF(q->leftMargin(), q->topMargin(), q->rightMargin(), q->bottomMargin()); +} + +void QQuickPopupPrivate::setTopMargin(qreal value, bool reset) +{ + Q_Q(QQuickPopup); + qreal oldMargin = q->topMargin(); + topMargin = value; + hasTopMargin = !reset; + if ((!reset && !qFuzzyCompare(oldMargin, value)) || (reset && !qFuzzyCompare(oldMargin, margins))) { + emit q->topMarginChanged(); + q->marginsChange(QMarginsF(leftMargin, topMargin, rightMargin, bottomMargin), + QMarginsF(leftMargin, oldMargin, rightMargin, bottomMargin)); + } +} + +void QQuickPopupPrivate::setLeftMargin(qreal value, bool reset) +{ + Q_Q(QQuickPopup); + qreal oldMargin = q->leftMargin(); + leftMargin = value; + hasLeftMargin = !reset; + if ((!reset && !qFuzzyCompare(oldMargin, value)) || (reset && !qFuzzyCompare(oldMargin, margins))) { + emit q->leftMarginChanged(); + q->marginsChange(QMarginsF(leftMargin, topMargin, rightMargin, bottomMargin), + QMarginsF(oldMargin, topMargin, rightMargin, bottomMargin)); + } +} + +void QQuickPopupPrivate::setRightMargin(qreal value, bool reset) +{ + Q_Q(QQuickPopup); + qreal oldMargin = q->rightMargin(); + rightMargin = value; + hasRightMargin = !reset; + if ((!reset && !qFuzzyCompare(oldMargin, value)) || (reset && !qFuzzyCompare(oldMargin, margins))) { + emit q->rightMarginChanged(); + q->marginsChange(QMarginsF(leftMargin, topMargin, rightMargin, bottomMargin), + QMarginsF(leftMargin, topMargin, oldMargin, bottomMargin)); + } +} + +void QQuickPopupPrivate::setBottomMargin(qreal value, bool reset) +{ + Q_Q(QQuickPopup); + qreal oldMargin = q->bottomMargin(); + bottomMargin = value; + hasBottomMargin = !reset; + if ((!reset && !qFuzzyCompare(oldMargin, value)) || (reset && !qFuzzyCompare(oldMargin, margins))) { + emit q->bottomMarginChanged(); + q->marginsChange(QMarginsF(leftMargin, topMargin, rightMargin, bottomMargin), + QMarginsF(leftMargin, topMargin, rightMargin, oldMargin)); + } +} + void QQuickPopupPrivate::setTopPadding(qreal value, bool reset) { Q_Q(QQuickPopup); @@ -403,10 +470,11 @@ void QQuickPopupPositioner::repositionPopup() QQuickWindow *window = m_parentItem->window(); if (window) { - if (rect.top() < 0 || rect.bottom() > window->height()) { + QRectF bounds = QRectF(0, 0, window->width(), window->height()).marginsRemoved(m_popup->getMargins()); + if (rect.top() < bounds.top() || rect.bottom() > bounds.bottom()) { // if the popup doesn't fit on the screen, try flipping it around (below <-> above) QRectF flipped = m_parentItem->mapRectToScene(QRectF(m_x, m_parentItem->height() - m_y - rect.height(), rect.width(), rect.height())); - if (flipped.y() >= 0 && flipped.bottom() < window->height()) + if (flipped.top() >= bounds.top() && flipped.bottom() < bounds.bottom()) rect = flipped; } } @@ -760,6 +828,152 @@ qreal QQuickPopup::availableHeight() const return qMax(0.0, height() - topPadding() - bottomPadding()); } +/*! + \qmlproperty real Qt.labs.controls::Popup::margins + + This property holds the default margins around the popup. + + \sa topMargin, leftMargin, rightMargin, bottomMargin +*/ +qreal QQuickPopup::margins() const +{ + Q_D(const QQuickPopup); + return d->margins; +} + +void QQuickPopup::setMargins(qreal margins) +{ + Q_D(QQuickPopup); + if (qFuzzyCompare(d->margins, margins)) + return; + QMarginsF oldMargins(leftMargin(), topMargin(), rightMargin(), bottomMargin()); + d->margins = margins; + emit marginsChanged(); + QMarginsF newMargins(leftMargin(), topMargin(), rightMargin(), bottomMargin()); + if (!qFuzzyCompare(newMargins.top(), oldMargins.top())) + emit topMarginChanged(); + if (!qFuzzyCompare(newMargins.left(), oldMargins.left())) + emit leftMarginChanged(); + if (!qFuzzyCompare(newMargins.right(), oldMargins.right())) + emit rightMarginChanged(); + if (!qFuzzyCompare(newMargins.bottom(), oldMargins.bottom())) + emit bottomMarginChanged(); + marginsChange(newMargins, oldMargins); +} + +void QQuickPopup::resetMargins() +{ + setMargins(0); +} + +/*! + \qmlproperty real Qt.labs.controls::Popup::topMargin + + This property holds the top margin around the popup. + + \sa margin, bottomMargin +*/ +qreal QQuickPopup::topMargin() const +{ + Q_D(const QQuickPopup); + if (d->hasTopMargin) + return d->topMargin; + return d->margins; +} + +void QQuickPopup::setTopMargin(qreal margin) +{ + Q_D(QQuickPopup); + d->setTopMargin(margin); +} + +void QQuickPopup::resetTopMargin() +{ + Q_D(QQuickPopup); + d->setTopMargin(0, true); +} + +/*! + \qmlproperty real Qt.labs.controls::Popup::leftMargin + + This property holds the left margin around the popup. + + \sa margin, rightMargin +*/ +qreal QQuickPopup::leftMargin() const +{ + Q_D(const QQuickPopup); + if (d->hasLeftMargin) + return d->leftMargin; + return d->margins; +} + +void QQuickPopup::setLeftMargin(qreal margin) +{ + Q_D(QQuickPopup); + d->setLeftMargin(margin); +} + +void QQuickPopup::resetLeftMargin() +{ + Q_D(QQuickPopup); + d->setLeftMargin(0, true); +} + +/*! + \qmlproperty real Qt.labs.controls::Popup::rightMargin + + This property holds the right margin around the popup. + + \sa margin, leftMargin +*/ +qreal QQuickPopup::rightMargin() const +{ + Q_D(const QQuickPopup); + if (d->hasRightMargin) + return d->rightMargin; + return d->margins; +} + +void QQuickPopup::setRightMargin(qreal margin) +{ + Q_D(QQuickPopup); + d->setRightMargin(margin); +} + +void QQuickPopup::resetRightMargin() +{ + Q_D(QQuickPopup); + d->setRightMargin(0, true); +} + +/*! + \qmlproperty real Qt.labs.controls::Popup::bottomMargin + + This property holds the bottom margin around the popup. + + \sa margin, topMargin +*/ +qreal QQuickPopup::bottomMargin() const +{ + Q_D(const QQuickPopup); + if (d->hasBottomMargin) + return d->bottomMargin; + return d->margins; +} + +void QQuickPopup::setBottomMargin(qreal margin) +{ + Q_D(QQuickPopup); + d->setBottomMargin(margin); +} + +void QQuickPopup::resetBottomMargin() +{ + Q_D(QQuickPopup); + d->setBottomMargin(0, true); +} + /*! \qmlproperty real Qt.labs.controls::Popup::padding @@ -1310,6 +1524,14 @@ void QQuickPopup::geometryChanged(const QRectF &newGeometry, const QRectF &oldGe } } +void QQuickPopup::marginsChange(const QMarginsF &newMargins, const QMarginsF &oldMargins) +{ + Q_D(QQuickPopup); + Q_UNUSED(newMargins); + Q_UNUSED(oldMargins); + d->positioner.repositionPopup(); +} + void QQuickPopup::paddingChange(const QMarginsF &newPadding, const QMarginsF &oldPadding) { Q_D(QQuickPopup); diff --git a/src/templates/qquickpopup_p.h b/src/templates/qquickpopup_p.h index 6c51c46a..e2d89c66 100644 --- a/src/templates/qquickpopup_p.h +++ b/src/templates/qquickpopup_p.h @@ -77,6 +77,11 @@ class Q_LABSTEMPLATES_EXPORT QQuickPopup : public QObject, public QQmlParserStat Q_PROPERTY(qreal contentHeight READ contentHeight WRITE setContentHeight NOTIFY contentHeightChanged FINAL) Q_PROPERTY(qreal availableWidth READ availableWidth NOTIFY availableWidthChanged FINAL) Q_PROPERTY(qreal availableHeight READ availableHeight NOTIFY availableHeightChanged FINAL) + Q_PROPERTY(qreal margins READ margins WRITE setMargins RESET resetMargins NOTIFY marginsChanged FINAL) + Q_PROPERTY(qreal topMargin READ topMargin WRITE setTopMargin RESET resetTopMargin NOTIFY topMarginChanged FINAL) + Q_PROPERTY(qreal leftMargin READ leftMargin WRITE setLeftMargin RESET resetLeftMargin NOTIFY leftMarginChanged FINAL) + Q_PROPERTY(qreal rightMargin READ rightMargin WRITE setRightMargin RESET resetRightMargin NOTIFY rightMarginChanged FINAL) + Q_PROPERTY(qreal bottomMargin READ bottomMargin WRITE setBottomMargin RESET resetBottomMargin NOTIFY bottomMarginChanged FINAL) Q_PROPERTY(qreal padding READ padding WRITE setPadding RESET resetPadding NOTIFY paddingChanged FINAL) Q_PROPERTY(qreal topPadding READ topPadding WRITE setTopPadding RESET resetTopPadding NOTIFY topPaddingChanged FINAL) Q_PROPERTY(qreal leftPadding READ leftPadding WRITE setLeftPadding RESET resetLeftPadding NOTIFY leftPaddingChanged FINAL) @@ -129,6 +134,26 @@ public: qreal availableWidth() const; qreal availableHeight() const; + qreal margins() const; + void setMargins(qreal margins); + void resetMargins(); + + qreal topMargin() const; + void setTopMargin(qreal margin); + void resetTopMargin(); + + qreal leftMargin() const; + void setLeftMargin(qreal margin); + void resetLeftMargin(); + + qreal rightMargin() const; + void setRightMargin(qreal margin); + void resetRightMargin(); + + qreal bottomMargin() const; + void setBottomMargin(qreal margin); + void resetBottomMargin(); + qreal padding() const; void setPadding(qreal padding); void resetPadding(); @@ -220,6 +245,11 @@ Q_SIGNALS: void contentHeightChanged(); void availableWidthChanged(); void availableHeightChanged(); + void marginsChanged(); + void topMarginChanged(); + void leftMarginChanged(); + void rightMarginChanged(); + void bottomMarginChanged(); void paddingChanged(); void topPaddingChanged(); void leftPaddingChanged(); @@ -259,6 +289,7 @@ protected: virtual void contentItemChange(QQuickItem *newItem, QQuickItem *oldItem); virtual void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry); + virtual void marginsChange(const QMarginsF &newMargins, const QMarginsF &oldMargins); virtual void paddingChange(const QMarginsF &newPadding, const QMarginsF &oldPadding); private: diff --git a/src/templates/qquickpopup_p_p.h b/src/templates/qquickpopup_p_p.h index 447f1612..f27ed762 100644 --- a/src/templates/qquickpopup_p_p.h +++ b/src/templates/qquickpopup_p_p.h @@ -164,6 +164,13 @@ public: void resizeBackground(); void resizeContent(); + QMarginsF getMargins() const; + + void setTopMargin(qreal value, bool reset = false); + void setLeftMargin(qreal value, bool reset = false); + void setRightMargin(qreal value, bool reset = false); + void setBottomMargin(qreal value, bool reset = false); + void setTopPadding(qreal value, bool reset = false); void setLeftPadding(qreal value, bool reset = false); void setRightPadding(qreal value, bool reset = false); @@ -172,10 +179,19 @@ public: bool focus; bool modal; bool complete; + bool hasTopMargin; + bool hasLeftMargin; + bool hasRightMargin; + bool hasBottomMargin; bool hasTopPadding; bool hasLeftPadding; bool hasRightPadding; bool hasBottomPadding; + qreal margins; + qreal topMargin; + qreal leftMargin; + qreal rightMargin; + qreal bottomMargin; qreal padding; qreal topPadding; qreal leftPadding; -- cgit v1.2.3 From fcb7cb051ce56bb913732501ab1271ef7738efba Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Sat, 30 Jan 2016 16:10:13 +0100 Subject: Update plugins.qmltypes Change-Id: I1b7c15c57ca491561bf082ab53967455a6299529 Reviewed-by: J-P Nurmi --- src/imports/controls/plugins.qmltypes | 13 ++++++++++--- src/imports/templates/plugins.qmltypes | 13 ++++++++++--- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/imports/controls/plugins.qmltypes b/src/imports/controls/plugins.qmltypes index d52c6153..75805fdd 100644 --- a/src/imports/controls/plugins.qmltypes +++ b/src/imports/controls/plugins.qmltypes @@ -363,9 +363,11 @@ Module { name: "ClosePolicy" values: { "NoAutoClose": 0, - "CloseOnPressOutside": 1, - "CloseOnReleaseOutside": 2, - "CloseOnEscape": 4 + "OnPressOutside": 1, + "OnPressOutsideParent": 2, + "OnReleaseOutside": 4, + "OnReleaseOutsideParent": 8, + "OnEscape": 16 } } Enum { @@ -392,6 +394,11 @@ Module { Property { name: "contentHeight"; type: "double" } Property { name: "availableWidth"; type: "double"; isReadonly: true } Property { name: "availableHeight"; type: "double"; isReadonly: true } + Property { name: "margins"; type: "double" } + Property { name: "topMargin"; type: "double" } + Property { name: "leftMargin"; type: "double" } + Property { name: "rightMargin"; type: "double" } + Property { name: "bottomMargin"; type: "double" } Property { name: "padding"; type: "double" } Property { name: "topPadding"; type: "double" } Property { name: "leftPadding"; type: "double" } diff --git a/src/imports/templates/plugins.qmltypes b/src/imports/templates/plugins.qmltypes index 67058870..d96563a7 100644 --- a/src/imports/templates/plugins.qmltypes +++ b/src/imports/templates/plugins.qmltypes @@ -357,9 +357,11 @@ Module { name: "ClosePolicy" values: { "NoAutoClose": 0, - "CloseOnPressOutside": 1, - "CloseOnReleaseOutside": 2, - "CloseOnEscape": 4 + "OnPressOutside": 1, + "OnPressOutsideParent": 2, + "OnReleaseOutside": 4, + "OnReleaseOutsideParent": 8, + "OnEscape": 16 } } Enum { @@ -386,6 +388,11 @@ Module { Property { name: "contentHeight"; type: "double" } Property { name: "availableWidth"; type: "double"; isReadonly: true } Property { name: "availableHeight"; type: "double"; isReadonly: true } + Property { name: "margins"; type: "double" } + Property { name: "topMargin"; type: "double" } + Property { name: "leftMargin"; type: "double" } + Property { name: "rightMargin"; type: "double" } + Property { name: "bottomMargin"; type: "double" } Property { name: "padding"; type: "double" } Property { name: "topPadding"; type: "double" } Property { name: "leftPadding"; type: "double" } -- cgit v1.2.3 From e7b526e08447bdea0b7c33f6d9e7bc3734f4796c Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Fri, 29 Jan 2016 19:59:06 +0100 Subject: Try harder to keep popups inside the window Change-Id: If9010f5694c1012a1eb7fb93dcb8958f0af49e9b Reviewed-by: J-P Nurmi --- src/templates/qquickpopup.cpp | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/src/templates/qquickpopup.cpp b/src/templates/qquickpopup.cpp index 185ad073..8937eb1f 100644 --- a/src/templates/qquickpopup.cpp +++ b/src/templates/qquickpopup.cpp @@ -464,23 +464,44 @@ void QQuickPopupPositioner::itemDestroyed(QQuickItem *item) void QQuickPopupPositioner::repositionPopup() { - QRectF rect(m_x, m_y, m_popup->popupItem->width(), m_popup->popupItem->height()); + const qreal w = m_popup->popupItem->width(); + const qreal h = m_popup->popupItem->height(); + const qreal iw = m_popup->popupItem->implicitWidth(); + const qreal ih = m_popup->popupItem->implicitHeight(); + + QRectF rect(m_x, m_y, iw > 0 ? iw : w, ih > 0 ? ih : h); if (m_parentItem) { rect = m_parentItem->mapRectToScene(rect); QQuickWindow *window = m_parentItem->window(); if (window) { - QRectF bounds = QRectF(0, 0, window->width(), window->height()).marginsRemoved(m_popup->getMargins()); + const QRectF bounds = QRectF(0, 0, window->width(), window->height()).marginsRemoved(m_popup->getMargins()); if (rect.top() < bounds.top() || rect.bottom() > bounds.bottom()) { - // if the popup doesn't fit on the screen, try flipping it around (below <-> above) - QRectF flipped = m_parentItem->mapRectToScene(QRectF(m_x, m_parentItem->height() - m_y - rect.height(), rect.width(), rect.height())); - if (flipped.top() >= bounds.top() && flipped.bottom() < bounds.bottom()) + // if the popup doesn't fit inside the window, try flipping it around (below <-> above) + const QRectF flipped = m_parentItem->mapRectToScene(QRectF(m_x, m_parentItem->height() - m_y - rect.height(), rect.width(), rect.height())); + if (flipped.top() >= bounds.top() && flipped.bottom() < bounds.bottom()) { rect = flipped; + } else if (ih > 0) { + // neither the flipped around geometry fits inside the window, choose + // whichever side (above vs. below) fits larger part of the popup + const QRectF primary = rect.intersected(bounds); + const QRectF secondary = flipped.intersected(bounds); + + if (primary.height() > secondary.height()) { + rect.setY(primary.y()); + rect.setHeight(primary.height()); + } else { + rect.setY(secondary.y()); + rect.setHeight(secondary.height()); + } + } } } } m_popup->popupItem->setPosition(rect.topLeft()); + if (ih > 0) + m_popup->popupItem->setHeight(rect.height()); } void QQuickPopupPositioner::removeAncestorListeners(QQuickItem *item) -- cgit v1.2.3 From cb86fefb321a05eb50b905a696401542acf7d441 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Sat, 30 Jan 2016 16:21:16 +0100 Subject: Allow ComboBox popup to use more screen space Change-Id: Icd2ee375d7886c1d4d61577fc9e196cfa5d910d1 Task-number: QTBUG-50758 Reviewed-by: J-P Nurmi --- src/imports/controls/ComboBox.qml | 4 +++- src/imports/controls/material/ComboBox.qml | 4 +++- src/imports/controls/universal/ComboBox.qml | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/imports/controls/ComboBox.qml b/src/imports/controls/ComboBox.qml index e0e8d76f..189eed92 100644 --- a/src/imports/controls/ComboBox.qml +++ b/src/imports/controls/ComboBox.qml @@ -100,7 +100,9 @@ T.ComboBox { popup: T.Popup { y: control.height - 1 implicitWidth: control.width - implicitHeight: Math.min(200, listview.contentHeight) + implicitHeight: Math.min(396, listview.contentHeight) + topMargin: 6 + bottomMargin: 6 contentItem: ListView { id: listview diff --git a/src/imports/controls/material/ComboBox.qml b/src/imports/controls/material/ComboBox.qml index 1aecaa3f..351feead 100644 --- a/src/imports/controls/material/ComboBox.qml +++ b/src/imports/controls/material/ComboBox.qml @@ -108,8 +108,10 @@ T.ComboBox { popup: T.Popup { y: control.height implicitWidth: control.width - implicitHeight: Math.min(200, listview.contentHeight) + implicitHeight: Math.min(396, listview.contentHeight) transformOrigin: Item.Top + topMargin: 12 + bottomMargin: 12 enter: Transition { // grow_fade_in diff --git a/src/imports/controls/universal/ComboBox.qml b/src/imports/controls/universal/ComboBox.qml index e450685f..5c0f1004 100644 --- a/src/imports/controls/universal/ComboBox.qml +++ b/src/imports/controls/universal/ComboBox.qml @@ -110,7 +110,9 @@ T.ComboBox { //! [popup] popup: T.Popup { implicitWidth: control.width - implicitHeight: Math.min(200, listview.contentHeight) // TODO: 396 + implicitHeight: Math.min(396, listview.contentHeight) + topMargin: 8 + bottomMargin: 8 contentItem: ListView { id: listview -- cgit v1.2.3 From 7fc567eda8a187e365f4c29c6e8f08440bf31218 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Sat, 30 Jan 2016 17:21:55 +0100 Subject: Make popups work without ApplicationWindow, to some degree Using ApplicationWindow is highly recommended. First of all, with a plain Window, QQuickPopup attempts to set a high z-value, but cannot guarantee correct stacking order. Secondly, we cannot provide style- specific background dimming for modal popups, because it is styled as part of ApplicationWindow. Last but not least, QQuickPopup has to install a window-level event filter, which is far less efficient than how event handling done in QQuickOverlay. Change-Id: I08915abce7a1764177b92f7539eef77c054a405a Task-number: QTBUG-49921 Reviewed-by: J-P Nurmi --- src/imports/controls/Drawer.qml | 3 +- src/imports/controls/material/Drawer.qml | 3 +- src/templates/qquickcombobox.cpp | 4 + src/templates/qquickmenu.cpp | 9 +-- src/templates/qquickoverlay.cpp | 59 ++++---------- src/templates/qquickpopup.cpp | 129 +++++++++++++++++++++---------- src/templates/qquickpopup_p.h | 1 + src/templates/qquickpopup_p_p.h | 4 +- 8 files changed, 118 insertions(+), 94 deletions(-) diff --git a/src/imports/controls/Drawer.qml b/src/imports/controls/Drawer.qml index eb4e3e57..60abeb0c 100644 --- a/src/imports/controls/Drawer.qml +++ b/src/imports/controls/Drawer.qml @@ -35,12 +35,13 @@ ****************************************************************************/ import QtQuick 2.6 +import QtQuick.Window 2.2 import Qt.labs.templates 1.0 as T T.Drawer { id: control - parent: T.ApplicationWindow.overlay + parent: T.ApplicationWindow.overlay || Window.contentItem width: parent ? parent.width : 0 // TODO: Window.width height: parent ? parent.height : 0 // TODO: Window.height diff --git a/src/imports/controls/material/Drawer.qml b/src/imports/controls/material/Drawer.qml index cb00096d..133ea9c8 100644 --- a/src/imports/controls/material/Drawer.qml +++ b/src/imports/controls/material/Drawer.qml @@ -35,13 +35,14 @@ ****************************************************************************/ import QtQuick 2.6 +import QtQuick.Window 2.2 import Qt.labs.templates 1.0 as T import Qt.labs.controls.material 1.0 T.Drawer { id: control - parent: T.ApplicationWindow.overlay + parent: T.ApplicationWindow.overlay || Window.contentItem width: parent ? parent.width : 0 // TODO: Window.width height: parent ? parent.height : 0 // TODO: Window.height diff --git a/src/templates/qquickcombobox.cpp b/src/templates/qquickcombobox.cpp index f4cb17af..dfb01e83 100644 --- a/src/templates/qquickcombobox.cpp +++ b/src/templates/qquickcombobox.cpp @@ -711,6 +711,10 @@ void QQuickComboBox::keyPressEvent(QKeyEvent *event) return; switch (event->key()) { + case Qt::Key_Escape: + if (d->isPopupVisible()) + event->accept(); + break; case Qt::Key_Space: if (!event->isAutoRepeat()) setPressed(true); diff --git a/src/templates/qquickmenu.cpp b/src/templates/qquickmenu.cpp index 692395ff..d3fc88d9 100644 --- a/src/templates/qquickmenu.cpp +++ b/src/templates/qquickmenu.cpp @@ -489,11 +489,8 @@ void QQuickMenu::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) bool QQuickMenu::eventFilter(QObject *object, QEvent *event) { Q_D(QQuickMenu); - if (d->contentModel->count() == 0) - return false; - - if (object != d->contentItem || event->type() != QEvent::KeyRelease) - return false; + if (object != d->contentItem || event->type() != QEvent::KeyRelease || d->contentModel->count() == 0) + return QQuickPopup::eventFilter(object, event); // QTBUG-17051 // Work around the fact that ListView has no way of distinguishing between @@ -517,7 +514,7 @@ bool QQuickMenu::eventFilter(QObject *object, QEvent *event) break; } - return false; + return QQuickPopup::eventFilter(object, event); } QT_END_NAMESPACE diff --git a/src/templates/qquickoverlay.cpp b/src/templates/qquickoverlay.cpp index 589cafdf..dd9d2c5d 100644 --- a/src/templates/qquickoverlay.cpp +++ b/src/templates/qquickoverlay.cpp @@ -35,7 +35,7 @@ ****************************************************************************/ #include "qquickoverlay_p.h" -#include "qquickpopup_p.h" +#include "qquickpopup_p_p.h" #include "qquickdrawer_p.h" #include #include @@ -52,13 +52,12 @@ public: void popupAboutToShow(); void popupAboutToHide(); - void closePopup(QQuickPopup *popup, QMouseEvent *event); void drawerPositionChange(); void resizeBackground(); QQuickItem *background; QVector drawers; - QHash popups; + QVector popups; int modalPopups; }; @@ -90,30 +89,6 @@ void QQuickOverlayPrivate::popupAboutToHide() QQmlProperty::write(background, QStringLiteral("opacity"), 0.0); } -void QQuickOverlayPrivate::closePopup(QQuickPopup *popup, QMouseEvent *event) -{ - Q_Q(QQuickOverlay); - const bool isPress = event->type() == QEvent::MouseButtonPress; - const bool onOutside = popup->closePolicy().testFlag(isPress ? QQuickPopup::OnPressOutside : QQuickPopup::OnReleaseOutside); - const bool onOutsideParent = popup->closePolicy().testFlag(isPress ? QQuickPopup::OnPressOutsideParent : QQuickPopup::OnReleaseOutsideParent); - if (onOutside || onOutsideParent) { - QQuickItem *popupItem = popup->popupItem(); - QQuickItem *parentItem = popup->parentItem(); - - if (onOutside && onOutsideParent) { - if (!popupItem->contains(q->mapToItem(popupItem, event->pos())) && - (!parentItem || !parentItem->contains(q->mapToItem(parentItem, event->pos())))) - popup->close(); - } else if (onOutside) { - if (!popupItem->contains(q->mapToItem(popupItem, event->pos()))) - popup->close(); - } else if (onOutsideParent) { - if (!parentItem || !parentItem->contains(q->mapToItem(parentItem, event->pos()))) - popup->close(); - } - } -} - void QQuickOverlayPrivate::drawerPositionChange() { Q_Q(QQuickOverlay); @@ -197,27 +172,19 @@ void QQuickOverlay::itemChange(ItemChange change, const ItemChangeData &data) return; if (change == ItemChildAddedChange) { - if (QQuickPopup *prevPopup = d->popups.value(data.item)) { - qmlInfo(popup).nospace() << "Popup is sharing item " << data.item << " with " << prevPopup - << ". This is not supported and strange things are about to happen."; - return; - } - - d->popups.insert(data.item, popup); + d->popups.append(popup); if (popup->isModal()) ++d->modalPopups; QObjectPrivate::connect(popup, &QQuickPopup::aboutToShow, d, &QQuickOverlayPrivate::popupAboutToShow); QObjectPrivate::connect(popup, &QQuickPopup::aboutToHide, d, &QQuickOverlayPrivate::popupAboutToHide); } else if (change == ItemChildRemovedChange) { - Q_ASSERT(popup == d->popups.value(data.item)); + d->popups.removeOne(popup); + if (popup->isModal()) + --d->modalPopups; QObjectPrivate::disconnect(popup, &QQuickPopup::aboutToShow, d, &QQuickOverlayPrivate::popupAboutToShow); QObjectPrivate::disconnect(popup, &QQuickPopup::aboutToHide, d, &QQuickOverlayPrivate::popupAboutToHide); - - if (popup->isModal()) - --d->modalPopups; - d->popups.remove(data.item); } } @@ -247,8 +214,10 @@ void QQuickOverlay::mousePressEvent(QMouseEvent *event) event->setAccepted(d->modalPopups > 0); emit pressed(); - foreach (QQuickPopup *popup, d->popups) - d->closePopup(popup, event); + for (int i = d->popups.count() - 1; i >= 0; --i) { + if (QQuickPopupPrivate::get(d->popups.at(i))->tryClose(this, event)) + break; + } } void QQuickOverlay::mouseMoveEvent(QMouseEvent *event) @@ -263,8 +232,10 @@ void QQuickOverlay::mouseReleaseEvent(QMouseEvent *event) event->setAccepted(d->modalPopups > 0); emit released(); - foreach (QQuickPopup *popup, d->popups) - d->closePopup(popup, event); + for (int i = d->popups.count() - 1; i >= 0; --i) { + if (QQuickPopupPrivate::get(d->popups.at(i))->tryClose(this, event)) + break; + } } void QQuickOverlay::wheelEvent(QWheelEvent *event) @@ -292,7 +263,7 @@ bool QQuickOverlay::childMouseEventFilter(QQuickItem *item, QEvent *event) if (popupItem == item) break; - QQuickPopup *popup = d->popups.value(popupItem); + QQuickPopup *popup = qobject_cast(popupItem->parent()); if (popup) { QQuickPopup::ClosePolicy policy = popup->closePolicy(); if (policy.testFlag(QQuickPopup::OnPressOutside) || policy.testFlag(QQuickPopup::OnPressOutsideParent)) diff --git a/src/templates/qquickpopup.cpp b/src/templates/qquickpopup.cpp index 8937eb1f..99525986 100644 --- a/src/templates/qquickpopup.cpp +++ b/src/templates/qquickpopup.cpp @@ -95,7 +95,6 @@ QQuickPopupPrivate::QQuickPopupPrivate() , parentItem(Q_NULLPTR) , background(Q_NULLPTR) , contentItem(Q_NULLPTR) - , overlay(Q_NULLPTR) , enter(Q_NULLPTR) , exit(Q_NULLPTR) , popupItem(Q_NULLPTR) @@ -108,10 +107,32 @@ void QQuickPopupPrivate::init() { Q_Q(QQuickPopup); popupItem = new QQuickPopupItem(q); - popupItem->setParent(q); q->setParentItem(qobject_cast(parent)); } +bool QQuickPopupPrivate::tryClose(QQuickItem *item, QMouseEvent *event) +{ + Q_Q(QQuickPopup); + const bool isPress = event->type() == QEvent::MouseButtonPress; + const bool onOutside = closePolicy.testFlag(isPress ? QQuickPopup::OnPressOutside : QQuickPopup::OnReleaseOutside); + const bool onOutsideParent = closePolicy.testFlag(isPress ? QQuickPopup::OnPressOutsideParent : QQuickPopup::OnReleaseOutsideParent); + if (onOutside || onOutsideParent) { + if (onOutsideParent) { + if (!popupItem->contains(item->mapToItem(popupItem, event->pos())) && + (!parentItem || !parentItem->contains(item->mapToItem(parentItem, event->pos())))) { + q->close(); + return true; + } + } else if (onOutside) { + if (!popupItem->contains(item->mapToItem(popupItem, event->pos()))) { + q->close(); + return true; + } + } + } + return false; +} + void QQuickPopupPrivate::finalizeEnterTransition() { if (focus) @@ -120,11 +141,9 @@ void QQuickPopupPrivate::finalizeEnterTransition() void QQuickPopupPrivate::finalizeExitTransition() { - Q_Q(QQuickPopup); - overlay = Q_NULLPTR; positioner.setParentItem(Q_NULLPTR); popupItem->setParentItem(Q_NULLPTR); - emit q->visibleChanged(); + popupItem->setVisible(false); } void QQuickPopupPrivate::resizeBackground() @@ -281,6 +300,7 @@ public: QQuickPopupItemPrivate::QQuickPopupItemPrivate(QQuickPopup *popup) : popup(popup) { + isTabFence = true; } void QQuickPopupItemPrivate::implicitWidthChanged() @@ -296,6 +316,9 @@ void QQuickPopupItemPrivate::implicitHeightChanged() QQuickPopupItem::QQuickPopupItem(QQuickPopup *popup) : QQuickItem(*(new QQuickPopupItemPrivate(popup))) { + setParent(popup); + setVisible(false); + setFlag(ItemIsFocusScope); setAcceptedMouseButtons(Qt::AllButtons); } @@ -365,6 +388,19 @@ void QQuickPopupItem::geometryChanged(const QRectF &newGeometry, const QRectF &o d->popup->geometryChanged(newGeometry, oldGeometry); } +void QQuickPopupItem::itemChange(ItemChange change, const ItemChangeData &data) +{ + Q_D(QQuickPopupItem); + QQuickItem::itemChange(change, data); + switch (change) { + case ItemVisibleHasChanged: + emit d->popup->visibleChanged(); + break; + default: + break; + } +} + QQuickPopupPositioner::QQuickPopupPositioner(QQuickPopupPrivate *popup) : m_x(0), m_y(0), @@ -390,7 +426,7 @@ void QQuickPopupPositioner::setX(qreal x) { if (m_x != x) { m_x = x; - if (m_popup->overlay) // isVisible + if (m_popup->popupItem->isVisible()) repositionPopup(); } } @@ -404,7 +440,7 @@ void QQuickPopupPositioner::setY(qreal y) { if (m_y != y) { m_y = y; - if (m_popup->overlay) // isVisible + if (m_popup->popupItem->isVisible()) repositionPopup(); } } @@ -432,13 +468,13 @@ void QQuickPopupPositioner::setParentItem(QQuickItem *parent) QQuickItemPrivate::get(parent)->addItemChangeListener(this, ItemChangeTypes); addAncestorListeners(parent->parentItem()); - if (m_popup->overlay) // isVisible + if (m_popup->popupItem->isVisible()) repositionPopup(); } void QQuickPopupPositioner::itemGeometryChanged(QQuickItem *, const QRectF &, const QRectF &) { - if (m_popup->overlay) // isVisible + if (m_popup->popupItem->isVisible()) repositionPopup(); } @@ -607,24 +643,12 @@ QQuickPopup::~QQuickPopup() void QQuickPopup::open() { Q_D(QQuickPopup); - if (d->overlay) { - // popup already open + if (d->popupItem->isVisible()) return; - } QQuickWindow *window = Q_NULLPTR; - QObject *p = parent(); - while (p && !window) { - if (QQuickItem *item = qobject_cast(p)) { - window = item->window(); - if (!window) - p = item->parentItem(); - } else { - window = qobject_cast(p); - if (!window) - p = p->parent(); - } - } + if (d->parentItem) + window = d->parentItem->window(); if (!window) { qmlInfo(this) << "cannot find any window to open popup in."; return; @@ -632,17 +656,17 @@ void QQuickPopup::open() QQuickApplicationWindow *applicationWindow = qobject_cast(window); if (!applicationWindow) { - // FIXME Maybe try to open it in that window somehow - qmlInfo(this) << "is not in an ApplicationWindow."; - return; + window->installEventFilter(this); + d->popupItem->setZ(10001); // DefaultWindowDecoration+1 + d->popupItem->setParentItem(window->contentItem()); + } else { + d->popupItem->setParentItem(applicationWindow->overlay()); } - d->overlay = static_cast(applicationWindow->overlay()); - d->popupItem->setParentItem(d->overlay); - d->positioner.setParentItem(d->parentItem); emit aboutToShow(); + d->popupItem->setVisible(true); + d->positioner.setParentItem(d->parentItem); d->transitionManager.transitionEnter(); - emit visibleChanged(); } /*! @@ -653,9 +677,14 @@ void QQuickPopup::open() void QQuickPopup::close() { Q_D(QQuickPopup); - if (!d->overlay) { - // popup already closed + if (!d->popupItem->isVisible()) return; + + if (d->parentItem) { + QQuickWindow *window = d->parentItem->window(); + if (!qobject_cast(window)) { + window->removeEventFilter(this); + } } d->popupItem->setFocus(false); @@ -1224,18 +1253,12 @@ QQuickItem *QQuickPopup::contentItem() const void QQuickPopup::setContentItem(QQuickItem *item) { Q_D(QQuickPopup); - if (d->overlay) { - // FIXME qmlInfo needs to know about QQuickItem and/or QObject - static_cast(qmlInfo(this) << "cannot set content item") << item << "while Popup is visible."; - return; - } if (d->contentItem != item) { contentItemChange(item, d->contentItem); delete d->contentItem; d->contentItem = item; if (item) { item->setParentItem(d->popupItem); - QQuickItemPrivate::get(item)->isTabFence = true; if (isComponentComplete()) d->resizeContent(); } @@ -1326,7 +1349,7 @@ void QQuickPopup::setModal(bool modal) bool QQuickPopup::isVisible() const { Q_D(const QQuickPopup); - return d->overlay != Q_NULLPTR /*&& !d->transitionManager.isRunning()*/; + return d->popupItem->isVisible(); } void QQuickPopup::setVisible(bool visible) @@ -1467,6 +1490,32 @@ bool QQuickPopup::isComponentComplete() const return d->complete; } +bool QQuickPopup::eventFilter(QObject *object, QEvent *event) +{ + Q_D(QQuickPopup); + Q_UNUSED(object); + switch (event->type()) { + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: + if (d->modal) + event->setAccepted(true); + if (QQuickWindow *window = qobject_cast(object)) { + if (d->tryClose(window->contentItem(), static_cast(event))) + return true; + } + return false; + case QEvent::KeyPress: + case QEvent::KeyRelease: + case QEvent::MouseMove: + case QEvent::Wheel: + if (d->modal) + event->setAccepted(true); + return false; + default: + return false; + } +} + void QQuickPopup::focusInEvent(QFocusEvent *event) { event->accept(); diff --git a/src/templates/qquickpopup_p.h b/src/templates/qquickpopup_p.h index e2d89c66..ac9a238a 100644 --- a/src/templates/qquickpopup_p.h +++ b/src/templates/qquickpopup_p.h @@ -276,6 +276,7 @@ protected: void componentComplete() Q_DECL_OVERRIDE; bool isComponentComplete() const; + bool eventFilter(QObject *object, QEvent *event) Q_DECL_OVERRIDE; virtual void focusInEvent(QFocusEvent *event); virtual void focusOutEvent(QFocusEvent *event); virtual void keyPressEvent(QKeyEvent *event); diff --git a/src/templates/qquickpopup_p_p.h b/src/templates/qquickpopup_p_p.h index f27ed762..29faa94e 100644 --- a/src/templates/qquickpopup_p_p.h +++ b/src/templates/qquickpopup_p_p.h @@ -60,7 +60,6 @@ QT_BEGIN_NAMESPACE class QQuickTransition; class QQuickTransitionManager; class QQuickPopup; -class QQuickOverlay; class QQuickPopupPrivate; class QQuickPopupItemPrivate; @@ -104,6 +103,7 @@ protected: void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE; void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) Q_DECL_OVERRIDE; + void itemChange(ItemChange change, const ItemChangeData &data) Q_DECL_OVERRIDE; private: Q_DECLARE_PRIVATE(QQuickPopupItem) @@ -157,6 +157,7 @@ public: } void init(); + bool tryClose(QQuickItem *item, QMouseEvent *event); void finalizeEnterTransition(); void finalizeExitTransition(); @@ -203,7 +204,6 @@ public: QQuickItem *parentItem; QQuickItem *background; QQuickItem *contentItem; - QQuickOverlay *overlay; QQuickTransition *enter; QQuickTransition *exit; QQuickPopupItem *popupItem; -- cgit v1.2.3