From fff036ab4d755bce4d1e4d1fbfb5ac1b79bf8150 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Tue, 28 Jun 2016 14:53:11 +0200 Subject: [PATCH] SpinBox: add up.hovered and down.hovered properties The actual hover effects are coming in separate patches. [ChangeLog][SpinBox] Added up.hovered and down.hovered properties that hold whether the respective buttons are hovered. Task-number: QTBUG-50003 Change-Id: Ie47329e23326f40e4c807703ff7a97437f68deb4 Reviewed-by: Mitch Curtis --- .../controls/qtquickcontrols2plugin.cpp | 1 + .../templates/qtquicktemplates2plugin.cpp | 1 + src/quicktemplates2/qquickspinbox.cpp | 59 ++++++++++++++++++- src/quicktemplates2/qquickspinbox_p.h | 8 +++ tests/auto/controls/data/tst_spinbox.qml | 29 +++++++++ 5 files changed, 95 insertions(+), 3 deletions(-) diff --git a/src/imports/controls/qtquickcontrols2plugin.cpp b/src/imports/controls/qtquickcontrols2plugin.cpp index 4cfbd340ff..cea3894a02 100644 --- a/src/imports/controls/qtquickcontrols2plugin.cpp +++ b/src/imports/controls/qtquickcontrols2plugin.cpp @@ -141,6 +141,7 @@ void QtQuickControls2Plugin::registerTypes(const char *uri) qmlRegisterType(uri, 2, 1, "Container"); qmlRegisterType(selector.select(QStringLiteral("DialogButtonBox.qml")), uri, 2, 1, "DialogButtonBox"); qmlRegisterType(selector.select(QStringLiteral("Slider.qml")), uri, 2, 1, "Slider"); + qmlRegisterType(selector.select(QStringLiteral("SpinBox.qml")), uri, 2, 1, "SpinBox"); qmlRegisterType(selector.select(QStringLiteral("StackView.qml")), uri, 2, 1, "StackView"); qmlRegisterType(selector.select(QStringLiteral("SwipeView.qml")), uri, 2, 1, "SwipeView"); qmlRegisterType(selector.select(QStringLiteral("Tumbler.qml")), uri, 2, 1, "Tumbler"); diff --git a/src/imports/templates/qtquicktemplates2plugin.cpp b/src/imports/templates/qtquicktemplates2plugin.cpp index 28162e61f4..1af21a7388 100644 --- a/src/imports/templates/qtquicktemplates2plugin.cpp +++ b/src/imports/templates/qtquicktemplates2plugin.cpp @@ -179,6 +179,7 @@ void QtQuickTemplates2Plugin::registerTypes(const char *uri) qmlRegisterType(uri, 2, 1, "DialogButtonBox"); qmlRegisterType(); qmlRegisterType(uri, 2, 1, "Slider"); + qmlRegisterType(uri, 2, 1, "SpinBox"); qmlRegisterType(uri, 2, 1, "StackView"); qmlRegisterType(uri, 2, 1, "SwipeView"); qmlRegisterType(uri, 2, 1, "Tumbler"); diff --git a/src/quicktemplates2/qquickspinbox.cpp b/src/quicktemplates2/qquickspinbox.cpp index b2d88d3b9f..634e3732a5 100644 --- a/src/quicktemplates2/qquickspinbox.cpp +++ b/src/quicktemplates2/qquickspinbox.cpp @@ -109,6 +109,7 @@ public: void updateUpEnabled(); bool downEnabled() const; void updateDownEnabled(); + void updateHover(const QPointF &pos); void startRepeatDelay(); void startPressRepeat(); @@ -190,6 +191,15 @@ void QQuickSpinBoxPrivate::updateDownEnabled() downIndicator->setEnabled(from < to ? value > from : value < from); } +void QQuickSpinBoxPrivate::updateHover(const QPointF &pos) +{ + Q_Q(QQuickSpinBox); + QQuickItem *ui = up->indicator(); + QQuickItem *di = down->indicator(); + up->setHovered(ui && ui->isEnabled() && ui->contains(q->mapToItem(ui, pos))); + down->setHovered(di && di->isEnabled() && di->contains(q->mapToItem(di, pos))); +} + void QQuickSpinBoxPrivate::startRepeatDelay() { Q_Q(QQuickSpinBox); @@ -526,8 +536,10 @@ void QQuickSpinBox::setValueFromText(const QJSValue &callback) \qmlpropertygroup QtQuick.Controls::SpinBox::up \qmlproperty bool QtQuick.Controls::SpinBox::up.pressed \qmlproperty Item QtQuick.Controls::SpinBox::up.indicator + \qmlproperty bool QtQuick.Controls::SpinBox::up.hovered - These properties hold the up indicator item and whether it is pressed. + These properties hold the up indicator item and whether it is pressed or + hovered. The \c up.hovered property was introduced in QtQuick.Controls 2.1. \sa increase() */ @@ -541,8 +553,10 @@ QQuickSpinButton *QQuickSpinBox::up() const \qmlpropertygroup QtQuick.Controls::SpinBox::down \qmlproperty bool QtQuick.Controls::SpinBox::down.pressed \qmlproperty Item QtQuick.Controls::SpinBox::down.indicator + \qmlproperty bool QtQuick.Controls::SpinBox::down.hovered - These properties hold the down indicator item and whether it is pressed. + These properties hold the down indicator item and whether it is pressed or + hovered. The \c down.hovered property was introduced in QtQuick.Controls 2.1. \sa decrease() */ @@ -578,6 +592,28 @@ void QQuickSpinBox::decrease() setValue(d->value - d->effectiveStepSize()); } +void QQuickSpinBox::hoverEnterEvent(QHoverEvent *event) +{ + Q_D(QQuickSpinBox); + QQuickControl::hoverEnterEvent(event); + d->updateHover(event->posF()); +} + +void QQuickSpinBox::hoverMoveEvent(QHoverEvent *event) +{ + Q_D(QQuickSpinBox); + QQuickControl::hoverMoveEvent(event); + d->updateHover(event->posF()); +} + +void QQuickSpinBox::hoverLeaveEvent(QHoverEvent *event) +{ + Q_D(QQuickSpinBox); + QQuickControl::hoverLeaveEvent(event); + d->down->setHovered(false); + d->up->setHovered(false); +} + void QQuickSpinBox::keyPressEvent(QKeyEvent *event) { Q_D(QQuickSpinBox); @@ -730,8 +766,9 @@ QAccessible::Role QQuickSpinBox::accessibleRole() const class QQuickSpinButtonPrivate : public QObjectPrivate { public: - QQuickSpinButtonPrivate() : pressed(false), indicator(nullptr) { } + QQuickSpinButtonPrivate() : pressed(false), hovered(false), indicator(nullptr) { } bool pressed; + bool hovered; QQuickItem *indicator; }; @@ -756,6 +793,22 @@ void QQuickSpinButton::setPressed(bool pressed) emit pressedChanged(); } +bool QQuickSpinButton::isHovered() const +{ + Q_D(const QQuickSpinButton); + return d->hovered; +} + +void QQuickSpinButton::setHovered(bool hovered) +{ + Q_D(QQuickSpinButton); + if (d->hovered == hovered) + return; + + d->hovered = hovered; + emit hoveredChanged(); +} + QQuickItem *QQuickSpinButton::indicator() const { Q_D(const QQuickSpinButton); diff --git a/src/quicktemplates2/qquickspinbox_p.h b/src/quicktemplates2/qquickspinbox_p.h index 3898a28b8a..b34f81a290 100644 --- a/src/quicktemplates2/qquickspinbox_p.h +++ b/src/quicktemplates2/qquickspinbox_p.h @@ -118,6 +118,9 @@ Q_SIGNALS: protected: bool childMouseEventFilter(QQuickItem *child, QEvent *event) override; + void hoverEnterEvent(QHoverEvent *event) override; + void hoverMoveEvent(QHoverEvent *event) override; + void hoverLeaveEvent(QHoverEvent *event) override; void keyPressEvent(QKeyEvent *event) override; void keyReleaseEvent(QKeyEvent *event) override; void mousePressEvent(QMouseEvent *event) override; @@ -146,6 +149,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickSpinButton : public QObject { Q_OBJECT Q_PROPERTY(bool pressed READ isPressed WRITE setPressed NOTIFY pressedChanged FINAL) + Q_PROPERTY(bool hovered READ isHovered WRITE setHovered NOTIFY hoveredChanged FINAL REVISION 1) Q_PROPERTY(QQuickItem *indicator READ indicator WRITE setIndicator NOTIFY indicatorChanged FINAL) public: @@ -154,11 +158,15 @@ public: bool isPressed() const; void setPressed(bool pressed); + bool isHovered() const; + void setHovered(bool hovered); + QQuickItem *indicator() const; void setIndicator(QQuickItem *indicator); Q_SIGNALS: void pressedChanged(); + Q_REVISION(1) void hoveredChanged(); void indicatorChanged(); private: diff --git a/tests/auto/controls/data/tst_spinbox.qml b/tests/auto/controls/data/tst_spinbox.qml index d842270656..aecf4af437 100644 --- a/tests/auto/controls/data/tst_spinbox.qml +++ b/tests/auto/controls/data/tst_spinbox.qml @@ -478,4 +478,33 @@ TestCase { control.destroy() } + + function test_hover_data() { + return [ + { tag: "up:true", button: "up", hoverEnabled: true, value: 50 }, + { tag: "up:false", button: "up", hoverEnabled: false, value: 50 }, + { tag: "up:max", button: "up", hoverEnabled: true, value: 99 }, + { tag: "down:true", button: "down", hoverEnabled: true, value: 50 }, + { tag: "down:false", button: "down", hoverEnabled: false, value: 50 }, + { tag: "down:min", button: "down", hoverEnabled: true, value: 0 } + ] + } + + function test_hover(data) { + var control = spinBox.createObject(testCase, {hoverEnabled: data.hoverEnabled, value: data.value}) + verify(control) + + var button = control[data.button] + compare(control.hovered, false) + compare(button.hovered, false) + + mouseMove(control, button.indicator.x + button.indicator.width / 2, button.indicator.y + button.indicator.height / 2) + compare(control.hovered, data.hoverEnabled) + compare(button.hovered, data.hoverEnabled && button.indicator.enabled) + + mouseMove(control, button.indicator.x - 1, button.indicator.y - 1) + compare(button.hovered, false) + + control.destroy() + } }