aboutsummaryrefslogtreecommitdiffstats
path: root/src
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 /src
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>
Diffstat (limited to 'src')
-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
4 files changed, 92 insertions, 19 deletions
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)