diff options
author | J-P Nurmi <jpnurmi@theqtcompany.com> | 2015-11-29 23:35:17 +0100 |
---|---|---|
committer | J-P Nurmi <jpnurmi@theqtcompany.com> | 2015-12-12 17:47:21 +0000 |
commit | 691366a678640448c1dcb04f5297f637919aa220 (patch) | |
tree | 8931979e244b489d4e1bb60d7d79c80e561871e5 | |
parent | 0cb8763ca7dc3190a797563ff64c35f9208aa9c8 (diff) |
Add QQuickControl::focusReason
This allows the Universal style ApplicationWindow to visualize key/tab
focus with a focus rectangle, but hide the focus rectangle when the
focus moves around for other reasons (mouse, active window, popups...)
Change-Id: I5c5b43d7c4c051679e34b806ee43cd80180d7ab8
Reviewed-by: J-P Nurmi <jpnurmi@theqtcompany.com>
-rw-r--r-- | src/templates/qquickcontrol.cpp | 48 | ||||
-rw-r--r-- | src/templates/qquickcontrol_p.h | 8 | ||||
-rw-r--r-- | src/templates/qquickcontrol_p_p.h | 1 | ||||
-rw-r--r-- | src/templates/qquicktextarea.cpp | 48 | ||||
-rw-r--r-- | src/templates/qquicktextarea_p.h | 8 | ||||
-rw-r--r-- | src/templates/qquicktextarea_p_p.h | 1 | ||||
-rw-r--r-- | src/templates/qquicktextfield.cpp | 47 | ||||
-rw-r--r-- | src/templates/qquicktextfield_p.h | 8 | ||||
-rw-r--r-- | src/templates/qquicktextfield_p_p.h | 1 | ||||
-rw-r--r-- | tests/auto/controls/data/tst_control.qml | 26 |
10 files changed, 194 insertions, 2 deletions
diff --git a/src/templates/qquickcontrol.cpp b/src/templates/qquickcontrol.cpp index b8634874..bcaeed56 100644 --- a/src/templates/qquickcontrol.cpp +++ b/src/templates/qquickcontrol.cpp @@ -67,7 +67,7 @@ QT_BEGIN_NAMESPACE QQuickControlPrivate::QQuickControlPrivate() : hasTopPadding(false), hasLeftPadding(false), hasRightPadding(false), hasBottomPadding(false), - padding(0), topPadding(0), leftPadding(0), rightPadding(0), bottomPadding(0), spacing(0), + padding(0), topPadding(0), leftPadding(0), rightPadding(0), bottomPadding(0), spacing(0), focusReason(Qt::OtherFocusReason), background(Q_NULLPTR), contentItem(Q_NULLPTR), accessibleAttached(Q_NULLPTR) { #ifndef QT_NO_ACCESSIBILITY @@ -654,6 +654,40 @@ bool QQuickControl::isMirrored() const } /*! + \qmlproperty enumeration Qt.labs.controls::Control::focusReason + + This property holds the reason of the last focus change. + + \note This property does not indicate whether the control has \l {Item::activeFocus} + {active focus}, but the reason why the control either gained or lost focus. + + \value Qt.MouseFocusReason A mouse action occurred. + \value Qt.TabFocusReason The Tab key was pressed. + \value Qt.BacktabFocusReason A Backtab occurred. The input for this may include the Shift or Control keys; e.g. Shift+Tab. + \value Qt.ActiveWindowFocusReason The window system made this window either active or inactive. + \value Qt.PopupFocusReason The application opened/closed a pop-up that grabbed/released the keyboard focus. + \value Qt.ShortcutFocusReason The user typed a label's buddy shortcut + \value Qt.MenuBarFocusReason The menu bar took focus. + \value Qt.OtherFocusReason Another reason, usually application-specific. + + \sa Item::activeFocus +*/ +Qt::FocusReason QQuickControl::focusReason() const +{ + Q_D(const QQuickControl); + return d->focusReason; +} + +void QQuickControl::setFocusReason(Qt::FocusReason reason) +{ + Q_D(QQuickControl); + if (d->focusReason != reason) { + d->focusReason = reason; + emit focusReasonChanged(); + } +} + +/*! \qmlproperty Item Qt.labs.controls::Control::background This property holds the background item. @@ -728,6 +762,18 @@ QFont QQuickControl::defaultFont() const return QQuickControlPrivate::themeFont(QPlatformTheme::SystemFont); } +void QQuickControl::focusInEvent(QFocusEvent *event) +{ + QQuickItem::focusInEvent(event); + setFocusReason(event->reason()); +} + +void QQuickControl::focusOutEvent(QFocusEvent *event) +{ + QQuickItem::focusOutEvent(event); + setFocusReason(event->reason()); +} + void QQuickControl::mousePressEvent(QMouseEvent *event) { event->accept(); diff --git a/src/templates/qquickcontrol_p.h b/src/templates/qquickcontrol_p.h index 56e8a9fd..8391a7ab 100644 --- a/src/templates/qquickcontrol_p.h +++ b/src/templates/qquickcontrol_p.h @@ -70,6 +70,7 @@ class Q_LABSTEMPLATES_EXPORT QQuickControl : public QQuickItem Q_PROPERTY(qreal spacing READ spacing WRITE setSpacing RESET resetSpacing NOTIFY spacingChanged FINAL) Q_PROPERTY(QLocale locale READ locale WRITE setLocale NOTIFY localeChanged FINAL) Q_PROPERTY(bool mirrored READ isMirrored NOTIFY mirroredChanged FINAL) + Q_PROPERTY(Qt::FocusReason focusReason READ focusReason WRITE setFocusReason NOTIFY focusReasonChanged FINAL) Q_PROPERTY(QQuickItem *background READ background WRITE setBackground NOTIFY backgroundChanged FINAL) Q_PROPERTY(QQuickItem *contentItem READ contentItem WRITE setContentItem NOTIFY contentItemChanged FINAL) @@ -112,6 +113,9 @@ public: bool isMirrored() const; + Qt::FocusReason focusReason() const; + void setFocusReason(Qt::FocusReason reason); + QQuickItem *background() const; void setBackground(QQuickItem *background); @@ -130,6 +134,7 @@ Q_SIGNALS: void spacingChanged(); void localeChanged(); void mirroredChanged(); + void focusReasonChanged(); void backgroundChanged(); void contentItemChanged(); @@ -143,6 +148,9 @@ protected: void itemChange(ItemChange change, const ItemChangeData &value) Q_DECL_OVERRIDE; + void focusInEvent(QFocusEvent *event) Q_DECL_OVERRIDE; + void focusOutEvent(QFocusEvent *event) Q_DECL_OVERRIDE; + void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE; void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; diff --git a/src/templates/qquickcontrol_p_p.h b/src/templates/qquickcontrol_p_p.h index f0cc402a..79824545 100644 --- a/src/templates/qquickcontrol_p_p.h +++ b/src/templates/qquickcontrol_p_p.h @@ -115,6 +115,7 @@ public: qreal bottomPadding; qreal spacing; QLocale locale; + Qt::FocusReason focusReason; QQuickItem *background; QQuickItem *contentItem; QQuickAccessibleAttached *accessibleAttached; diff --git a/src/templates/qquicktextarea.cpp b/src/templates/qquicktextarea.cpp index dba082a4..fbc14573 100644 --- a/src/templates/qquicktextarea.cpp +++ b/src/templates/qquicktextarea.cpp @@ -79,7 +79,7 @@ QT_BEGIN_NAMESPACE */ QQuickTextAreaPrivate::QQuickTextAreaPrivate() - : background(Q_NULLPTR), accessibleAttached(Q_NULLPTR) + : background(Q_NULLPTR), focusReason(Qt::OtherFocusReason), accessibleAttached(Q_NULLPTR) { #ifndef QT_NO_ACCESSIBILITY QAccessible::installActivationObserver(this); @@ -285,6 +285,40 @@ void QQuickTextArea::setPlaceholderText(const QString &text) } } +/*! + \qmlproperty enumeration Qt.labs.controls::TextArea::focusReason + + This property holds the reason of the last focus change. + + \note This property does not indicate whether the control has \l {Item::activeFocus} + {active focus}, but the reason why the control either gained or lost focus. + + \value Qt.MouseFocusReason A mouse action occurred. + \value Qt.TabFocusReason The Tab key was pressed. + \value Qt.BacktabFocusReason A Backtab occurred. The input for this may include the Shift or Control keys; e.g. Shift+Tab. + \value Qt.ActiveWindowFocusReason The window system made this window either active or inactive. + \value Qt.PopupFocusReason The application opened/closed a pop-up that grabbed/released the keyboard focus. + \value Qt.ShortcutFocusReason The user typed a label's buddy shortcut + \value Qt.MenuBarFocusReason The menu bar took focus. + \value Qt.OtherFocusReason Another reason, usually application-specific. + + \sa Item::activeFocus +*/ +Qt::FocusReason QQuickTextArea::focusReason() const +{ + Q_D(const QQuickTextArea); + return d->focusReason; +} + +void QQuickTextArea::setFocusReason(Qt::FocusReason reason) +{ + Q_D(QQuickTextArea); + if (d->focusReason != reason) { + d->focusReason = reason; + emit focusReasonChanged(); + } +} + void QQuickTextArea::classBegin() { Q_D(QQuickTextArea); @@ -323,6 +357,18 @@ QSGNode *QQuickTextArea::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData * return clipNode; } +void QQuickTextArea::focusInEvent(QFocusEvent *event) +{ + QQuickTextEdit::focusInEvent(event); + setFocusReason(event->reason()); +} + +void QQuickTextArea::focusOutEvent(QFocusEvent *event) +{ + QQuickTextEdit::focusOutEvent(event); + setFocusReason(event->reason()); +} + void QQuickTextArea::mousePressEvent(QMouseEvent *event) { Q_D(QQuickTextArea); diff --git a/src/templates/qquicktextarea_p.h b/src/templates/qquicktextarea_p.h index d8326f66..74eb54dc 100644 --- a/src/templates/qquicktextarea_p.h +++ b/src/templates/qquicktextarea_p.h @@ -65,6 +65,7 @@ class Q_LABSTEMPLATES_EXPORT QQuickTextArea : public QQuickTextEdit Q_PROPERTY(qreal implicitHeight READ implicitHeight WRITE setImplicitHeight NOTIFY implicitHeightChanged FINAL) Q_PROPERTY(QQuickItem *background READ background WRITE setBackground NOTIFY backgroundChanged FINAL) Q_PROPERTY(QString placeholderText READ placeholderText WRITE setPlaceholderText NOTIFY placeholderTextChanged FINAL) + Q_PROPERTY(Qt::FocusReason focusReason READ focusReason WRITE setFocusReason NOTIFY focusReasonChanged FINAL) public: explicit QQuickTextArea(QQuickItem *parent = Q_NULLPTR); @@ -79,12 +80,16 @@ public: QString placeholderText() const; void setPlaceholderText(const QString &text); + Qt::FocusReason focusReason() const; + void setFocusReason(Qt::FocusReason reason); + Q_SIGNALS: void fontChanged(); void implicitWidthChanged(); void implicitHeightChanged(); void backgroundChanged(); void placeholderTextChanged(); + void focusReasonChanged(); void pressAndHold(QQuickMouseEvent *event); protected: @@ -93,6 +98,9 @@ protected: void itemChange(ItemChange change, const ItemChangeData &value) Q_DECL_OVERRIDE; void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) Q_DECL_OVERRIDE; QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data) Q_DECL_OVERRIDE; + + void focusInEvent(QFocusEvent *event) Q_DECL_OVERRIDE; + void focusOutEvent(QFocusEvent *event) Q_DECL_OVERRIDE; void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE; void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; diff --git a/src/templates/qquicktextarea_p_p.h b/src/templates/qquicktextarea_p_p.h index 2960f7bf..7e976da5 100644 --- a/src/templates/qquicktextarea_p_p.h +++ b/src/templates/qquicktextarea_p_p.h @@ -93,6 +93,7 @@ public: QQuickItem *background; QString placeholder; + Qt::FocusReason focusReason; QQuickPressAndHoldHelper pressAndHoldHelper; QQuickAccessibleAttached *accessibleAttached; }; diff --git a/src/templates/qquicktextfield.cpp b/src/templates/qquicktextfield.cpp index 50d49c11..ec8c24ab 100644 --- a/src/templates/qquicktextfield.cpp +++ b/src/templates/qquicktextfield.cpp @@ -90,6 +90,7 @@ QT_BEGIN_NAMESPACE QQuickTextFieldPrivate::QQuickTextFieldPrivate() : background(Q_NULLPTR) + , focusReason(Qt::OtherFocusReason) , accessibleAttached(Q_NULLPTR) { #ifndef QT_NO_ACCESSIBILITY @@ -309,6 +310,40 @@ void QQuickTextField::setPlaceholderText(const QString &text) } } +/*! + \qmlproperty enumeration Qt.labs.controls::TextField::focusReason + + This property holds the reason of the last focus change. + + \note This property does not indicate whether the control has \l {Item::activeFocus} + {active focus}, but the reason why the control either gained or lost focus. + + \value Qt.MouseFocusReason A mouse action occurred. + \value Qt.TabFocusReason The Tab key was pressed. + \value Qt.BacktabFocusReason A Backtab occurred. The input for this may include the Shift or Control keys; e.g. Shift+Tab. + \value Qt.ActiveWindowFocusReason The window system made this window either active or inactive. + \value Qt.PopupFocusReason The application opened/closed a pop-up that grabbed/released the keyboard focus. + \value Qt.ShortcutFocusReason The user typed a label's buddy shortcut + \value Qt.MenuBarFocusReason The menu bar took focus. + \value Qt.OtherFocusReason Another reason, usually application-specific. + + \sa Item::activeFocus +*/ +Qt::FocusReason QQuickTextField::focusReason() const +{ + Q_D(const QQuickTextField); + return d->focusReason; +} + +void QQuickTextField::setFocusReason(Qt::FocusReason reason) +{ + Q_D(QQuickTextField); + if (d->focusReason != reason) { + d->focusReason = reason; + emit focusReasonChanged(); + } +} + void QQuickTextField::classBegin() { Q_D(QQuickTextField); @@ -347,6 +382,18 @@ QSGNode *QQuickTextField::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData return clipNode; } +void QQuickTextField::focusInEvent(QFocusEvent *event) +{ + QQuickTextInput::focusInEvent(event); + setFocusReason(event->reason()); +} + +void QQuickTextField::focusOutEvent(QFocusEvent *event) +{ + QQuickTextInput::focusOutEvent(event); + setFocusReason(event->reason()); +} + void QQuickTextField::mousePressEvent(QMouseEvent *event) { Q_D(QQuickTextField); diff --git a/src/templates/qquicktextfield_p.h b/src/templates/qquicktextfield_p.h index d8b20225..dd4d0b98 100644 --- a/src/templates/qquicktextfield_p.h +++ b/src/templates/qquicktextfield_p.h @@ -65,6 +65,7 @@ class Q_LABSTEMPLATES_EXPORT QQuickTextField : public QQuickTextInput Q_PROPERTY(qreal implicitHeight READ implicitHeight WRITE setImplicitHeight NOTIFY implicitHeightChanged FINAL) Q_PROPERTY(QQuickItem *background READ background WRITE setBackground NOTIFY backgroundChanged FINAL) Q_PROPERTY(QString placeholderText READ placeholderText WRITE setPlaceholderText NOTIFY placeholderTextChanged FINAL) + Q_PROPERTY(Qt::FocusReason focusReason READ focusReason WRITE setFocusReason NOTIFY focusReasonChanged FINAL) public: explicit QQuickTextField(QQuickItem *parent = Q_NULLPTR); @@ -79,12 +80,16 @@ public: QString placeholderText() const; void setPlaceholderText(const QString &text); + Qt::FocusReason focusReason() const; + void setFocusReason(Qt::FocusReason reason); + Q_SIGNALS: void fontChanged(); void implicitWidthChanged(); void implicitHeightChanged(); void backgroundChanged(); void placeholderTextChanged(); + void focusReasonChanged(); void pressAndHold(QQuickMouseEvent *mouse); protected: @@ -93,6 +98,9 @@ protected: void itemChange(ItemChange change, const ItemChangeData &value) Q_DECL_OVERRIDE; void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) Q_DECL_OVERRIDE; QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data) Q_DECL_OVERRIDE; + + void focusInEvent(QFocusEvent *event) Q_DECL_OVERRIDE; + void focusOutEvent(QFocusEvent *event) Q_DECL_OVERRIDE; void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE; void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; diff --git a/src/templates/qquicktextfield_p_p.h b/src/templates/qquicktextfield_p_p.h index 459e0847..82af32c5 100644 --- a/src/templates/qquicktextfield_p_p.h +++ b/src/templates/qquicktextfield_p_p.h @@ -94,6 +94,7 @@ public: QQuickItem *background; QString placeholder; + Qt::FocusReason focusReason; QQuickPressAndHoldHelper pressAndHoldHelper; QQuickAccessibleAttached *accessibleAttached; }; diff --git a/tests/auto/controls/data/tst_control.qml b/tests/auto/controls/data/tst_control.qml index 3bfc5e63..ea1e58df 100644 --- a/tests/auto/controls/data/tst_control.qml +++ b/tests/auto/controls/data/tst_control.qml @@ -638,4 +638,30 @@ TestCase { control.destroy() } + + function test_focusReason_data() { + return [ + { tag: "Control", qml: "import Qt.labs.controls 1.0; Control { }" }, + { tag: "TextField", qml: "import Qt.labs.controls 1.0; TextField { }" }, + { tag: "TextArea", qml: "import Qt.labs.controls 1.0; TextArea { }" }, + { tag: "SpinBox", qml: "import Qt.labs.controls 1.0; SpinBox { }" }, + { tag: "ComboBox", qml: "import Qt.labs.controls 1.0; ComboBox { }" } + ] + } + + function test_focusReason(data) { + var control = Qt.createQmlObject(data.qml, testCase) + verify(control) + + compare(control.focusReason, Qt.OtherFocusReason) + control.forceActiveFocus(Qt.MouseFocusReason) + compare(control.activeFocus, true) + compare(control.focusReason, Qt.MouseFocusReason) + + testCase.forceActiveFocus(Qt.TabFocusReason) + compare(control.activeFocus, false) + compare(control.focusReason, Qt.TabFocusReason) + + control.destroy() + } } |