diff options
-rw-r--r-- | src/imports/controls/material/CheckIndicator.qml | 13 | ||||
-rw-r--r-- | src/imports/controls/material/MenuItem.qml | 1 | ||||
-rw-r--r-- | src/quicktemplates2/qquickcombobox.cpp | 18 | ||||
-rw-r--r-- | src/quicktemplates2/qquickcombobox_p.h | 1 | ||||
-rw-r--r-- | src/quicktemplates2/qquickrangeslider.cpp | 9 | ||||
-rw-r--r-- | src/quicktemplates2/qquickslider.cpp | 6 | ||||
-rw-r--r-- | tests/auto/controls/data/tst_combobox.qml | 86 | ||||
-rw-r--r-- | tests/auto/controls/data/tst_popup.qml | 6 |
8 files changed, 125 insertions, 15 deletions
diff --git a/src/imports/controls/material/CheckIndicator.qml b/src/imports/controls/material/CheckIndicator.qml index c52d5ae0..67f46551 100644 --- a/src/imports/controls/material/CheckIndicator.qml +++ b/src/imports/controls/material/CheckIndicator.qml @@ -44,11 +44,12 @@ Rectangle { implicitHeight: 18 color: "transparent" border.color: !control.enabled ? control.Material.hintTextColor - : control.checkState !== Qt.Unchecked ? control.Material.accentColor : control.Material.secondaryTextColor - border.width: control.checkState !== Qt.Unchecked ? width / 2 : 2 + : checkState !== Qt.Unchecked ? control.Material.accentColor : control.Material.secondaryTextColor + border.width: checkState !== Qt.Unchecked ? width / 2 : 2 radius: 2 property Item control + property int checkState: control.checkState Behavior on border.width { NumberAnimation { @@ -74,7 +75,7 @@ Rectangle { source: "qrc:/qt-project.org/imports/QtQuick/Controls.2/Material/images/check.png" fillMode: Image.PreserveAspectFit - scale: control.checkState === Qt.Checked ? 1 : 0 + scale: checkState === Qt.Checked ? 1 : 0 Behavior on scale { NumberAnimation { duration: 100 } } } @@ -84,18 +85,18 @@ Rectangle { width: 12 height: 3 - scale: control.checkState === Qt.PartiallyChecked ? 1 : 0 + scale: checkState === Qt.PartiallyChecked ? 1 : 0 Behavior on scale { NumberAnimation { duration: 100 } } } states: [ State { name: "checked" - when: control.checkState === Qt.Checked + when: checkState === Qt.Checked }, State { name: "partiallychecked" - when: control.checkState === Qt.PartiallyChecked + when: checkState === Qt.PartiallyChecked } ] diff --git a/src/imports/controls/material/MenuItem.qml b/src/imports/controls/material/MenuItem.qml index 744bada5..1f9caf8d 100644 --- a/src/imports/controls/material/MenuItem.qml +++ b/src/imports/controls/material/MenuItem.qml @@ -63,6 +63,7 @@ T.MenuItem { y: control.topPadding + (control.availableHeight - height) / 2 visible: control.checkable control: control + checkState: control.checked ? Qt.Checked : Qt.Unchecked } arrow: ColorImage { diff --git a/src/quicktemplates2/qquickcombobox.cpp b/src/quicktemplates2/qquickcombobox.cpp index 65d17366..d4280b30 100644 --- a/src/quicktemplates2/qquickcombobox.cpp +++ b/src/quicktemplates2/qquickcombobox.cpp @@ -1698,9 +1698,11 @@ void QQuickComboBox::keyReleaseEvent(QKeyEvent *event) break; case Qt::Key_Escape: case Qt::Key_Back: - d->hidePopup(false); - setPressed(false); - event->accept(); + if (d->isPopupVisible()) { + d->hidePopup(false); + setPressed(false); + event->accept(); + } break; default: break; @@ -1740,6 +1742,16 @@ void QQuickComboBox::componentComplete() } } +void QQuickComboBox::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value) +{ + Q_D(QQuickComboBox); + QQuickControl::itemChange(change, value); + if (change == ItemVisibleHasChanged && !value.boolValue) { + d->hidePopup(false); + setPressed(false); + } +} + void QQuickComboBox::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) { Q_D(QQuickComboBox); diff --git a/src/quicktemplates2/qquickcombobox_p.h b/src/quicktemplates2/qquickcombobox_p.h index 11fddefa..75e535a9 100644 --- a/src/quicktemplates2/qquickcombobox_p.h +++ b/src/quicktemplates2/qquickcombobox_p.h @@ -204,6 +204,7 @@ protected: #endif void componentComplete() override; + void itemChange(ItemChange change, const ItemChangeData &value) override; void contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) override; void localeChange(const QLocale &newLocale, const QLocale &oldLocale) override; diff --git a/src/quicktemplates2/qquickrangeslider.cpp b/src/quicktemplates2/qquickrangeslider.cpp index e5c0766b..b06cb23c 100644 --- a/src/quicktemplates2/qquickrangeslider.cpp +++ b/src/quicktemplates2/qquickrangeslider.cpp @@ -807,7 +807,8 @@ qreal QQuickRangeSlider::valueAt(qreal position) const \l {first.visualPosition}{visualPosition} should be used instead. \row \li pressed - \li This property holds whether the first handle is pressed. + \li This property holds whether the first handle is pressed by either touch, + mouse, or keys. \row \li hovered \li This property holds whether the first handle is hovered. @@ -881,7 +882,8 @@ QQuickRangeSliderNode *QQuickRangeSlider::first() const \l {second.visualPosition}{visualPosition} should be used instead. \row \li pressed - \li This property holds whether the second handle is pressed. + \li This property holds whether the second handle is pressed by either touch, + mouse, or keys. \row \li hovered \li This property holds whether the second handle is hovered. @@ -938,6 +940,9 @@ void QQuickRangeSlider::setStepSize(qreal step) This property holds the snap mode. + The snap mode determines how the slider handles behave with + regards to the \l stepSize. + Possible values: \value RangeSlider.NoSnap The slider does not snap (default). \value RangeSlider.SnapAlways The slider snaps while the handle is dragged. diff --git a/src/quicktemplates2/qquickslider.cpp b/src/quicktemplates2/qquickslider.cpp index 406199c9..1e6e0c25 100644 --- a/src/quicktemplates2/qquickslider.cpp +++ b/src/quicktemplates2/qquickslider.cpp @@ -448,6 +448,9 @@ void QQuickSlider::setStepSize(qreal step) This property holds the snap mode. + The snap mode determines how the slider handle behaves with + regards to the \l stepSize. + Possible values: \value Slider.NoSnap The slider does not snap (default). \value Slider.SnapAlways The slider snaps while the handle is dragged. @@ -486,7 +489,8 @@ void QQuickSlider::setSnapMode(SnapMode mode) /*! \qmlproperty bool QtQuick.Controls::Slider::pressed - This property holds whether the slider is pressed. + This property holds whether the slider is pressed by either touch, mouse, + or keys. */ bool QQuickSlider::isPressed() const { diff --git a/tests/auto/controls/data/tst_combobox.qml b/tests/auto/controls/data/tst_combobox.qml index 22b36725..8e8f9c2f 100644 --- a/tests/auto/controls/data/tst_combobox.qml +++ b/tests/auto/controls/data/tst_combobox.qml @@ -755,6 +755,12 @@ TestCase { control.x = testCase.width - control.width / 2 compare(control.x, testCase.width - control.width / 2) compare(control.popup.contentItem.parent.x, testCase.width - control.width / 2) + + // close the popup when hidden (QTBUG-67684) + control.popup.open() + tryCompare(control.popup, "opened", true) + control.visible = false + tryCompare(control.popup, "visible", false) } function test_mouse() { @@ -1594,4 +1600,84 @@ TestCase { tryCompare(control.popup, "visible", true) compare(control.popup.height, control.popup.topPadding + control.popup.bottomPadding) } + + Component { + id: keysMonitor + Item { + property int pressedKeys: 0 + property int releasedKeys: 0 + property int lastPressedKey: 0 + property int lastReleasedKey: 0 + property alias comboBox: comboBox + + width: 200 + height: 200 + + Keys.onPressed: { ++pressedKeys; lastPressedKey = event.key } + Keys.onReleased: { ++releasedKeys; lastReleasedKey = event.key } + + ComboBox { + id: comboBox + } + } + } + + function test_keyClose_data() { + return [ + { tag: "Escape", key: Qt.Key_Escape }, + { tag: "Back", key: Qt.Key_Back } + ] + } + + function test_keyClose(data) { + var container = createTemporaryObject(keysMonitor, testCase) + verify(container) + + var control = comboBox.createObject(container) + verify(control) + + control.forceActiveFocus() + verify(control.activeFocus) + + var pressedKeys = 0 + var releasedKeys = 0 + + // popup not visible -> propagates + keyPress(data.key) + compare(container.pressedKeys, ++pressedKeys) + compare(container.lastPressedKey, data.key) + + keyRelease(data.key) + compare(container.releasedKeys, ++releasedKeys) + compare(container.lastReleasedKey, data.key) + + verify(control.activeFocus) + + // popup visible -> handled -> does not propagate + control.popup.open() + tryCompare(control.popup, "opened", true) + + keyPress(data.key) + compare(container.pressedKeys, pressedKeys) + + keyRelease(data.key) + // Popup receives the key release event if it has an exit transition, but + // not if it has been immediately closed on press, without a transition. + // ### TODO: Should Popup somehow always block the key release event? + if (!control.popup.exit) + ++releasedKeys + compare(container.releasedKeys, releasedKeys) + + tryCompare(control.popup, "visible", false) + verify(control.activeFocus) + + // popup not visible -> propagates + keyPress(data.key) + compare(container.pressedKeys, ++pressedKeys) + compare(container.lastPressedKey, data.key) + + keyRelease(data.key) + compare(container.releasedKeys, ++releasedKeys) + compare(container.lastReleasedKey, data.key) + } } diff --git a/tests/auto/controls/data/tst_popup.qml b/tests/auto/controls/data/tst_popup.qml index 9ff01e40..3106b22f 100644 --- a/tests/auto/controls/data/tst_popup.qml +++ b/tests/auto/controls/data/tst_popup.qml @@ -1358,7 +1358,7 @@ TestCase { Shortcut { id: shortcut - sequence: "Tab" + sequence: "A" onActivated: popup.visible = !popup.visible } } @@ -1376,11 +1376,11 @@ TestCase { verify(shortcutActivatedSpy.valid) waitForRendering(window.contentItem) - keyClick(Qt.Key_Tab) + keyClick(Qt.Key_A) compare(shortcutActivatedSpy.count, 1) tryCompare(control, "visible", true) - keyClick(Qt.Key_Tab) + keyClick(Qt.Key_A) compare(shortcutActivatedSpy.count, 2) tryCompare(control, "visible", false) } |