aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJ-P Nurmi <jpnurmi@theqtcompany.com>2015-11-29 23:35:17 +0100
committerJ-P Nurmi <jpnurmi@theqtcompany.com>2015-12-12 17:47:21 +0000
commit691366a678640448c1dcb04f5297f637919aa220 (patch)
tree8931979e244b489d4e1bb60d7d79c80e561871e5
parent0cb8763ca7dc3190a797563ff64c35f9208aa9c8 (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.cpp48
-rw-r--r--src/templates/qquickcontrol_p.h8
-rw-r--r--src/templates/qquickcontrol_p_p.h1
-rw-r--r--src/templates/qquicktextarea.cpp48
-rw-r--r--src/templates/qquicktextarea_p.h8
-rw-r--r--src/templates/qquicktextarea_p_p.h1
-rw-r--r--src/templates/qquicktextfield.cpp47
-rw-r--r--src/templates/qquicktextfield_p.h8
-rw-r--r--src/templates/qquicktextfield_p_p.h1
-rw-r--r--tests/auto/controls/data/tst_control.qml26
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()
+ }
}