aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJ-P Nurmi <jpnurmi@qt.io>2016-11-04 12:54:38 +0100
committerJ-P Nurmi <jpnurmi@qt.io>2016-11-09 11:43:49 +0000
commit372c5b44e5bc2730c3557cf56bffc5496ab020f3 (patch)
tree02ff1d36bdbd9bb6544fa5f21728dcfa5f9b404e
parentbefe5e0dca3b5af7ffa48b0f66794b083d43656f (diff)
Add QQuickComboBox::down
This allows us to replace all "control.pressed || popup.visible" expressions with "control.down", and takes us one step closer to deferred popop execution as mentioned in the previous commit. In order to be able to defer the popup execution, we must get rid of such explicit references to the popup. Change-Id: Ifa7ecf8201912d3ec1bca232e2cf600e3886715e Reviewed-by: J-P Nurmi <jpnurmi@qt.io> Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
-rw-r--r--src/imports/controls/ComboBox.qml4
-rw-r--r--src/imports/controls/material/ComboBox.qml2
-rw-r--r--src/imports/controls/universal/ComboBox.qml6
-rw-r--r--src/imports/templates/qtquicktemplates2plugin.cpp1
-rw-r--r--src/quicktemplates2/qquickcombobox.cpp88
-rw-r--r--src/quicktemplates2/qquickcombobox_p.h8
-rw-r--r--tests/auto/controls/data/tst_combobox.qml68
7 files changed, 164 insertions, 13 deletions
diff --git a/src/imports/controls/ComboBox.qml b/src/imports/controls/ComboBox.qml
index 720bb534..6c85dd58 100644
--- a/src/imports/controls/ComboBox.qml
+++ b/src/imports/controls/ComboBox.qml
@@ -38,7 +38,7 @@ import QtQuick 2.8
import QtQuick.Window 2.2
import QtQuick.Controls 2.1
import QtQuick.Controls.impl 2.1
-import QtQuick.Templates 2.1 as T
+import QtQuick.Templates 2.2 as T
T.ComboBox {
id: control
@@ -97,7 +97,7 @@ T.ComboBox {
implicitHeight: 40
color: control.visualFocus ? (control.pressed ? Default.focusPressedColor : Default.focusLightColor) :
- (control.pressed || popup.visible ? Default.buttonPressedColor : Default.buttonColor)
+ (control.down ? Default.buttonPressedColor : Default.buttonColor)
border.color: Default.focusColor
border.width: control.visualFocus ? 2 : 0
visible: !control.flat || control.pressed
diff --git a/src/imports/controls/material/ComboBox.qml b/src/imports/controls/material/ComboBox.qml
index 3c8f5c75..79e8d017 100644
--- a/src/imports/controls/material/ComboBox.qml
+++ b/src/imports/controls/material/ComboBox.qml
@@ -37,7 +37,7 @@
import QtQuick 2.8
import QtQuick.Window 2.2
import QtQuick.Controls 2.1
-import QtQuick.Templates 2.1 as T
+import QtQuick.Templates 2.2 as T
import QtQuick.Controls.Material 2.1
import QtQuick.Controls.Material.impl 2.1
diff --git a/src/imports/controls/universal/ComboBox.qml b/src/imports/controls/universal/ComboBox.qml
index 536782c7..62aee832 100644
--- a/src/imports/controls/universal/ComboBox.qml
+++ b/src/imports/controls/universal/ComboBox.qml
@@ -37,7 +37,7 @@
import QtQuick 2.8
import QtQuick.Window 2.2
import QtQuick.Controls 2.1
-import QtQuick.Templates 2.1 as T
+import QtQuick.Templates 2.2 as T
import QtQuick.Controls.Universal 2.1
T.ComboBox {
@@ -90,10 +90,10 @@ T.ComboBox {
border.width: control.flat ? 0 : 2 // ComboBoxBorderThemeThickness
border.color: !control.enabled ? control.Universal.baseLowColor :
- control.pressed || popup.visible ? control.Universal.baseMediumLowColor :
+ control.down ? control.Universal.baseMediumLowColor :
control.hovered ? control.Universal.baseMediumColor : control.Universal.baseMediumLowColor
color: !control.enabled ? control.Universal.baseLowColor :
- control.pressed || popup.visible ? control.Universal.listMediumColor :
+ control.down ? control.Universal.listMediumColor :
control.flat && control.hovered ? control.Universal.listLowColor : control.Universal.altMediumLowColor
visible: !control.flat || control.pressed || control.hovered || control.visualFocus
diff --git a/src/imports/templates/qtquicktemplates2plugin.cpp b/src/imports/templates/qtquicktemplates2plugin.cpp
index 58e5ce90..b7094e13 100644
--- a/src/imports/templates/qtquicktemplates2plugin.cpp
+++ b/src/imports/templates/qtquicktemplates2plugin.cpp
@@ -201,6 +201,7 @@ void QtQuickTemplates2Plugin::registerTypes(const char *uri)
qmlRegisterType<QQuickTumbler, 1>(uri, 2, 1, "Tumbler");
// QtQuick.Templates 2.2 (Qt 5.9)
+ qmlRegisterRevision<QQuickComboBox, 2>(uri, 2, 2);
qmlRegisterRevision<QQuickDial, 2>(uri, 2, 2);
qmlRegisterRevision<QQuickRangeSlider, 2>(uri, 2, 2);
qmlRegisterRevision<QQuickSlider, 2>(uri, 2, 2);
diff --git a/src/quicktemplates2/qquickcombobox.cpp b/src/quicktemplates2/qquickcombobox.cpp
index 3aa67688..298a795f 100644
--- a/src/quicktemplates2/qquickcombobox.cpp
+++ b/src/quicktemplates2/qquickcombobox.cpp
@@ -165,14 +165,13 @@ class QQuickComboBoxPrivate : public QQuickControlPrivate
Q_DECLARE_PUBLIC(QQuickComboBox)
public:
- QQuickComboBoxPrivate() : flat(false), pressed(false), ownModel(false), hasDisplayText(false), hasCurrentIndex(false),
- highlightedIndex(-1), currentIndex(-1), delegateModel(nullptr),
- delegate(nullptr), indicator(nullptr), popup(nullptr) { }
+ QQuickComboBoxPrivate();
bool isPopupVisible() const;
void showPopup();
void hidePopup(bool accept);
void togglePopup(bool accept);
+ void popupVisibleChanged();
void itemClicked();
@@ -187,6 +186,8 @@ public:
void createDelegateModel();
bool flat;
+ bool down;
+ bool hasDown;
bool pressed;
bool ownModel;
bool hasDisplayText;
@@ -204,6 +205,23 @@ public:
QQuickPopup *popup;
};
+QQuickComboBoxPrivate::QQuickComboBoxPrivate()
+ : flat(false),
+ down(false),
+ hasDown(false),
+ pressed(false),
+ ownModel(false),
+ hasDisplayText(false),
+ hasCurrentIndex(false),
+ highlightedIndex(-1),
+ currentIndex(-1),
+ delegateModel(nullptr),
+ delegate(nullptr),
+ indicator(nullptr),
+ popup(nullptr)
+{
+}
+
bool QQuickComboBoxPrivate::isPopupVisible() const
{
return popup && popup->isVisible();
@@ -237,6 +255,16 @@ void QQuickComboBoxPrivate::togglePopup(bool accept)
showPopup();
}
+void QQuickComboBoxPrivate::popupVisibleChanged()
+{
+ Q_Q(QQuickComboBox);
+ updateHighlightedIndex();
+ if (!hasDown) {
+ q->setDown(pressed || isPopupVisible());
+ hasDown = false;
+ }
+}
+
void QQuickComboBoxPrivate::itemClicked()
{
Q_Q(QQuickComboBox);
@@ -484,9 +512,52 @@ void QQuickComboBox::setFlat(bool flat)
}
/*!
+ \since QtQuick.Controls 2.2
+ \qmlproperty bool QtQuick.Controls::ComboBox::down
+
+ This property holds whether the combo box button is visually down.
+
+ Unless explicitly set, this property is \c true when either \c pressed
+ or \c popup.visible is \c true. To return to the default value, set this
+ property to \c undefined.
+
+ \sa pressed, popup
+*/
+bool QQuickComboBox::isDown() const
+{
+ Q_D(const QQuickComboBox);
+ return d->down;
+}
+
+void QQuickComboBox::setDown(bool down)
+{
+ Q_D(QQuickComboBox);
+ d->hasDown = true;
+
+ if (d->down == down)
+ return;
+
+ d->down = down;
+ emit downChanged();
+}
+
+void QQuickComboBox::resetDown()
+{
+ Q_D(QQuickComboBox);
+ if (!d->hasDown)
+ return;
+
+ setDown(d->pressed || d->isPopupVisible());
+ d->hasDown = false;
+}
+
+/*!
\qmlproperty bool QtQuick.Controls::ComboBox::pressed
- This property holds whether the combo box button is pressed.
+ This property holds whether the combo box button is physically pressed.
+ A button can be pressed by either touch or key events.
+
+ \sa down
*/
bool QQuickComboBox::isPressed() const
{
@@ -502,6 +573,11 @@ void QQuickComboBox::setPressed(bool pressed)
d->pressed = pressed;
emit pressedChanged();
+
+ if (!d->hasDown) {
+ setDown(d->pressed || d->isPopupVisible());
+ d->hasDown = false;
+ }
}
/*!
@@ -733,12 +809,12 @@ void QQuickComboBox::setPopup(QQuickPopup *popup)
return;
if (d->popup)
- QObjectPrivate::disconnect(d->popup, &QQuickPopup::visibleChanged, d, &QQuickComboBoxPrivate::updateHighlightedIndex);
+ QObjectPrivate::disconnect(d->popup, &QQuickPopup::visibleChanged, d, &QQuickComboBoxPrivate::popupVisibleChanged);
d->deleteDelegate(d->popup);
if (popup) {
QQuickPopupPrivate::get(popup)->allowVerticalFlip = true;
popup->setClosePolicy(QQuickPopup::CloseOnEscape | QQuickPopup::CloseOnPressOutsideParent);
- QObjectPrivate::connect(popup, &QQuickPopup::visibleChanged, d, &QQuickComboBoxPrivate::updateHighlightedIndex);
+ QObjectPrivate::connect(popup, &QQuickPopup::visibleChanged, d, &QQuickComboBoxPrivate::popupVisibleChanged);
}
d->popup = popup;
emit popupChanged();
diff --git a/src/quicktemplates2/qquickcombobox_p.h b/src/quicktemplates2/qquickcombobox_p.h
index 3788d56a..1feab73c 100644
--- a/src/quicktemplates2/qquickcombobox_p.h
+++ b/src/quicktemplates2/qquickcombobox_p.h
@@ -63,7 +63,8 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickComboBox : public QQuickControl
Q_PROPERTY(QVariant model READ model WRITE setModel NOTIFY modelChanged FINAL)
Q_PROPERTY(QQmlInstanceModel *delegateModel READ delegateModel NOTIFY delegateModelChanged FINAL)
Q_PROPERTY(bool flat READ isFlat WRITE setFlat NOTIFY flatChanged FINAL REVISION 1)
- Q_PROPERTY(bool pressed READ isPressed WRITE setPressed NOTIFY pressedChanged FINAL)
+ Q_PROPERTY(bool down READ isDown WRITE setDown RESET resetDown NOTIFY downChanged FINAL REVISION 2)
+ Q_PROPERTY(bool pressed READ isPressed WRITE setPressed NOTIFY pressedChanged FINAL) // ### Qt 6: should not be writable
Q_PROPERTY(int highlightedIndex READ highlightedIndex NOTIFY highlightedIndexChanged FINAL)
Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged FINAL)
Q_PROPERTY(QString currentText READ currentText NOTIFY currentTextChanged FINAL)
@@ -86,6 +87,10 @@ public:
bool isFlat() const;
void setFlat(bool flat);
+ bool isDown() const;
+ void setDown(bool down);
+ void resetDown();
+
bool isPressed() const;
void setPressed(bool pressed);
@@ -124,6 +129,7 @@ Q_SIGNALS:
void modelChanged();
void delegateModelChanged();
Q_REVISION(1) void flatChanged();
+ Q_REVISION(2) void downChanged();
void pressedChanged();
void highlightedIndexChanged();
void currentIndexChanged();
diff --git a/tests/auto/controls/data/tst_combobox.qml b/tests/auto/controls/data/tst_combobox.qml
index b74911c7..777b98f0 100644
--- a/tests/auto/controls/data/tst_combobox.qml
+++ b/tests/auto/controls/data/tst_combobox.qml
@@ -558,6 +558,74 @@ TestCase {
control.destroy()
}
+ function test_down() {
+ var control = comboBox.createObject(testCase, {model: 3})
+ verify(control)
+
+ // some styles position the popup over the combo button. move it out
+ // of the way to avoid stealing mouse presses. we want to test the
+ // combinations of the button being pressed and the popup being visible.
+ control.popup.y = control.height
+
+ var downSpy = signalSpy.createObject(control, {target: control, signalName: "downChanged"})
+ verify(downSpy.valid)
+
+ var pressedSpy = signalSpy.createObject(control, {target: control, signalName: "pressedChanged"})
+ verify(pressedSpy.valid)
+
+ mousePress(control)
+ compare(control.popup.visible, false)
+ compare(control.pressed, true)
+ compare(control.down, true)
+ compare(downSpy.count, 1)
+ compare(pressedSpy.count, 1)
+
+ mouseRelease(control)
+ compare(control.popup.visible, true)
+ compare(control.pressed, false)
+ compare(control.down, true)
+ compare(downSpy.count, 3)
+ compare(pressedSpy.count, 2)
+
+ control.down = false
+ compare(control.down, false)
+ compare(downSpy.count, 4)
+
+ mousePress(control)
+ compare(control.popup.visible, true)
+ compare(control.pressed, true)
+ compare(control.down, false) // explicit false
+ compare(downSpy.count, 4)
+ compare(pressedSpy.count, 3)
+
+ control.down = undefined
+ compare(control.down, true)
+ compare(downSpy.count, 5)
+
+ mouseRelease(control)
+ tryCompare(control.popup, "visible", false)
+ compare(control.pressed, false)
+ compare(control.down, false)
+ compare(downSpy.count, 6)
+ compare(pressedSpy.count, 4)
+
+ control.popup.open()
+ compare(control.popup.visible, true)
+ compare(control.pressed, false)
+ compare(control.down, true)
+ compare(downSpy.count, 7)
+ compare(pressedSpy.count, 4)
+
+ control.popup.close()
+ tryCompare(control.popup, "visible", false)
+ compare(control.pressed, false)
+ compare(control.down, false)
+ compare(downSpy.count, 8)
+ compare(pressedSpy.count, 4)
+
+ control.destroy()
+ }
+
function test_focus() {
var control = comboBox.createObject(testCase, {model: 3})
verify(control)