diff options
author | Morten Johan Sorvig <[email protected]> | 2012-01-10 12:12:51 +0100 |
---|---|---|
committer | Qt by Nokia <[email protected]> | 2012-03-07 20:08:19 +0100 |
commit | 70966df1be02dd94ecf9a122ff9e4976245aeb92 (patch) | |
tree | 372db90105c34d0c2a72e029f4e087fdc93423b7 /src/plugins | |
parent | 3f9b58c0890a4263730e2c06b46e7a69d4bfb62d (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 <[email protected]>
Diffstat (limited to 'src/plugins')
-rw-r--r-- | src/plugins/accessible/quick/main.cpp | 1 | ||||
-rw-r--r-- | src/plugins/accessible/shared/qqmlaccessible.cpp | 87 | ||||
-rw-r--r-- | src/plugins/accessible/shared/qqmlaccessible.h | 1 |
3 files changed, 83 insertions, 6 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; |