implemented accessible tree

This commit is contained in:
Igor Korsukov 2021-05-20 16:52:50 +02:00 committed by pereverzev+v
parent 73b50d98ca
commit b30a63ff38
15 changed files with 306 additions and 257 deletions

View file

@ -32,8 +32,6 @@ set(MODULE_SRC
${CMAKE_CURRENT_LIST_DIR}/internal/accessibilitycontroller.h
${CMAKE_CURRENT_LIST_DIR}/internal/accessibleobject.cpp
${CMAKE_CURRENT_LIST_DIR}/internal/accessibleobject.h
${CMAKE_CURRENT_LIST_DIR}/internal/accessiblecontrollerinterface.cpp
${CMAKE_CURRENT_LIST_DIR}/internal/accessiblecontrollerinterface.h
${CMAKE_CURRENT_LIST_DIR}/internal/accessibleiteminterface.cpp
${CMAKE_CURRENT_LIST_DIR}/internal/accessibleiteminterface.h
)

View file

@ -23,6 +23,7 @@
#define MU_ACCESSIBILITY_IACCESSIBILITY_H
#include <QString>
#include "async/notification.h"
namespace mu::accessibility {
class IAccessibility
@ -30,6 +31,7 @@ class IAccessibility
public:
enum class Role {
NoRole = 0,
Application,
Panel,
Button
};
@ -41,6 +43,11 @@ public:
Focused
};
virtual const IAccessibility* accessibleParent() const = 0;
virtual async::Notification accessibleParentChanged() const = 0;
virtual size_t accessibleChildCount() const = 0;
virtual const IAccessibility* accessibleChild(size_t i) const = 0;
virtual Role accessibleRole() const = 0;
virtual QString accessibleName() const = 0;
virtual bool accessibleState(State st) const = 0;

View file

@ -33,8 +33,11 @@ class IAccessibilityController : MODULE_EXPORT_INTERFACE
public:
virtual ~IAccessibilityController() = default;
virtual void created(IAccessibility* parent, IAccessibility* item) = 0;
virtual void destroyed(IAccessibility* item) = 0;
virtual const IAccessibility* rootItem() const = 0;
virtual void reg(IAccessibility* item) = 0;
virtual void unreg(IAccessibility* item) = 0;
virtual void actived(IAccessibility* item, bool isActive) = 0;
virtual void focused(IAccessibility* item) = 0;
};

View file

@ -25,26 +25,34 @@
#include <QAccessible>
#include "accessibleobject.h"
#include "accessiblecontrollerinterface.h"
#include "accessibleiteminterface.h"
#include "async/async.h"
#include "log.h"
#define ACCESSIBILITY_LOGGING_ENABLED
#ifdef ACCESSIBILITY_LOGGING_ENABLED
#define MYLOG() LOGI()
#else
#define MYLOG() LOGN()
#endif
using namespace mu::accessibility;
AccessibilityController::~AccessibilityController()
{
unreg(this);
}
static QAccessibleInterface* muAccessibleFactory(const QString& classname, QObject* object)
{
if (classname == QLatin1String("mu::accessibility::AccessibleObject")) {
return static_cast<QAccessibleInterface*>(new AccessibleItemInterface(object));
}
if (classname == QLatin1String("mu::accessibility::AccessibilityController")) {
return static_cast<QAccessibleInterface*>(new AccessibleControllerInterface(object));
AccessibleObject* aobj = qobject_cast<AccessibleObject*>(object);
IF_ASSERT_FAILED(aobj) {
return nullptr;
}
return static_cast<QAccessibleInterface*>(new AccessibleItemInterface(aobj));
}
return nullptr;
@ -54,54 +62,75 @@ static void updateHandlerNoop(QAccessibleEvent*)
{
}
static void rootObjectHandlerNoop(QObject*)
{
}
void AccessibilityController::init()
{
setObjectName("AccessibilityController");
QAccessible::installFactory(muAccessibleFactory);
QAccessible::setRootObject(this);
QAccessible::installRootObjectHandler([](QObject*) {});
reg(this);
const Item& self = findItem(this);
QAccessible::installRootObjectHandler(nullptr);
QAccessible::setRootObject(self.object);
//! NOTE Disabled any events from Qt
QAccessible::installRootObjectHandler(rootObjectHandlerNoop);
QAccessible::installUpdateHandler(updateHandlerNoop);
}
void AccessibilityController::created(IAccessibility* parent, IAccessibility* item)
const IAccessibility* AccessibilityController::rootItem() const
{
//! TODO Not working yet
parent = nullptr;
return this;
}
QObject* prnObj = nullptr;
if (parent) {
prnObj = findItem(parent).object;
} else {
prnObj = this;
void AccessibilityController::reg(IAccessibility* item)
{
if (findItem(item).isValid()) {
LOGW() << "Already registered";
return;
}
MYLOG() << "item: " << item->accessibleName();
Item it;
it.parent = parent;
it.item = item;
it.object = new AccessibleObject(item, prnObj);
it.object = new AccessibleObject(item);
it.object->setController(shared_from_this());
it.iface = QAccessible::queryAccessibleInterface(it.object);
m_items.append(it);
m_allItems.insert(item, it);
LOGI() << "parent: " << (parent ? parent->accessibleName() : "") << ", item: " << item->accessibleName();
if (item->accessibleParent() == this) {
m_children.append(item);
}
item->accessibleParentChanged().onNotify(this, [this, item]() {
const Item& it = findItem(item);
if (!it.isValid()) {
return;
}
QAccessibleEvent ev(it.object, QAccessible::ParentChanged);
sendEvent(&ev);
});
QAccessibleEvent ev(it.object, QAccessible::ObjectCreated);
sendEvent(&ev);
}
void AccessibilityController::destroyed(IAccessibility* aitem)
void AccessibilityController::unreg(IAccessibility* aitem)
{
LOGI() << aitem->accessibleName();
int idx = indexBy(aitem);
IF_ASSERT_FAILED(idx >= 0) {
return;
MYLOG() << aitem->accessibleName();
Item item = m_allItems.take(aitem);
if (aitem->accessibleParent() == this) {
m_children.removeOne(aitem);
}
Item item = m_items.takeAt(idx);
QAccessibleEvent ev(item.object, QAccessible::ObjectDestroyed);
sendEvent(&ev);
@ -110,7 +139,7 @@ void AccessibilityController::destroyed(IAccessibility* aitem)
void AccessibilityController::actived(IAccessibility* aitem, bool isActive)
{
LOGI() << aitem->accessibleName() << " " << isActive;
MYLOG() << aitem->accessibleName() << " " << isActive;
const Item& item = findItem(aitem);
IF_ASSERT_FAILED(item.isValid()) {
return;
@ -124,7 +153,7 @@ void AccessibilityController::actived(IAccessibility* aitem, bool isActive)
void AccessibilityController::focused(IAccessibility* aitem)
{
LOGI() << aitem->accessibleName();
MYLOG() << aitem->accessibleName();
const Item& item = findItem(aitem);
IF_ASSERT_FAILED(item.isValid()) {
return;
@ -142,64 +171,127 @@ void AccessibilityController::sendEvent(QAccessibleEvent* ev)
QAccessible::installUpdateHandler(updateHandlerNoop);
}
const AccessibilityController::Item& AccessibilityController::findItem(IAccessibility* aitem) const
const AccessibilityController::Item& AccessibilityController::findItem(const IAccessibility* aitem) const
{
for (int i = 0; i < m_items.count(); ++i) {
if (m_items.at(i).item == aitem) {
return m_items.at(i);
}
auto it = m_allItems.find(aitem);
if (it != m_allItems.end()) {
return it.value();
}
static AccessibilityController::Item null;
return null;
}
int AccessibilityController::indexBy(IAccessibility* aitem) const
QAccessibleInterface* AccessibilityController::parentIface(const IAccessibility* item) const
{
for (int i = 0; i < m_items.count(); ++i) {
if (m_items.at(i).item == aitem) {
return i;
IF_ASSERT_FAILED(item) {
return nullptr;
}
const IAccessibility* parent = item->accessibleParent();
if (!parent) {
return nullptr;
}
const Item& it = findItem(parent);
if (!it.isValid()) {
return nullptr;
}
return it.iface;
}
int AccessibilityController::childCount(const IAccessibility* item) const
{
IF_ASSERT_FAILED(item) {
return 0;
}
const Item& it = findItem(item);
IF_ASSERT_FAILED(it.isValid()) {
return 0;
}
return it.item->accessibleChildCount();
}
QAccessibleInterface* AccessibilityController::child(const IAccessibility* item, int i) const
{
IF_ASSERT_FAILED(item) {
return nullptr;
}
const IAccessibility* chld = item->accessibleChild(static_cast<size_t>(i));
IF_ASSERT_FAILED(chld) {
return nullptr;
}
const Item& chldIt = findItem(chld);
IF_ASSERT_FAILED(chldIt.isValid()) {
return nullptr;
}
return chldIt.iface;
}
int AccessibilityController::indexOfChild(const IAccessibility* item, const QAccessibleInterface* iface) const
{
TRACEFUNC;
size_t count = item->accessibleChildCount();
for (size_t i = 0; i < count; ++i) {
const IAccessibility* ch = item->accessibleChild(i);
const Item& chIt = findItem(ch);
IF_ASSERT_FAILED(chIt.isValid()) {
continue;
}
if (chIt.iface == iface) {
return static_cast<int>(i);
}
}
return -1;
}
int AccessibilityController::childCount(const IAccessibility* aitem) const
IAccessibility* AccessibilityController::accessibleParent() const
{
int count = 0;
for (const Item& item: m_items) {
if (item.parent == aitem) {
++count;
}
}
return count;
}
QAccessibleInterface* AccessibilityController::child(const IAccessibility* aitem, int i) const
{
int idx = -1;
for (const Item& item: m_items) {
if (item.parent == aitem) {
++idx;
if (idx == i) {
return item.iface;
}
}
}
return nullptr;
}
int AccessibilityController::indexOfChild(const IAccessibility* aitem, const QAccessibleInterface* iface) const
mu::async::Notification AccessibilityController::accessibleParentChanged() const
{
int idx = -1;
for (const Item& item: m_items) {
if (item.parent == aitem) {
++idx;
if (item.iface == iface) {
return idx;
}
}
static mu::async::Notification notification;
return notification;
}
size_t AccessibilityController::accessibleChildCount() const
{
return static_cast<size_t>(m_children.size());
}
IAccessibility* AccessibilityController::accessibleChild(size_t i) const
{
return m_children.at(static_cast<int>(i));
}
IAccessibility::Role AccessibilityController::accessibleRole() const
{
return IAccessibility::Role::Application;
}
QString AccessibilityController::accessibleName() const
{
return QString("AccessibilityController");
}
bool AccessibilityController::accessibleState(State st) const
{
switch (st) {
case State::Undefined: return false;
case State::Disabled: return false;
case State::Active: return true;
default: {
LOGW() << "not handled state: " << static_cast<int>(st);
}
}
return -1;
return false;
}

View file

@ -25,29 +25,48 @@
#include <memory>
#include <QObject>
#include <QList>
#include <QHash>
#include "../iaccessibilitycontroller.h"
#include "accessibleobject.h"
#include "async/asyncable.h"
class QAccessibleInterface;
class QAccessibleEvent;
namespace mu::accessibility {
class AccessibilityController : public QObject, public IAccessibilityController,
class AccessibilityController : public IAccessibilityController, public IAccessibility, public async::Asyncable,
public std::enable_shared_from_this<AccessibilityController>
{
Q_OBJECT
public:
AccessibilityController() = default;
~AccessibilityController();
void init();
void created(IAccessibility* parent, IAccessibility* item) override;
void destroyed(IAccessibility* item) override;
// IAccessibilityController
const IAccessibility* rootItem() const override;
void reg(IAccessibility* item) override;
void unreg(IAccessibility* item) override;
void actived(IAccessibility* item, bool isActive) override;
void focused(IAccessibility* item) override;
// -----
// IAccessibility
IAccessibility* accessibleParent() const override;
async::Notification accessibleParentChanged() const override;
size_t accessibleChildCount() const override;
IAccessibility* accessibleChild(size_t i) const override;
Role accessibleRole() const override;
QString accessibleName() const override;
bool accessibleState(State st) const override;
// -----
QAccessibleInterface* parentIface(const IAccessibility* item) const;
int childCount(const IAccessibility* item) const;
QAccessibleInterface* child(const IAccessibility* item, int i) const;
int indexOfChild(const IAccessibility* item, const QAccessibleInterface* iface) const;
@ -56,7 +75,6 @@ private:
struct Item
{
IAccessibility* parent = nullptr;
IAccessibility* item = nullptr;
AccessibleObject* object = nullptr;
QAccessibleInterface* iface = nullptr;
@ -64,12 +82,13 @@ private:
bool isValid() const { return item != nullptr; }
};
const Item& findItem(IAccessibility* aitem) const;
int indexBy(IAccessibility* aitem) const;
const Item& findItem(const IAccessibility* aitem) const;
void sendEvent(QAccessibleEvent* ev);
QList<Item> m_items;
QHash<const IAccessibility*, Item> m_allItems;
QList<IAccessibility*> m_children;
};
}

View file

@ -1,101 +0,0 @@
/*
* SPDX-License-Identifier: GPL-3.0-only
* MuseScore-CLA-applies
*
* MuseScore
* Music Composition & Notation
*
* Copyright (C) 2021 MuseScore BVBA and others
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "accessiblecontrollerinterface.h"
#include "accessibilitycontroller.h"
#include "log.h"
using namespace mu::accessibility;
AccessibleControllerInterface::AccessibleControllerInterface(QObject* o)
{
m_controller = qobject_cast<AccessibilityController*>(o);
}
bool AccessibleControllerInterface::isValid() const
{
return m_controller != nullptr;
}
QObject* AccessibleControllerInterface::object() const
{
return m_controller;
}
QWindow* AccessibleControllerInterface::window() const
{
return nullptr;
}
QRect AccessibleControllerInterface::rect() const
{
return QRect();
}
QAccessibleInterface* AccessibleControllerInterface::parent() const
{
return nullptr;
}
int AccessibleControllerInterface::childCount() const
{
return m_controller->childCount(nullptr);
}
QAccessibleInterface* AccessibleControllerInterface::child(int i) const
{
return m_controller->child(nullptr, i);
}
QAccessibleInterface* AccessibleControllerInterface::childAt(int, int) const
{
NOT_IMPLEMENTED;
return nullptr;
}
int AccessibleControllerInterface::indexOfChild(const QAccessibleInterface* iface) const
{
return m_controller->indexOfChild(nullptr, iface);
}
QAccessible::Role AccessibleControllerInterface::role() const
{
return QAccessible::Application;
}
QAccessible::State AccessibleControllerInterface::state() const
{
QAccessible::State state;
state.active = 1;
return state;
}
QString AccessibleControllerInterface::text(QAccessible::Text) const
{
return QString();
}
void AccessibleControllerInterface::setText(QAccessible::Text, const QString&)
{
NOT_IMPLEMENTED;
}

View file

@ -1,58 +0,0 @@
/*
* SPDX-License-Identifier: GPL-3.0-only
* MuseScore-CLA-applies
*
* MuseScore
* Music Composition & Notation
*
* Copyright (C) 2021 MuseScore BVBA and others
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef CONTROLLERACCESSIBLEINTERFACE_H
#define CONTROLLERACCESSIBLEINTERFACE_H
#include <QAccessibleInterface>
namespace mu::accessibility {
class AccessibilityController;
class AccessibleControllerInterface : public QAccessibleInterface
{
public:
AccessibleControllerInterface(QObject* o);
bool isValid() const override;
QObject* object() const override;
QWindow* window() const override;
QRect rect() const override;
QAccessibleInterface* parent() const override;
int childCount() const override;
QAccessibleInterface* child(int i) const override;
QAccessibleInterface* childAt(int x, int y) const override;
int indexOfChild(const QAccessibleInterface* iface) const override;
QAccessible::Role role() const override;
QAccessible::State state() const override;
QString text(QAccessible::Text) const override;
void setText(QAccessible::Text t, const QString& text) override;
private:
AccessibilityController* m_controller = nullptr;
};
}
#endif // CONTROLLERACCESSIBLEINTERFACE_H

View file

@ -29,9 +29,9 @@
using namespace mu::accessibility;
AccessibleItemInterface::AccessibleItemInterface(QObject* object)
AccessibleItemInterface::AccessibleItemInterface(AccessibleObject* object)
{
m_object = qobject_cast<AccessibleObject*>(object);
m_object = object;
}
bool AccessibleItemInterface::isValid() const
@ -58,22 +58,30 @@ QRect AccessibleItemInterface::rect() const
QAccessibleInterface* AccessibleItemInterface::parent() const
{
return QAccessible::queryAccessibleInterface(m_object->parent());
QAccessibleInterface* iface = m_object->controller()->parentIface(m_object->item());
LOGI() << "item: " << m_object->item()->accessibleName() << ", parent: " << (iface ? iface->text(QAccessible::Name) : "null");
return iface;
}
int AccessibleItemInterface::childCount() const
{
return m_object->controller()->childCount(m_object->item());
int count = m_object->controller()->childCount(m_object->item());
LOGI() << "item: " << m_object->item()->accessibleName() << ", childCount: " << count;
return count;
}
QAccessibleInterface* AccessibleItemInterface::child(int index) const
{
return m_object->controller()->child(m_object->item(), index);
QAccessibleInterface* iface = m_object->controller()->child(m_object->item(), index);
LOGI() << "item: " << m_object->item()->accessibleName() << ", child: " << index << " " << iface->text(QAccessible::Name);
return iface;
}
int AccessibleItemInterface::indexOfChild(const QAccessibleInterface* iface) const
{
return m_object->controller()->indexOfChild(m_object->item(), iface);
int idx = m_object->controller()->indexOfChild(m_object->item(), iface);
LOGI() << "item: " << m_object->item()->accessibleName() << ", indexOfChild: " << iface->text(QAccessible::Name) << " = " << idx;
return idx;
}
QAccessibleInterface* AccessibleItemInterface::childAt(int, int) const
@ -99,6 +107,9 @@ QAccessible::State AccessibleItemInterface::state() const
IAccessibility::Role r = m_object->item()->accessibleRole();
switch (r) {
case IAccessibility::Role::NoRole: break;
case IAccessibility::Role::Application: {
state.active = item->accessibleState(IAccessibility::State::Active);
} break;
case IAccessibility::Role::Panel: {
state.active = item->accessibleState(IAccessibility::State::Active);
} break;
@ -116,6 +127,7 @@ QAccessible::Role AccessibleItemInterface::role() const
IAccessibility::Role r = m_object->item()->accessibleRole();
switch (r) {
case IAccessibility::Role::NoRole: return QAccessible::NoRole;
case IAccessibility::Role::Application: return QAccessible::Application;
case IAccessibility::Role::Panel: return QAccessible::Pane;
case IAccessibility::Role::Button: return QAccessible::Button;
}

View file

@ -35,7 +35,7 @@ class AccessibleItemInterface : public QAccessibleInterface
INJECT(accessibility, ui::IMainWindow, mainWindow)
public:
AccessibleItemInterface(QObject* object);
AccessibleItemInterface(AccessibleObject* object);
bool isValid() const override;
QObject* object() const override;

View file

@ -25,8 +25,8 @@
using namespace mu::accessibility;
AccessibleObject::AccessibleObject(IAccessibility* item, QObject* parent)
: QObject(parent)
AccessibleObject::AccessibleObject(IAccessibility* item)
: QObject()
{
setObjectName("AccessibleObject");
m_item = item;

View file

@ -31,7 +31,7 @@ class AccessibleObject : public QObject
{
Q_OBJECT
public:
explicit AccessibleObject(IAccessibility* item, QObject* parent);
explicit AccessibleObject(IAccessibility* item);
void setController(std::shared_ptr<AccessibilityController> controller);
const std::shared_ptr<AccessibilityController>& controller() const;

View file

@ -34,16 +34,16 @@ NavigationControl::NavigationControl(QObject* parent)
NavigationControl::~NavigationControl()
{
accessibilityController()->unreg(this);
if (m_panel) {
m_panel->removeControl(this);
}
accessibilityController()->destroyed(this);
}
void NavigationControl::componentComplete()
{
AbstractNavigation::componentComplete();
accessibilityController()->created(m_panel, this);
accessibilityController()->reg(this);
}
QString NavigationControl::name() const
@ -129,6 +129,7 @@ void NavigationControl::setPanel(NavigationPanel* panel)
}
emit panelChanged(m_panel);
m_accessibleParentChanged.notify();
}
void NavigationControl::onPanelDestroyed()
@ -146,6 +147,26 @@ INavigationPanel* NavigationControl::panel() const
return m_panel;
}
const IAccessibility* NavigationControl::accessibleParent() const
{
return m_panel;
}
mu::async::Notification NavigationControl::accessibleParentChanged() const
{
return m_accessibleParentChanged;
}
size_t NavigationControl::accessibleChildCount() const
{
return 0;
}
const IAccessibility* NavigationControl::accessibleChild(size_t) const
{
return nullptr;
}
IAccessibility::Role NavigationControl::accessibleRole() const
{
return IAccessibility::Role::Button;

View file

@ -69,9 +69,16 @@ public:
void componentComplete() override;
// IAccessibility
const IAccessibility* accessibleParent() const override;
async::Notification accessibleParentChanged() const override;
size_t accessibleChildCount() const override;
const IAccessibility* accessibleChild(size_t i) const override;
IAccessibility::Role accessibleRole() const override;
QString accessibleName() const override;
bool accessibleState(State st) const override;
// -----
public slots:
void setPanel(NavigationPanel* panel);
@ -87,6 +94,8 @@ private:
NavigationPanel* m_panel = nullptr;
async::Channel<INavigationControl*> m_forceActiveRequested;
async::Notification m_accessibleParentChanged;
};
}

View file

@ -36,11 +36,10 @@ NavigationPanel::NavigationPanel(QObject* parent)
NavigationPanel::~NavigationPanel()
{
accessibilityController()->unreg(this);
if (m_section) {
m_section->removePanel(this);
}
accessibilityController()->destroyed(this);
}
QString NavigationPanel::name() const
@ -179,7 +178,7 @@ void NavigationPanel::onSectionDestroyed()
void NavigationPanel::componentComplete()
{
accessibilityController()->created(nullptr, this);
accessibilityController()->reg(this);
}
void NavigationPanel::addControl(NavigationControl* control)
@ -198,6 +197,9 @@ void NavigationPanel::addControl(NavigationControl* control)
if (m_controlsListChanged.isConnected()) {
m_controlsListChanged.notify();
}
//! TODO Maybe need sorting
m_accessibleControls.push_back(control);
}
void NavigationPanel::removeControl(NavigationControl* control)
@ -213,6 +215,32 @@ void NavigationPanel::removeControl(NavigationControl* control)
if (m_controlsListChanged.isConnected()) {
m_controlsListChanged.notify();
}
m_accessibleControls.erase(std::remove(m_accessibleControls.begin(), m_accessibleControls.end(), control), m_accessibleControls.end());
}
const IAccessibility* NavigationPanel::accessibleParent() const
{
return accessibilityController()->rootItem();
}
mu::async::Notification NavigationPanel::accessibleParentChanged() const
{
static async::Notification notification;
return notification;
}
size_t NavigationPanel::accessibleChildCount() const
{
return m_accessibleControls.size();
}
const IAccessibility* NavigationPanel::accessibleChild(size_t i) const
{
IF_ASSERT_FAILED(i < m_accessibleControls.size()) {
return nullptr;
}
return m_accessibleControls.at(i);
}
IAccessibility::Role NavigationPanel::accessibleRole() const
@ -222,7 +250,17 @@ IAccessibility::Role NavigationPanel::accessibleRole() const
QString NavigationPanel::accessibleName() const
{
return name();
QString dirc;
switch (m_direction) {
case Horizontal: dirc = "Horizontal";
break;
case Vertical: dirc = "Vertical";
break;
case Both: dirc = "Both";
break;
}
return name() + " direction " + dirc;
}
bool NavigationPanel::accessibleState(State st) const

View file

@ -86,9 +86,16 @@ public:
void removeControl(NavigationControl* control);
// IAccessibility
const IAccessibility* accessibleParent() const override;
async::Notification accessibleParentChanged() const override;
size_t accessibleChildCount() const override;
const IAccessibility* accessibleChild(size_t i) const override;
Role accessibleRole() const override;
QString accessibleName() const override;
bool accessibleState(State st) const override;
// -----
public slots:
void setSection_property(NavigationSection* section);
@ -108,6 +115,8 @@ private:
async::Notification m_controlsListChanged;
async::Channel<PanelControl> m_forceActiveRequested;
QmlDirection m_direction = QmlDirection::Horizontal;
std::vector<NavigationControl*> m_accessibleControls;
};
}