aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMorten Johan Sorvig <morten.sorvig@nokia.com>2012-01-10 12:12:51 +0100
committerQt by Nokia <qt-info@nokia.com>2012-03-07 20:08:19 +0100
commit70966df1be02dd94ecf9a122ff9e4976245aeb92 (patch)
tree372db90105c34d0c2a72e029f4e087fdc93423b7
parent3f9b58c0890a4263730e2c06b46e7a69d4bfb62d (diff)
Improve accessibility action support for Qt Quick
Add interface_cast for the action interface. Implement actions for the following roles: Button : Press CheckBox, RadioButton : Press, Check, Uncheck Slider, Spinbox, Dial, ScrollBar : Increment, Decrement Change-Id: Ic8e0d17c709ba51655f3f4b699092baf603b6f18 Reviewed-by: Frederik Gladhorn <frederik.gladhorn@nokia.com>
-rw-r--r--examples/declarative/accessibility/widgets/Checkbox.qml62
-rw-r--r--examples/declarative/accessibility/widgets/Slider.qml67
-rw-r--r--examples/quick/accessibility/accessibility.qml16
-rw-r--r--examples/quick/accessibility/content/Button.qml5
-rw-r--r--src/plugins/accessible/quick/main.cpp1
-rw-r--r--src/plugins/accessible/shared/qqmlaccessible.cpp87
-rw-r--r--src/plugins/accessible/shared/qqmlaccessible.h1
-rw-r--r--src/quick/items/qquickaccessibleattached.cpp22
8 files changed, 239 insertions, 22 deletions
diff --git a/examples/declarative/accessibility/widgets/Checkbox.qml b/examples/declarative/accessibility/widgets/Checkbox.qml
new file mode 100644
index 0000000000..17eb733197
--- /dev/null
+++ b/examples/declarative/accessibility/widgets/Checkbox.qml
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+import QtQuick 2.0
+
+
+Rectangle {
+ id: checkbox
+
+ Accessible.role: Accessible.CheckBox
+
+ property bool checked // required variable
+
+ width: 30
+ height: 30
+
+
+ Text {
+ id: checkboxText
+ text: parent.checked ? "on" : "off"
+ anchors.centerIn: parent
+ }
+}
diff --git a/examples/declarative/accessibility/widgets/Slider.qml b/examples/declarative/accessibility/widgets/Slider.qml
new file mode 100644
index 0000000000..32aa6a3a41
--- /dev/null
+++ b/examples/declarative/accessibility/widgets/Slider.qml
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+import QtQuick 2.0
+
+// Minimal slider implementation
+Rectangle {
+ id: slider
+
+ property alias text : buttonText.text
+ Accessible.role: Accessible.Slider
+
+ property int value // required
+ property int minimumValue : 0 // optional (default INT_MIN)
+ property int maximumValue : 20 // optional (default INT_MAX)
+ property int stepSize : 1 // optional (default 1)
+
+ width: 30
+ height: 30
+
+
+ Text {
+ id: buttonText
+ text: parent.value
+ anchors.centerIn: parent
+ font.pixelSize: parent.height * .5
+ }
+}
diff --git a/examples/quick/accessibility/accessibility.qml b/examples/quick/accessibility/accessibility.qml
index 2804d2abc8..e987561bb1 100644
--- a/examples/quick/accessibility/accessibility.qml
+++ b/examples/quick/accessibility/accessibility.qml
@@ -59,12 +59,13 @@ Rectangle {
id: column
spacing: 6
anchors.fill: parent
+ anchors.margins: 10
width: parent.width
Row {
spacing: 6
width: column.width
- Button { width: 100; height: column.h + 20; text: "Send" }
- Button { width: 100; height: column.h + 20; text: "Discard" }
+ Button { width: 100; height: column.h + 20; text: "Send"; onClicked : { status.text = "Send" } }
+ Button { width: 100; height: column.h + 20; text: "Discard"; onClicked : { status.text = "Discard" } }
}
Row {
@@ -106,5 +107,16 @@ Rectangle {
wrapMode: TextEdit.WordWrap
}
}
+ Text {
+ id : status
+ width: column.width
+ }
+
+ Row {
+ spacing: 6
+ width: column.width
+ Checkbox { checked: false }
+ Slider { value: 10 }
+ }
}
}
diff --git a/examples/quick/accessibility/content/Button.qml b/examples/quick/accessibility/content/Button.qml
index 2c203abe11..3d5086f741 100644
--- a/examples/quick/accessibility/content/Button.qml
+++ b/examples/quick/accessibility/content/Button.qml
@@ -49,6 +49,9 @@ Rectangle {
Accessible.name: text
Accessible.description: "This button does " + text
Accessible.role: Accessible.Button
+ function accessiblePressAction() {
+ button.clicked()
+ }
signal clicked
@@ -74,7 +77,7 @@ Rectangle {
id: mouseArea
anchors.fill: parent
onClicked: {
- checked = !checked;
+ parent.clicked()
}
}
}
diff --git a/src/plugins/accessible/quick/main.cpp b/src/plugins/accessible/quick/main.cpp
index 6ff3d5db9e..2c75e594c2 100644
--- a/src/plugins/accessible/quick/main.cpp
+++ b/src/plugins/accessible/quick/main.cpp
@@ -99,6 +99,7 @@ QAccessibleInterface *AccessibleQuickFactory::create(const QString &classname, Q
case QAccessible::Slider:
case QAccessible::SpinBox:
case QAccessible::Dial:
+ case QAccessible::ScrollBar:
return new QAccessibleQuickItemValueInterface(item);
default:
return new QAccessibleQuickItem(item);
diff --git a/src/plugins/accessible/shared/qqmlaccessible.cpp b/src/plugins/accessible/shared/qqmlaccessible.cpp
index 1818ebebfe..70c6b90efe 100644
--- a/src/plugins/accessible/shared/qqmlaccessible.cpp
+++ b/src/plugins/accessible/shared/qqmlaccessible.cpp
@@ -59,6 +59,13 @@ QQmlAccessible::QQmlAccessible(QObject *object)
{
}
+void *QQmlAccessible::interface_cast(QAccessible::InterfaceType t)
+{
+ if (t == QAccessible::ActionInterface)
+ return static_cast<QAccessibleActionInterface*>(this);
+ return QAccessibleObject::interface_cast(t);
+}
+
QQmlAccessible::~QQmlAccessible()
{
}
@@ -131,7 +138,15 @@ QStringList QQmlAccessible::actionNames() const
break;
case QAccessible::RadioButton:
case QAccessible::CheckBox:
- actions << QAccessibleActionInterface::checkAction();
+ actions << QAccessibleActionInterface::checkAction()
+ << QAccessibleActionInterface::uncheckAction()
+ << QAccessibleActionInterface::pressAction();
+ break;
+ case QAccessible::Slider:
+ case QAccessible::SpinBox:
+ case QAccessible::ScrollBar:
+ actions << QAccessibleActionInterface::increaseAction()
+ << QAccessibleActionInterface::decreaseAction();
break;
default:
break;
@@ -141,12 +156,72 @@ QStringList QQmlAccessible::actionNames() const
void QQmlAccessible::doAction(const QString &actionName)
{
- if (role() == QAccessible::PushButton && actionName == QAccessibleActionInterface::pressAction()) {
- QMetaObject::invokeMethod(object(), "accessibleAction");
+ // Look for and call the accessible[actionName]Action() function on the item.
+ // This allows for overriding the default action handling.
+ const QByteArray functionName = "accessible" + actionName.toLatin1() + "Action()";
+ if (object()->metaObject()->indexOfMethod(functionName) != -1) {
+ QMetaObject::invokeMethod(object(), functionName, Q_ARG(QString, actionName));
+ return;
}
- if ((role() == QAccessible::CheckBox || role() == QAccessible::RadioButton) && actionName == QAccessibleActionInterface::checkAction()) {
- bool checked = object()->property("checked").toBool();
- object()->setProperty("checked", QVariant(!checked));
+
+ // Role-specific default action handling follows. Items are excepted to provide
+ // properties according to role conventions. These will then be read and/or updated
+ // by the accessibility system.
+ // Checkable roles : checked
+ // Value-based roles : (via the value interface: value, minimumValue, maximumValue), stepSize
+ switch (role()) {
+ case QAccessible::RadioButton:
+ case QAccessible::CheckBox: {
+ QVariant checked = object()->property("checked");
+ if (checked.isValid()) {
+ if (actionName == QAccessibleActionInterface::pressAction()) {
+ object()->setProperty("checked", QVariant(!checked.toBool()));
+ } else if (actionName == QAccessibleActionInterface::checkAction()) {
+ object()->setProperty("checked", QVariant(true));
+ } else if (actionName == QAccessibleActionInterface::uncheckAction()) {
+ object()->setProperty("checked", QVariant(false));
+ }
+ }
+ break;
+ }
+ case QAccessible::Slider:
+ case QAccessible::SpinBox:
+ case QAccessible::Dial:
+ case QAccessible::ScrollBar: {
+ if (actionName != QAccessibleActionInterface::increaseAction() &&
+ actionName != QAccessibleActionInterface::decreaseAction())
+ break;
+
+ // Update the value using QAccessibleValueInterface, respecting
+ // the minimum and maximum value (if set). Also check for and
+ // use the "stepSize" property on the item
+ if (QAccessibleValueInterface *valueIface = valueInterface()) {
+ QVariant valueV = valueIface->currentValue();
+ qreal newValue = valueV.toInt();
+
+ QVariant stepSizeV = object()->property("stepSize");
+ qreal stepSize = stepSizeV.isValid() ? stepSizeV.toReal() : qreal(1.0);
+ if (actionName == QAccessibleActionInterface::increaseAction()) {
+ newValue += stepSize;
+ } else {
+ newValue -= stepSize;
+ }
+
+ QVariant minimumValueV = valueIface->minimumValue();
+ if (minimumValueV.isValid()) {
+ newValue = qMax(newValue, minimumValueV.toReal());
+ }
+ QVariant maximumValueV = valueIface->maximumValue();
+ if (maximumValueV.isValid()) {
+ newValue = qMin(newValue, maximumValueV.toReal());
+ }
+
+ valueIface->setCurrentValue(QVariant(newValue));
+ }
+ break;
+ }
+ default:
+ break;
}
}
diff --git a/src/plugins/accessible/shared/qqmlaccessible.h b/src/plugins/accessible/shared/qqmlaccessible.h
index 570a3c8c40..ec26aa2306 100644
--- a/src/plugins/accessible/shared/qqmlaccessible.h
+++ b/src/plugins/accessible/shared/qqmlaccessible.h
@@ -74,6 +74,7 @@ class QQmlAccessible: public QAccessibleObject, public QAccessibleActionInterfac
{
public:
~QQmlAccessible();
+ void *interface_cast(QAccessible::InterfaceType t);
virtual QRect viewRect() const = 0;
QAccessibleInterface *childAt(int, int) const;
diff --git a/src/quick/items/qquickaccessibleattached.cpp b/src/quick/items/qquickaccessibleattached.cpp
index 177454eedc..1e07d96690 100644
--- a/src/quick/items/qquickaccessibleattached.cpp
+++ b/src/quick/items/qquickaccessibleattached.cpp
@@ -104,6 +104,7 @@ QT_BEGIN_NAMESPACE
}
Accessible.name: label.text
Accessible.role: Accessible.Button
+ funtion accessiblePressAction { ... }
}
\endqml
@@ -117,24 +118,19 @@ QT_BEGIN_NAMESPACE
\o
\row
- \o CheckBox
- \o checked
- \o The check state of the check box.
+ \o Button
+ \o function accessiblePressAction
+ \o Called when the button receives a press action. The implementation should visually simulate a button click and perform the button action.
\row
- \o RadioButton
+ \o CheckBox, Radiobutton
\o checked
- \o The selected state of the radio button.
- \row
- \o Button
- \o checkable
- \o Whether the button is checkable.
+ \o The check state of the check box. Updated on Press, Check and Uncheck actions.
\row
- \o Button
- \o checked
- \o Whether the button is checked (only if checkable is true).
+ \o Slider, SpinBox, Dial, ScrollBar
+ \o value, minimumValue, maximumValue, stepSize
+ \o value will be updated on increase and decrase actions, in accordance with the other properties
\endtable
-
*/
QQuickAccessibleAttached::QQuickAccessibleAttached(QObject *parent)