GUI: Add accessibility region role for landmark navigation
Adds ROLE_REGION to allow controls to be marked as accessibility regions/landmarks. - Add `accessibility_region` property to Control - Add ROLE_REGION to DisplayServer and AccessKit mapping - Prevent Container/ScrollContainer from overriding region role - Fix TabContainer to update accessibility when tabs change - Mark editor docks, main screen, bottom panel, and scene tabs as regions
This commit is contained in:
parent
5f9a510441
commit
d53ab67b83
13 changed files with 57 additions and 2 deletions
|
|
@ -40,6 +40,9 @@
|
|||
</method>
|
||||
</methods>
|
||||
<members>
|
||||
<member name="accessibility_region" type="bool" setter="set_accessibility_region" getter="is_accessibility_region" default="false">
|
||||
If [code]true[/code], this container is marked as a region for accessibility. Use [member Control.accessibility_name] to give the region a descriptive name. Screen readers can navigate between regions using landmark navigation.
|
||||
</member>
|
||||
<member name="mouse_filter" type="int" setter="set_mouse_filter" getter="get_mouse_filter" overrides="Control" enum="Control.MouseFilter" default="1" />
|
||||
</members>
|
||||
<signals>
|
||||
|
|
|
|||
|
|
@ -2775,6 +2775,9 @@
|
|||
<constant name="ROLE_TOOLTIP" value="45" enum="AccessibilityRole">
|
||||
Tooltip element.
|
||||
</constant>
|
||||
<constant name="ROLE_REGION" value="46" enum="AccessibilityRole">
|
||||
Region/landmark element. Screen readers can navigate between regions using landmark navigation.
|
||||
</constant>
|
||||
<constant name="POPUP_MENU" value="0" enum="AccessibilityPopupType">
|
||||
Popup menu.
|
||||
</constant>
|
||||
|
|
|
|||
|
|
@ -1657,6 +1657,7 @@ AccessibilityDriverAccessKit::AccessibilityDriverAccessKit() {
|
|||
role_map[DisplayServer::AccessibilityRole::ROLE_TITLE_BAR] = ACCESSKIT_ROLE_TITLE_BAR;
|
||||
role_map[DisplayServer::AccessibilityRole::ROLE_DIALOG] = ACCESSKIT_ROLE_DIALOG;
|
||||
role_map[DisplayServer::AccessibilityRole::ROLE_TOOLTIP] = ACCESSKIT_ROLE_TOOLTIP;
|
||||
role_map[DisplayServer::AccessibilityRole::ROLE_REGION] = ACCESSKIT_ROLE_REGION;
|
||||
|
||||
action_map[DisplayServer::AccessibilityAction::ACTION_CLICK] = ACCESSKIT_ACTION_CLICK;
|
||||
action_map[DisplayServer::AccessibilityAction::ACTION_FOCUS] = ACCESSKIT_ACTION_FOCUS;
|
||||
|
|
|
|||
|
|
@ -43,6 +43,15 @@ void EditorDock::_emit_changed() {
|
|||
emit_signal(SNAME("_tab_style_changed"));
|
||||
}
|
||||
|
||||
void EditorDock::_notification(int p_what) {
|
||||
switch (p_what) {
|
||||
case NOTIFICATION_READY: {
|
||||
set_accessibility_region(true);
|
||||
set_accessibility_name(get_display_title());
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void EditorDock::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("open"), &EditorDock::open);
|
||||
ClassDB::bind_method(D_METHOD("make_visible"), &EditorDock::make_visible);
|
||||
|
|
@ -142,6 +151,7 @@ void EditorDock::set_title(const String &p_title) {
|
|||
return;
|
||||
}
|
||||
title = p_title;
|
||||
set_accessibility_name(get_display_title());
|
||||
_emit_changed();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -94,6 +94,7 @@ private:
|
|||
void _emit_changed();
|
||||
|
||||
protected:
|
||||
void _notification(int p_what);
|
||||
static void _bind_methods();
|
||||
|
||||
GDVIRTUAL1(_update_layout, int)
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@
|
|||
void EditorMainScreen::_notification(int p_what) {
|
||||
switch (p_what) {
|
||||
case NOTIFICATION_READY: {
|
||||
set_accessibility_region(true);
|
||||
if (EDITOR_3D < buttons.size() && buttons[EDITOR_3D]->is_visible()) {
|
||||
// If the 3D editor is enabled, use this as the default.
|
||||
select(EDITOR_3D);
|
||||
|
|
@ -194,6 +195,7 @@ void EditorMainScreen::select(int p_index) {
|
|||
selected_plugin = new_editor;
|
||||
selected_plugin->make_visible(true);
|
||||
selected_plugin->selected_notify();
|
||||
set_accessibility_name(selected_plugin->get_plugin_name());
|
||||
|
||||
EditorData &editor_data = EditorNode::get_editor_data();
|
||||
int plugin_count = editor_data.get_editor_plugin_count();
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@
|
|||
void EditorBottomPanel::_notification(int p_what) {
|
||||
switch (p_what) {
|
||||
case NOTIFICATION_READY: {
|
||||
set_accessibility_region(true);
|
||||
layout_popup = get_popup();
|
||||
} break;
|
||||
|
||||
|
|
@ -60,6 +61,9 @@ void EditorBottomPanel::_notification(int p_what) {
|
|||
void EditorBottomPanel::_on_tab_changed(int p_idx) {
|
||||
_update_center_split_offset();
|
||||
_repaint();
|
||||
if (p_idx >= 0 && p_idx < get_tab_count()) {
|
||||
set_accessibility_name(get_tab_title(p_idx));
|
||||
}
|
||||
}
|
||||
|
||||
void EditorBottomPanel::_theme_changed() {
|
||||
|
|
|
|||
|
|
@ -188,7 +188,11 @@ void Container::_notification(int p_what) {
|
|||
RID ae = get_accessibility_element();
|
||||
ERR_FAIL_COND(ae.is_null());
|
||||
|
||||
DisplayServer::get_singleton()->accessibility_update_set_role(ae, DisplayServer::AccessibilityRole::ROLE_CONTAINER);
|
||||
if (accessibility_region) {
|
||||
DisplayServer::get_singleton()->accessibility_update_set_role(ae, DisplayServer::AccessibilityRole::ROLE_REGION);
|
||||
} else {
|
||||
DisplayServer::get_singleton()->accessibility_update_set_role(ae, DisplayServer::AccessibilityRole::ROLE_CONTAINER);
|
||||
}
|
||||
} break;
|
||||
|
||||
case NOTIFICATION_RESIZED:
|
||||
|
|
@ -204,6 +208,18 @@ void Container::_notification(int p_what) {
|
|||
}
|
||||
}
|
||||
|
||||
void Container::set_accessibility_region(bool p_region) {
|
||||
ERR_MAIN_THREAD_GUARD;
|
||||
if (accessibility_region != p_region) {
|
||||
accessibility_region = p_region;
|
||||
queue_accessibility_update();
|
||||
}
|
||||
}
|
||||
|
||||
bool Container::is_accessibility_region() const {
|
||||
return accessibility_region;
|
||||
}
|
||||
|
||||
PackedStringArray Container::get_configuration_warnings() const {
|
||||
PackedStringArray warnings = Control::get_configuration_warnings();
|
||||
|
||||
|
|
@ -217,6 +233,8 @@ PackedStringArray Container::get_configuration_warnings() const {
|
|||
void Container::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("queue_sort"), &Container::queue_sort);
|
||||
ClassDB::bind_method(D_METHOD("fit_child_in_rect", "child", "rect"), &Container::fit_child_in_rect);
|
||||
ClassDB::bind_method(D_METHOD("set_accessibility_region", "region"), &Container::set_accessibility_region);
|
||||
ClassDB::bind_method(D_METHOD("is_accessibility_region"), &Container::is_accessibility_region);
|
||||
|
||||
GDVIRTUAL_BIND(_get_allowed_size_flags_horizontal);
|
||||
GDVIRTUAL_BIND(_get_allowed_size_flags_vertical);
|
||||
|
|
@ -226,6 +244,8 @@ void Container::_bind_methods() {
|
|||
|
||||
ADD_SIGNAL(MethodInfo("pre_sort_children"));
|
||||
ADD_SIGNAL(MethodInfo("sort_children"));
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "accessibility_region"), "set_accessibility_region", "is_accessibility_region");
|
||||
}
|
||||
|
||||
Container::Container() {
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ class Container : public Control {
|
|||
GDCLASS(Container, Control);
|
||||
|
||||
bool pending_sort = false;
|
||||
bool accessibility_region = false;
|
||||
void _sort_children();
|
||||
void _child_minsize_changed();
|
||||
|
||||
|
|
@ -72,5 +73,8 @@ public:
|
|||
|
||||
PackedStringArray get_configuration_warnings() const override;
|
||||
|
||||
void set_accessibility_region(bool p_region);
|
||||
bool is_accessibility_region() const;
|
||||
|
||||
Container();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -434,7 +434,11 @@ void ScrollContainer::_notification(int p_what) {
|
|||
RID ae = get_accessibility_element();
|
||||
ERR_FAIL_COND(ae.is_null());
|
||||
|
||||
DisplayServer::get_singleton()->accessibility_update_set_role(ae, DisplayServer::AccessibilityRole::ROLE_SCROLL_VIEW);
|
||||
if (is_accessibility_region()) {
|
||||
DisplayServer::get_singleton()->accessibility_update_set_role(ae, DisplayServer::AccessibilityRole::ROLE_REGION);
|
||||
} else {
|
||||
DisplayServer::get_singleton()->accessibility_update_set_role(ae, DisplayServer::AccessibilityRole::ROLE_SCROLL_VIEW);
|
||||
}
|
||||
|
||||
DisplayServer::get_singleton()->accessibility_update_add_action(ae, DisplayServer::AccessibilityAction::ACTION_SCROLL_DOWN, callable_mp(this, &ScrollContainer::_accessibility_action_scroll_down));
|
||||
DisplayServer::get_singleton()->accessibility_update_add_action(ae, DisplayServer::AccessibilityAction::ACTION_SCROLL_LEFT, callable_mp(this, &ScrollContainer::_accessibility_action_scroll_left));
|
||||
|
|
|
|||
|
|
@ -565,6 +565,7 @@ void TabContainer::_on_tab_hovered(int p_tab) {
|
|||
void TabContainer::_on_tab_changed(int p_tab) {
|
||||
callable_mp(this, &TabContainer::_repaint).call_deferred();
|
||||
queue_redraw();
|
||||
queue_accessibility_update();
|
||||
|
||||
emit_signal(SNAME("tab_changed"), p_tab);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1706,6 +1706,7 @@ void DisplayServer::_bind_methods() {
|
|||
BIND_ENUM_CONSTANT(ROLE_TITLE_BAR);
|
||||
BIND_ENUM_CONSTANT(ROLE_DIALOG);
|
||||
BIND_ENUM_CONSTANT(ROLE_TOOLTIP);
|
||||
BIND_ENUM_CONSTANT(ROLE_REGION);
|
||||
|
||||
BIND_ENUM_CONSTANT(POPUP_MENU);
|
||||
BIND_ENUM_CONSTANT(POPUP_LIST);
|
||||
|
|
|
|||
|
|
@ -606,6 +606,7 @@ public:
|
|||
ROLE_TITLE_BAR,
|
||||
ROLE_DIALOG,
|
||||
ROLE_TOOLTIP,
|
||||
ROLE_REGION,
|
||||
};
|
||||
|
||||
enum AccessibilityPopupType {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue