3ade83cd1b
When no name and extra info is set, it would still add a space. is_empty() would never be true. The space character would be set as label and screen readers are prompted to read it with various output. Fixed by stripping spaces.
1794 lines
73 KiB
C++
1794 lines
73 KiB
C++
/**************************************************************************/
|
|
/* accessibility_server_accesskit.cpp */
|
|
/**************************************************************************/
|
|
/* This file is part of: */
|
|
/* GODOT ENGINE */
|
|
/* https://godotengine.org */
|
|
/**************************************************************************/
|
|
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
|
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
|
/* */
|
|
/* Permission is hereby granted, free of charge, to any person obtaining */
|
|
/* a copy of this software and associated documentation files (the */
|
|
/* "Software"), to deal in the Software without restriction, including */
|
|
/* without limitation the rights to use, copy, modify, merge, publish, */
|
|
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
|
/* permit persons to whom the Software is furnished to do so, subject to */
|
|
/* the following conditions: */
|
|
/* */
|
|
/* The above copyright notice and this permission notice shall be */
|
|
/* included in all copies or substantial portions of the Software. */
|
|
/* */
|
|
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
|
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
|
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
|
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
|
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
|
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
|
/**************************************************************************/
|
|
|
|
#ifdef ACCESSKIT_ENABLED
|
|
|
|
#include "accessibility_server_accesskit.h"
|
|
|
|
#include "servers/text/text_server.h"
|
|
|
|
_FORCE_INLINE_ accesskit_role AccessibilityServerAccessKit::_accessibility_role(AccessibilityServerEnums::AccessibilityRole p_role) const {
|
|
if (role_map.has(p_role)) {
|
|
return role_map[p_role];
|
|
}
|
|
return ACCESSKIT_ROLE_UNKNOWN;
|
|
}
|
|
|
|
_FORCE_INLINE_ accesskit_action AccessibilityServerAccessKit::_accessibility_action(AccessibilityServerEnums::AccessibilityAction p_action) const {
|
|
if (action_map.has(p_action)) {
|
|
return action_map[p_action];
|
|
}
|
|
return ACCESSKIT_ACTION_CLICK;
|
|
}
|
|
|
|
bool AccessibilityServerAccessKit::window_create(DisplayServerEnums::WindowID p_window_id, void *p_handle) {
|
|
ERR_FAIL_COND_V(windows.has(p_window_id), false);
|
|
|
|
WindowData &wd = windows[p_window_id];
|
|
|
|
AccessibilityElement *ae = memnew(AccessibilityElement);
|
|
ae->role = ACCESSKIT_ROLE_WINDOW;
|
|
ae->window_id = p_window_id;
|
|
wd.root_id = rid_owner.make_rid(ae);
|
|
|
|
#ifdef WINDOWS_ENABLED
|
|
wd.adapter = accesskit_windows_subclassing_adapter_new(static_cast<HWND>(p_handle), &_accessibility_initial_tree_update_callback, (void *)(size_t)p_window_id, &_accessibility_action_callback, (void *)(size_t)p_window_id);
|
|
#endif
|
|
#ifdef MACOS_ENABLED
|
|
wd.adapter = accesskit_macos_subclassing_adapter_for_window(p_handle, &_accessibility_initial_tree_update_callback, (void *)(size_t)p_window_id, &_accessibility_action_callback, (void *)(size_t)p_window_id);
|
|
#endif
|
|
#ifdef LINUXBSD_ENABLED
|
|
wd.adapter = accesskit_unix_adapter_new(&_accessibility_initial_tree_update_callback, (void *)(size_t)p_window_id, &_accessibility_action_callback, (void *)(size_t)p_window_id, &_accessibility_deactivation_callback, (void *)(size_t)p_window_id);
|
|
#endif
|
|
print_verbose(vformat("Accessibility: window %d adapter created.", p_window_id));
|
|
|
|
if (wd.adapter == nullptr) {
|
|
memdelete(ae);
|
|
rid_owner.free(wd.root_id);
|
|
windows.erase(p_window_id);
|
|
|
|
return false;
|
|
} else {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::window_destroy(DisplayServerEnums::WindowID p_window_id) {
|
|
WindowData *wd = windows.getptr(p_window_id);
|
|
ERR_FAIL_NULL(wd);
|
|
|
|
print_verbose(vformat("Accessibility: window %d adapter destroyed.", p_window_id));
|
|
|
|
#ifdef WINDOWS_ENABLED
|
|
accesskit_windows_subclassing_adapter_free(wd->adapter);
|
|
#endif
|
|
#ifdef MACOS_ENABLED
|
|
accesskit_macos_subclassing_adapter_free(wd->adapter);
|
|
#endif
|
|
#ifdef LINUXBSD_ENABLED
|
|
accesskit_unix_adapter_free(wd->adapter);
|
|
#endif
|
|
free_element(wd->root_id);
|
|
|
|
windows.erase(p_window_id);
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::_accessibility_deactivation_callback(void *p_user_data) {
|
|
DisplayServerEnums::WindowID window_id = (DisplayServerEnums::WindowID)(size_t)p_user_data;
|
|
WindowData *wd = static_cast<AccessibilityServerAccessKit *>(get_singleton())->windows.getptr(window_id);
|
|
ERR_FAIL_NULL(wd);
|
|
|
|
print_verbose(vformat("Accessibility: window %d adapter deactivated.", window_id));
|
|
|
|
if (static_cast<AccessibilityServerAccessKit *>(get_singleton())->focus.is_valid()) {
|
|
AccessibilityElement *ae = static_cast<AccessibilityServerAccessKit *>(get_singleton())->rid_owner.get_or_null(static_cast<AccessibilityServerAccessKit *>(get_singleton())->focus);
|
|
if (ae && ae->window_id == window_id) {
|
|
static_cast<AccessibilityServerAccessKit *>(get_singleton())->focus = RID();
|
|
}
|
|
}
|
|
if (wd->deactivate.is_valid()) {
|
|
wd->deactivate.call_deferred(); // Should be called on main thread only.
|
|
}
|
|
|
|
wd->activated = false;
|
|
wd->update.clear();
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::_accessibility_action_callback(struct accesskit_action_request *p_request, void *p_user_data) {
|
|
DisplayServerEnums::WindowID window_id = (DisplayServerEnums::WindowID)(size_t)p_user_data;
|
|
ERR_FAIL_COND(!static_cast<AccessibilityServerAccessKit *>(get_singleton())->windows.has(window_id));
|
|
|
|
RID rid = RID::from_uint64(p_request->target_node);
|
|
AccessibilityElement *ae = static_cast<AccessibilityServerAccessKit *>(get_singleton())->rid_owner.get_or_null(rid);
|
|
ERR_FAIL_NULL(ae);
|
|
|
|
Variant rq_data;
|
|
if (!ae->actions.has(p_request->action) && ae->role == ACCESSKIT_ROLE_TEXT_RUN && p_request->action == ACCESSKIT_ACTION_SCROLL_INTO_VIEW) {
|
|
AccessibilityElement *root_ae = static_cast<AccessibilityServerAccessKit *>(get_singleton())->rid_owner.get_or_null(ae->parent);
|
|
ERR_FAIL_NULL(root_ae);
|
|
ae = root_ae;
|
|
rq_data = ae->run;
|
|
}
|
|
|
|
if (ae->actions.has(p_request->action)) {
|
|
Callable &cb = ae->actions[p_request->action];
|
|
if (cb.is_valid()) {
|
|
if (p_request->data.has_value) {
|
|
switch (p_request->data.value.tag) {
|
|
case ACCESSKIT_ACTION_DATA_CUSTOM_ACTION: {
|
|
rq_data = p_request->data.value.custom_action;
|
|
} break;
|
|
case ACCESSKIT_ACTION_DATA_VALUE: {
|
|
rq_data = String::utf8(p_request->data.value.value);
|
|
} break;
|
|
case ACCESSKIT_ACTION_DATA_NUMERIC_VALUE: {
|
|
rq_data = p_request->data.value.numeric_value;
|
|
} break;
|
|
case ACCESSKIT_ACTION_DATA_SCROLL_HINT: {
|
|
switch (p_request->data.value.scroll_hint) {
|
|
case ACCESSKIT_SCROLL_HINT_TOP_LEFT: {
|
|
rq_data = AccessibilityServerEnums::SCROLL_HINT_TOP_LEFT;
|
|
} break;
|
|
case ACCESSKIT_SCROLL_HINT_BOTTOM_RIGHT: {
|
|
rq_data = AccessibilityServerEnums::SCROLL_HINT_BOTTOM_RIGHT;
|
|
} break;
|
|
case ACCESSKIT_SCROLL_HINT_TOP_EDGE: {
|
|
rq_data = AccessibilityServerEnums::SCROLL_HINT_TOP_EDGE;
|
|
} break;
|
|
case ACCESSKIT_SCROLL_HINT_BOTTOM_EDGE: {
|
|
rq_data = AccessibilityServerEnums::SCROLL_HINT_BOTTOM_EDGE;
|
|
} break;
|
|
case ACCESSKIT_SCROLL_HINT_LEFT_EDGE: {
|
|
rq_data = AccessibilityServerEnums::SCROLL_HINT_LEFT_EDGE;
|
|
} break;
|
|
case ACCESSKIT_SCROLL_HINT_RIGHT_EDGE: {
|
|
rq_data = AccessibilityServerEnums::SCROLL_HINT_RIGHT_EDGE;
|
|
} break;
|
|
default:
|
|
break;
|
|
}
|
|
} break;
|
|
case ACCESSKIT_ACTION_DATA_SCROLL_UNIT: {
|
|
if (p_request->data.value.scroll_unit == ACCESSKIT_SCROLL_UNIT_ITEM) {
|
|
rq_data = AccessibilityServerEnums::SCROLL_UNIT_ITEM;
|
|
} else if (p_request->data.value.scroll_unit == ACCESSKIT_SCROLL_UNIT_PAGE) {
|
|
rq_data = AccessibilityServerEnums::SCROLL_UNIT_PAGE;
|
|
}
|
|
} break;
|
|
case ACCESSKIT_ACTION_DATA_SCROLL_TO_POINT: {
|
|
rq_data = Point2(p_request->data.value.scroll_to_point.x, p_request->data.value.scroll_to_point.y);
|
|
} break;
|
|
case ACCESSKIT_ACTION_DATA_SET_SCROLL_OFFSET: {
|
|
rq_data = Point2(p_request->data.value.set_scroll_offset.x, p_request->data.value.set_scroll_offset.y);
|
|
} break;
|
|
case ACCESSKIT_ACTION_DATA_SET_TEXT_SELECTION: {
|
|
Dictionary sel;
|
|
|
|
RID start_rid = RID::from_uint64(p_request->data.value.set_text_selection.anchor.node);
|
|
AccessibilityElement *start_ae = static_cast<AccessibilityServerAccessKit *>(get_singleton())->rid_owner.get_or_null(start_rid);
|
|
ERR_FAIL_NULL(start_ae);
|
|
|
|
RID end_rid = RID::from_uint64(p_request->data.value.set_text_selection.focus.node);
|
|
AccessibilityElement *end_ae = static_cast<AccessibilityServerAccessKit *>(get_singleton())->rid_owner.get_or_null(end_rid);
|
|
ERR_FAIL_NULL(end_ae);
|
|
|
|
sel["start_element"] = start_ae->parent;
|
|
sel["start_char"] = (int64_t)p_request->data.value.set_text_selection.anchor.character_index + start_ae->run.x;
|
|
sel["end_element"] = end_ae->parent;
|
|
sel["end_char"] = (int64_t)p_request->data.value.set_text_selection.focus.character_index + end_ae->run.x;
|
|
rq_data = sel;
|
|
} break;
|
|
}
|
|
}
|
|
|
|
cb.call_deferred(rq_data);
|
|
}
|
|
}
|
|
}
|
|
|
|
accesskit_tree_update *AccessibilityServerAccessKit::_accessibility_initial_tree_update_callback(void *p_user_data) {
|
|
DisplayServerEnums::WindowID window_id = (DisplayServerEnums::WindowID)(size_t)p_user_data;
|
|
WindowData *wd = static_cast<AccessibilityServerAccessKit *>(get_singleton())->windows.getptr(window_id);
|
|
ERR_FAIL_NULL_V(wd, nullptr);
|
|
|
|
accesskit_node *win_node = accesskit_node_new(ACCESSKIT_ROLE_WINDOW);
|
|
accesskit_node_set_label(win_node, "Godot Engine");
|
|
accesskit_node_set_busy(win_node);
|
|
|
|
accesskit_node_id win_id = (accesskit_node_id)wd->root_id.get_id();
|
|
|
|
accesskit_tree_update *tree_update = accesskit_tree_update_with_capacity_and_focus(1, win_id);
|
|
|
|
accesskit_tree_update_set_tree(tree_update, accesskit_tree_new(win_id));
|
|
accesskit_tree_update_push_node(tree_update, win_id, win_node);
|
|
|
|
print_verbose(vformat("Accessibility: window %d adapter activated.", window_id));
|
|
|
|
if (wd->activate.is_valid()) {
|
|
wd->activate.call_deferred(); // Should be called on main thread only.
|
|
}
|
|
wd->activated = true;
|
|
|
|
return tree_update;
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::set_window_callbacks(DisplayServerEnums::WindowID p_window_id, const Callable &p_activate_callable, const Callable &p_deativate_callable) {
|
|
WindowData *wd = static_cast<AccessibilityServerAccessKit *>(get_singleton())->windows.getptr(p_window_id);
|
|
ERR_FAIL_NULL(wd);
|
|
|
|
wd->activate = p_activate_callable;
|
|
wd->deactivate = p_deativate_callable;
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::window_activation_completed(DisplayServerEnums::WindowID p_window_id) {
|
|
WindowData *wd = static_cast<AccessibilityServerAccessKit *>(get_singleton())->windows.getptr(p_window_id);
|
|
if (!wd) {
|
|
return;
|
|
}
|
|
|
|
print_verbose(vformat("Accessibility: window %d adapter initial update completed.", p_window_id));
|
|
|
|
wd->initial_update_completed = true;
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::window_deactivation_completed(DisplayServerEnums::WindowID p_window_id) {
|
|
WindowData *wd = static_cast<AccessibilityServerAccessKit *>(get_singleton())->windows.getptr(p_window_id);
|
|
if (!wd) {
|
|
return;
|
|
}
|
|
|
|
print_verbose(vformat("Accessibility: window %d adapter deactivation completed.", p_window_id));
|
|
|
|
#ifdef DEV_ENABLED
|
|
LocalVector<RID> to_delete;
|
|
for (const RID &rid : rid_owner.get_owned_list()) {
|
|
AccessibilityElement *ae = rid_owner.get_or_null(rid);
|
|
if (rid != wd->root_id && ae && ae->window_id == p_window_id) {
|
|
ERR_PRINT(vformat("Accessibility/BUG: Accessibility element %d was not deleted on window %d adapter deactivation.", rid.get_id(), p_window_id));
|
|
to_delete.push_back(rid);
|
|
}
|
|
}
|
|
for (const RID &rid : to_delete) {
|
|
_free_recursive(wd, rid);
|
|
}
|
|
#endif
|
|
wd->initial_update_completed = false;
|
|
}
|
|
|
|
RID AccessibilityServerAccessKit::create_element(DisplayServerEnums::WindowID p_window_id, AccessibilityServerEnums::AccessibilityRole p_role) {
|
|
AccessibilityElement *ae = memnew(AccessibilityElement);
|
|
ae->role = _accessibility_role(p_role);
|
|
ae->window_id = p_window_id;
|
|
RID rid = rid_owner.make_rid(ae);
|
|
|
|
return rid;
|
|
}
|
|
|
|
RID AccessibilityServerAccessKit::create_sub_element(const RID &p_parent_rid, AccessibilityServerEnums::AccessibilityRole p_role, int p_insert_pos) {
|
|
AccessibilityElement *parent_ae = rid_owner.get_or_null(p_parent_rid);
|
|
ERR_FAIL_NULL_V(parent_ae, RID());
|
|
|
|
WindowData *wd = windows.getptr(parent_ae->window_id);
|
|
ERR_FAIL_NULL_V(wd, RID());
|
|
|
|
AccessibilityElement *ae = memnew(AccessibilityElement);
|
|
ae->role = _accessibility_role(p_role);
|
|
ae->window_id = parent_ae->window_id;
|
|
ae->parent = p_parent_rid;
|
|
ae->node = accesskit_node_new(ae->role);
|
|
RID rid = rid_owner.make_rid(ae);
|
|
if (p_insert_pos == -1) {
|
|
parent_ae->children.push_back(rid);
|
|
} else {
|
|
parent_ae->children.insert(p_insert_pos, rid);
|
|
}
|
|
wd->update.insert(rid);
|
|
|
|
return rid;
|
|
}
|
|
|
|
RID AccessibilityServerAccessKit::create_sub_text_edit_elements(const RID &p_parent_rid, const RID &p_shaped_text, float p_min_height, int p_insert_pos, bool p_is_last_line) {
|
|
AccessibilityElement *parent_ae = rid_owner.get_or_null(p_parent_rid);
|
|
ERR_FAIL_NULL_V(parent_ae, RID());
|
|
|
|
WindowData *wd = windows.getptr(parent_ae->window_id);
|
|
ERR_FAIL_NULL_V(wd, RID());
|
|
|
|
AccessibilityElement *root_ae = memnew(AccessibilityElement);
|
|
root_ae->role = ACCESSKIT_ROLE_GENERIC_CONTAINER;
|
|
root_ae->window_id = parent_ae->window_id;
|
|
root_ae->parent = p_parent_rid;
|
|
root_ae->node = accesskit_node_new(root_ae->role);
|
|
RID root_rid = rid_owner.make_rid(root_ae);
|
|
if (p_insert_pos == -1) {
|
|
parent_ae->children.push_back(root_rid);
|
|
} else {
|
|
parent_ae->children.insert(p_insert_pos, root_rid);
|
|
}
|
|
wd->update.insert(root_rid);
|
|
|
|
float text_width = 0;
|
|
float text_height = p_min_height;
|
|
Vector<int32_t> words;
|
|
int64_t run_count = 0; // Note: runs in visual order.
|
|
const Glyph *gl = nullptr;
|
|
float run_off_x = 0.0;
|
|
Vector2i full_range;
|
|
|
|
if (p_shaped_text.is_valid()) {
|
|
text_width = TS->shaped_text_get_size(p_shaped_text).x;
|
|
text_height = MAX(text_height, TS->shaped_text_get_size(p_shaped_text).y);
|
|
words = TS->shaped_text_get_word_breaks(p_shaped_text);
|
|
run_count = TS->shaped_get_run_count(p_shaped_text);
|
|
gl = TS->shaped_text_get_glyphs(p_shaped_text);
|
|
full_range = TS->shaped_text_get_range(p_shaped_text);
|
|
}
|
|
|
|
accesskit_rect root_rect;
|
|
root_rect.x0 = 0;
|
|
root_rect.y0 = 0;
|
|
root_rect.x1 = text_width;
|
|
root_rect.y1 = MAX(p_min_height, text_height);
|
|
accesskit_node_set_bounds(root_ae->node, root_rect);
|
|
|
|
// Create text element for each run.
|
|
Vector<AccessibilityElement *> text_elements;
|
|
for (int64_t i = 0; i < run_count; i++) {
|
|
const Vector2i range = TS->shaped_get_run_range(p_shaped_text, i);
|
|
const Vector2i gl_range = TS->shaped_get_run_glyph_range(p_shaped_text, i);
|
|
String run_t = TS->shaped_get_run_text(p_shaped_text, i);
|
|
TextServer::Direction dir = TS->shaped_get_run_direction(p_shaped_text, i);
|
|
|
|
if (run_t.is_empty()) {
|
|
continue;
|
|
}
|
|
|
|
// Split long runs in to < 254 char subruns due to AccessKit limitation.
|
|
Vector<Vector2i> subrun_ranges;
|
|
Vector<Vector<uint8_t>> subrun_word_starts;
|
|
{
|
|
Vector2i cur_range = range;
|
|
bool slice = false;
|
|
do {
|
|
// Word starts.
|
|
Vector<uint8_t> word_starts;
|
|
word_starts.push_back(0);
|
|
|
|
slice = false;
|
|
for (int j = 0; j < words.size(); j += 2) {
|
|
if (words[j] <= cur_range.x) {
|
|
continue;
|
|
}
|
|
if (words[j] >= cur_range.y) {
|
|
break;
|
|
}
|
|
int32_t wstart = words[j] - cur_range.x;
|
|
int32_t wend = words[j + 1] - cur_range.x;
|
|
if (wend >= 254) {
|
|
cur_range.y = words[j];
|
|
slice = true;
|
|
break;
|
|
}
|
|
word_starts.push_back(wstart);
|
|
}
|
|
subrun_ranges.push_back(cur_range);
|
|
subrun_word_starts.push_back(word_starts);
|
|
|
|
if (slice) {
|
|
cur_range.x = cur_range.y;
|
|
cur_range.y = range.y;
|
|
}
|
|
} while (slice);
|
|
}
|
|
|
|
// Process subruns.
|
|
int start, end, delta;
|
|
if (dir == TextServer::DIRECTION_LTR) {
|
|
start = 0;
|
|
end = subrun_ranges.size();
|
|
delta = +1;
|
|
} else {
|
|
start = subrun_ranges.size() - 1;
|
|
end = -1;
|
|
delta = -1;
|
|
}
|
|
for (int rr = start; rr != end; rr += delta) {
|
|
// Word starts.
|
|
const Vector<uint8_t> &word_starts = subrun_word_starts[rr];
|
|
const Vector2i &cur_range = subrun_ranges[rr];
|
|
|
|
AccessibilityElement *ae = memnew(AccessibilityElement);
|
|
ae->role = ACCESSKIT_ROLE_TEXT_RUN;
|
|
ae->window_id = parent_ae->window_id;
|
|
ae->parent = root_rid;
|
|
ae->run = Vector3i(cur_range.x, cur_range.y, i);
|
|
ae->node = accesskit_node_new(ae->role);
|
|
|
|
text_elements.push_back(ae);
|
|
|
|
String sub_t = run_t.substr(cur_range.x - range.x, cur_range.y - cur_range.x);
|
|
if (sub_t.is_empty()) {
|
|
continue;
|
|
}
|
|
|
|
// UTF-8 text and char lengths.
|
|
Vector<uint8_t> char_lengths;
|
|
CharString text = sub_t.utf8(&char_lengths);
|
|
|
|
ae->value = sub_t;
|
|
accesskit_node_set_value(ae->node, text.ptr());
|
|
accesskit_node_set_character_lengths(ae->node, char_lengths.size(), char_lengths.ptr());
|
|
|
|
accesskit_node_set_word_starts(ae->node, word_starts.size(), word_starts.ptr());
|
|
|
|
// Char widths and positions.
|
|
Vector<float> char_positions;
|
|
Vector<float> char_widths;
|
|
|
|
char_positions.resize_initialized(sub_t.length());
|
|
float *positions_ptr = char_positions.ptrw();
|
|
|
|
char_widths.resize_initialized(sub_t.length());
|
|
float *widths_ptr = char_widths.ptrw();
|
|
|
|
float size_x = 0.0;
|
|
for (int j = gl_range.x; j <= gl_range.y; j += gl[j].count) {
|
|
if (gl[j].start >= ae->run.y || gl[j].start < ae->run.x) {
|
|
continue;
|
|
}
|
|
|
|
float advance = 0.0; // Graphame advance.
|
|
for (int k = 0; k < gl[j].count; k++) {
|
|
advance += gl[j + k].advance;
|
|
}
|
|
int chars = gl[j].end - gl[j].start;
|
|
float adv_per_char = advance / (float)chars;
|
|
|
|
for (int k = 0; k < chars; k++) {
|
|
int index = gl[j].start + k - ae->run.x;
|
|
ERR_CONTINUE(index < 0 || index >= sub_t.length());
|
|
positions_ptr[index] = size_x + adv_per_char * k;
|
|
widths_ptr[index] = adv_per_char;
|
|
}
|
|
size_x += advance * gl[j].repeat;
|
|
}
|
|
positions_ptr[sub_t.length() - 1] = size_x;
|
|
widths_ptr[sub_t.length() - 1] = 1.0;
|
|
|
|
accesskit_node_set_character_positions(ae->node, char_positions.size(), char_positions.ptr());
|
|
accesskit_node_set_character_widths(ae->node, char_widths.size(), char_widths.ptr());
|
|
|
|
RID font_rid = TS->shaped_get_run_font_rid(p_shaped_text, i);
|
|
if (font_rid != RID()) {
|
|
CharString font_name = TS->font_get_name(font_rid).utf8();
|
|
if (font_name.length() > 0) {
|
|
accesskit_node_set_font_family(ae->node, font_name.ptr());
|
|
}
|
|
if (TS->font_get_style(font_rid).has_flag(TextServer::FONT_ITALIC)) {
|
|
accesskit_node_set_italic(ae->node);
|
|
}
|
|
accesskit_node_set_font_weight(ae->node, TS->font_get_weight(font_rid));
|
|
}
|
|
accesskit_node_set_font_size(ae->node, TS->shaped_get_run_font_size(p_shaped_text, i));
|
|
CharString language = TS->shaped_get_run_language(p_shaped_text, i).utf8();
|
|
if (language.length() > 0) {
|
|
accesskit_node_set_language(ae->node, language.ptr());
|
|
}
|
|
accesskit_node_set_text_direction(ae->node, ACCESSKIT_TEXT_DIRECTION_LEFT_TO_RIGHT);
|
|
|
|
accesskit_rect rect;
|
|
rect.x0 = run_off_x;
|
|
rect.y0 = 0;
|
|
rect.x1 = run_off_x + size_x;
|
|
rect.y1 = text_height;
|
|
accesskit_node_set_bounds(ae->node, rect);
|
|
accesskit_node_add_action(ae->node, ACCESSKIT_ACTION_SCROLL_INTO_VIEW);
|
|
|
|
run_off_x += size_x;
|
|
}
|
|
}
|
|
if (!p_is_last_line || text_elements.is_empty()) {
|
|
// Add "\n" at the end.
|
|
AccessibilityElement *ae = memnew(AccessibilityElement);
|
|
ae->role = ACCESSKIT_ROLE_TEXT_RUN;
|
|
ae->window_id = parent_ae->window_id;
|
|
ae->parent = root_rid;
|
|
ae->run = Vector3i(full_range.y, full_range.y, run_count);
|
|
ae->node = accesskit_node_new(ae->role);
|
|
|
|
text_elements.push_back(ae);
|
|
|
|
ae->value = String();
|
|
if (!p_is_last_line) {
|
|
accesskit_node_set_value(ae->node, "\n");
|
|
|
|
Vector<uint8_t> char_lengths;
|
|
Vector<float> char_positions;
|
|
Vector<float> char_widths;
|
|
char_lengths.push_back(1);
|
|
char_positions.push_back(0.0);
|
|
char_widths.push_back(1.0);
|
|
|
|
accesskit_node_set_character_lengths(ae->node, char_lengths.size(), char_lengths.ptr());
|
|
accesskit_node_set_character_positions(ae->node, char_positions.size(), char_positions.ptr());
|
|
accesskit_node_set_character_widths(ae->node, char_widths.size(), char_widths.ptr());
|
|
} else {
|
|
accesskit_node_set_value(ae->node, "");
|
|
}
|
|
accesskit_node_set_text_direction(ae->node, ACCESSKIT_TEXT_DIRECTION_LEFT_TO_RIGHT);
|
|
|
|
accesskit_rect rect;
|
|
rect.x0 = run_off_x;
|
|
rect.y0 = 0;
|
|
rect.x1 = run_off_x + 1;
|
|
rect.y1 = text_height;
|
|
accesskit_node_set_bounds(ae->node, rect);
|
|
}
|
|
|
|
// Sort runs in logical order.
|
|
struct RunCompare {
|
|
_FORCE_INLINE_ bool operator()(const AccessibilityElement *l, const AccessibilityElement *r) const {
|
|
return l->run.x < r->run.x;
|
|
}
|
|
};
|
|
text_elements.sort_custom<RunCompare>();
|
|
for (int i = 0; i < text_elements.size(); i++) {
|
|
RID rid = rid_owner.make_rid(text_elements[i]);
|
|
root_ae->children.push_back(rid);
|
|
wd->update.insert(rid);
|
|
|
|
// Link adjacent TextRuns on the same line.
|
|
if (i > 0) {
|
|
RID prev_rid = root_ae->children[i - 1];
|
|
AccessibilityElement *prev_ae = rid_owner.get_or_null(prev_rid);
|
|
accesskit_node_set_previous_on_line(text_elements[i]->node, (accesskit_node_id)prev_rid.get_id());
|
|
accesskit_node_set_next_on_line(prev_ae->node, (accesskit_node_id)rid.get_id());
|
|
}
|
|
}
|
|
|
|
return root_rid;
|
|
}
|
|
|
|
bool AccessibilityServerAccessKit::has_element(const RID &p_id) const {
|
|
return rid_owner.owns(p_id);
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::_free_recursive(WindowData *p_wd, const RID &p_id) {
|
|
if (p_wd && p_wd->update.has(p_id)) {
|
|
p_wd->update.erase(p_id);
|
|
}
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
for (const RID &rid : ae->children) {
|
|
_free_recursive(p_wd, rid);
|
|
}
|
|
if (ae->node) {
|
|
accesskit_node_free(ae->node);
|
|
}
|
|
memdelete(ae);
|
|
rid_owner.free(p_id);
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::free_element(const RID &p_id) {
|
|
ERR_FAIL_COND_MSG(in_accessibility_update, "Element can't be removed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
if (ae) {
|
|
WindowData *wd = windows.getptr(ae->window_id);
|
|
AccessibilityElement *parent_ae = rid_owner.get_or_null(ae->parent);
|
|
if (parent_ae) {
|
|
parent_ae->children.erase(p_id);
|
|
}
|
|
_free_recursive(wd, p_id);
|
|
}
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::element_set_meta(const RID &p_id, const Variant &p_meta) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
ae->meta = p_meta;
|
|
}
|
|
|
|
Variant AccessibilityServerAccessKit::element_get_meta(const RID &p_id) const {
|
|
const AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL_V(ae, Variant());
|
|
return ae->meta;
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_set_focus(const RID &p_id) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
if (p_id.is_valid() && rid_owner.owns(p_id)) {
|
|
focus = p_id;
|
|
} else {
|
|
focus = RID();
|
|
}
|
|
}
|
|
|
|
RID AccessibilityServerAccessKit::get_window_root(DisplayServerEnums::WindowID p_window_id) const {
|
|
const WindowData *wd = windows.getptr(p_window_id);
|
|
ERR_FAIL_NULL_V(wd, RID());
|
|
|
|
return wd->root_id;
|
|
}
|
|
|
|
accesskit_tree_update *AccessibilityServerAccessKit::_accessibility_build_tree_update(void *p_user_data) {
|
|
DisplayServerEnums::WindowID window_id = (DisplayServerEnums::WindowID)(size_t)p_user_data;
|
|
|
|
ERR_FAIL_COND_V(!static_cast<AccessibilityServerAccessKit *>(get_singleton())->windows.has(window_id), nullptr);
|
|
WindowData &wd = static_cast<AccessibilityServerAccessKit *>(get_singleton())->windows[window_id];
|
|
|
|
static_cast<AccessibilityServerAccessKit *>(get_singleton())->in_accessibility_update = true;
|
|
if (static_cast<AccessibilityServerAccessKit *>(get_singleton())->update_cb.is_valid()) {
|
|
static_cast<AccessibilityServerAccessKit *>(get_singleton())->update_cb.call(window_id);
|
|
}
|
|
static_cast<AccessibilityServerAccessKit *>(get_singleton())->in_accessibility_update = false;
|
|
|
|
AccessibilityElement *focus_ae = static_cast<AccessibilityServerAccessKit *>(get_singleton())->rid_owner.get_or_null(static_cast<AccessibilityServerAccessKit *>(get_singleton())->focus);
|
|
uint32_t update_size = wd.update.size();
|
|
|
|
accesskit_node_id ac_focus = (accesskit_node_id)wd.root_id.get_id();
|
|
if (focus_ae && focus_ae->window_id == window_id) {
|
|
ac_focus = (accesskit_node_id) static_cast<AccessibilityServerAccessKit *>(get_singleton())->focus.get_id();
|
|
}
|
|
accesskit_tree_update *tree_update = (update_size > 0) ? accesskit_tree_update_with_capacity_and_focus(update_size, ac_focus) : accesskit_tree_update_with_focus(ac_focus);
|
|
for (const RID &rid : wd.update) {
|
|
AccessibilityElement *ae = static_cast<AccessibilityServerAccessKit *>(get_singleton())->rid_owner.get_or_null(rid);
|
|
if (ae && ae->node) {
|
|
for (const RID &child_rid : ae->children) {
|
|
accesskit_node_push_child(ae->node, (accesskit_node_id)child_rid.get_id());
|
|
}
|
|
accesskit_tree_update_push_node(tree_update, (accesskit_node_id)rid.get_id(), ae->node);
|
|
ae->node = nullptr;
|
|
}
|
|
}
|
|
wd.update.clear();
|
|
|
|
return tree_update;
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_if_active(const Callable &p_callable) {
|
|
ERR_FAIL_COND(!p_callable.is_valid());
|
|
update_cb = p_callable;
|
|
for (KeyValue<DisplayServerEnums::WindowID, WindowData> &window : windows) {
|
|
#ifdef WINDOWS_ENABLED
|
|
accesskit_windows_queued_events *events = accesskit_windows_subclassing_adapter_update_if_active(window.value.adapter, _accessibility_build_tree_update, (void *)(size_t)window.key);
|
|
if (events) {
|
|
accesskit_windows_queued_events_raise(events);
|
|
}
|
|
#endif
|
|
#ifdef MACOS_ENABLED
|
|
accesskit_macos_queued_events *events = accesskit_macos_subclassing_adapter_update_if_active(window.value.adapter, _accessibility_build_tree_update, (void *)(size_t)window.key);
|
|
if (events) {
|
|
accesskit_macos_queued_events_raise(events);
|
|
}
|
|
#endif
|
|
#ifdef LINUXBSD_ENABLED
|
|
accesskit_unix_adapter_update_if_active(window.value.adapter, _accessibility_build_tree_update, (void *)(size_t)window.key);
|
|
#endif
|
|
}
|
|
update_cb = Callable();
|
|
}
|
|
|
|
_FORCE_INLINE_ void AccessibilityServerAccessKit::_ensure_node(const RID &p_id, AccessibilityElement *p_ae) {
|
|
if (unlikely(!p_ae->node)) {
|
|
WindowData *wd = windows.getptr(p_ae->window_id);
|
|
ERR_FAIL_NULL(wd);
|
|
|
|
wd->update.insert(p_id);
|
|
p_ae->node = accesskit_node_new(p_ae->role);
|
|
|
|
// Re-apply stored name if any, so nodes recreated by _ensure_node
|
|
// retain their label even if the caller doesn't re-set all properties.
|
|
String full_name = (p_ae->name + " " + p_ae->name_extra_info).strip_edges();
|
|
if (!full_name.is_empty()) {
|
|
accesskit_node_set_label(p_ae->node, full_name.utf8().ptr());
|
|
}
|
|
}
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::set_window_rect(DisplayServerEnums::WindowID p_window_id, const Rect2 &p_rect_out, const Rect2 &p_rect_in) {
|
|
#ifdef LINUXBSD_ENABLED
|
|
const WindowData *wd = windows.getptr(p_window_id);
|
|
ERR_FAIL_NULL(wd);
|
|
|
|
accesskit_rect outer_bounds = { p_rect_out.position.x, p_rect_out.position.y, p_rect_out.position.x + p_rect_out.size.width, p_rect_out.position.y + p_rect_out.size.height };
|
|
accesskit_rect inner_bounds = { p_rect_in.position.x, p_rect_in.position.y, p_rect_in.position.x + p_rect_in.size.width, p_rect_in.position.y + p_rect_in.size.height };
|
|
accesskit_unix_adapter_set_root_window_bounds(wd->adapter, outer_bounds, inner_bounds);
|
|
#endif
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::set_window_focused(DisplayServerEnums::WindowID p_window_id, bool p_focused) {
|
|
const WindowData *wd = windows.getptr(p_window_id);
|
|
ERR_FAIL_NULL(wd);
|
|
|
|
#ifdef LINUXBSD_ENABLED
|
|
accesskit_unix_adapter_update_window_focus_state(wd->adapter, p_focused);
|
|
#endif
|
|
#ifdef MACOS_ENABLED
|
|
accesskit_macos_queued_events *events = accesskit_macos_subclassing_adapter_update_view_focus_state(wd->adapter, p_focused);
|
|
if (events != nullptr) {
|
|
accesskit_macos_queued_events_raise(events);
|
|
}
|
|
#endif
|
|
// Note: On Windows, the subclassing adapter takes care of this.
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_set_role(const RID &p_id, AccessibilityServerEnums::AccessibilityRole p_role) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
if (ae->role == _accessibility_role(p_role)) {
|
|
return;
|
|
}
|
|
ae->role = _accessibility_role(p_role);
|
|
_ensure_node(p_id, ae);
|
|
|
|
accesskit_node_set_role(ae->node, ae->role);
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_set_name(const RID &p_id, const String &p_name) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
_ensure_node(p_id, ae);
|
|
|
|
ae->name = p_name;
|
|
String full_name = (ae->name + " " + ae->name_extra_info).strip_edges();
|
|
if (!full_name.is_empty()) {
|
|
accesskit_node_set_label(ae->node, full_name.utf8().ptr());
|
|
} else {
|
|
accesskit_node_clear_label(ae->node);
|
|
}
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_set_braille_label(const RID &p_id, const String &p_name) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
_ensure_node(p_id, ae);
|
|
|
|
if (!p_name.is_empty()) {
|
|
accesskit_node_set_braille_label(ae->node, p_name.utf8().ptr());
|
|
} else {
|
|
accesskit_node_clear_braille_label(ae->node);
|
|
}
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_set_braille_role_description(const RID &p_id, const String &p_description) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
_ensure_node(p_id, ae);
|
|
|
|
if (!p_description.is_empty()) {
|
|
accesskit_node_set_braille_role_description(ae->node, p_description.utf8().ptr());
|
|
} else {
|
|
accesskit_node_clear_braille_role_description(ae->node);
|
|
}
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_set_extra_info(const RID &p_id, const String &p_name_extra_info) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
_ensure_node(p_id, ae);
|
|
|
|
ae->name_extra_info = p_name_extra_info;
|
|
String full_name = (ae->name + " " + ae->name_extra_info).strip_edges();
|
|
if (!full_name.is_empty()) {
|
|
accesskit_node_set_label(ae->node, full_name.utf8().ptr());
|
|
} else {
|
|
accesskit_node_clear_label(ae->node);
|
|
}
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_set_description(const RID &p_id, const String &p_description) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
_ensure_node(p_id, ae);
|
|
|
|
if (!p_description.is_empty()) {
|
|
accesskit_node_set_description(ae->node, p_description.utf8().ptr());
|
|
} else {
|
|
accesskit_node_clear_description(ae->node);
|
|
}
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_set_value(const RID &p_id, const String &p_value) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
_ensure_node(p_id, ae);
|
|
|
|
if (!p_value.is_empty()) {
|
|
Vector<uint8_t> ch_length;
|
|
ae->value = p_value;
|
|
accesskit_node_set_value(ae->node, p_value.utf8(&ch_length).ptr());
|
|
accesskit_node_set_character_lengths(ae->node, ch_length.size(), ch_length.ptr());
|
|
} else {
|
|
ae->value = String();
|
|
accesskit_node_clear_value(ae->node);
|
|
accesskit_node_clear_character_lengths(ae->node);
|
|
}
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_set_tooltip(const RID &p_id, const String &p_tooltip) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
_ensure_node(p_id, ae);
|
|
|
|
if (!p_tooltip.is_empty()) {
|
|
accesskit_node_set_tooltip(ae->node, p_tooltip.utf8().ptr());
|
|
} else {
|
|
accesskit_node_clear_tooltip(ae->node);
|
|
}
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_set_bounds(const RID &p_id, const Rect2 &p_rect) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
_ensure_node(p_id, ae);
|
|
|
|
accesskit_rect rect;
|
|
rect.x0 = p_rect.position.x;
|
|
rect.y0 = p_rect.position.y;
|
|
rect.x1 = p_rect.position.x + p_rect.size.x;
|
|
rect.y1 = p_rect.position.y + p_rect.size.y;
|
|
accesskit_node_set_bounds(ae->node, rect);
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_set_transform(const RID &p_id, const Transform2D &p_transform) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
_ensure_node(p_id, ae);
|
|
|
|
accesskit_affine transform = { p_transform.columns[0][0], p_transform.columns[0][1], p_transform.columns[1][0], p_transform.columns[1][1], p_transform.columns[2][0], p_transform.columns[2][1] };
|
|
accesskit_node_set_transform(ae->node, transform);
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_add_child(const RID &p_id, const RID &p_child_id) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
AccessibilityElement *other_ae = rid_owner.get_or_null(p_child_id);
|
|
ERR_FAIL_NULL(other_ae);
|
|
ERR_FAIL_COND(other_ae->window_id != ae->window_id);
|
|
_ensure_node(p_id, ae);
|
|
|
|
accesskit_node_push_child(ae->node, (accesskit_node_id)p_child_id.get_id());
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_add_related_controls(const RID &p_id, const RID &p_related_id) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
AccessibilityElement *other_ae = rid_owner.get_or_null(p_related_id);
|
|
ERR_FAIL_NULL(other_ae);
|
|
ERR_FAIL_COND(other_ae->window_id != ae->window_id);
|
|
_ensure_node(p_id, ae);
|
|
|
|
accesskit_node_push_controlled(ae->node, (accesskit_node_id)p_related_id.get_id());
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_add_related_details(const RID &p_id, const RID &p_related_id) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
AccessibilityElement *other_ae = rid_owner.get_or_null(p_related_id);
|
|
ERR_FAIL_NULL(other_ae);
|
|
ERR_FAIL_COND(other_ae->window_id != ae->window_id);
|
|
_ensure_node(p_id, ae);
|
|
|
|
accesskit_node_push_detail(ae->node, (accesskit_node_id)p_related_id.get_id());
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_add_related_described_by(const RID &p_id, const RID &p_related_id) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
AccessibilityElement *other_ae = rid_owner.get_or_null(p_related_id);
|
|
ERR_FAIL_NULL(other_ae);
|
|
ERR_FAIL_COND(other_ae->window_id != ae->window_id);
|
|
_ensure_node(p_id, ae);
|
|
|
|
accesskit_node_push_described_by(ae->node, (accesskit_node_id)p_related_id.get_id());
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_add_related_flow_to(const RID &p_id, const RID &p_related_id) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
AccessibilityElement *other_ae = rid_owner.get_or_null(p_related_id);
|
|
ERR_FAIL_NULL(other_ae);
|
|
ERR_FAIL_COND(other_ae->window_id != ae->window_id);
|
|
_ensure_node(p_id, ae);
|
|
|
|
accesskit_node_push_flow_to(ae->node, (accesskit_node_id)p_related_id.get_id());
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_add_related_labeled_by(const RID &p_id, const RID &p_related_id) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
AccessibilityElement *other_ae = rid_owner.get_or_null(p_related_id);
|
|
ERR_FAIL_NULL(other_ae);
|
|
ERR_FAIL_COND(other_ae->window_id != ae->window_id);
|
|
_ensure_node(p_id, ae);
|
|
|
|
accesskit_node_push_labelled_by(ae->node, (accesskit_node_id)p_related_id.get_id());
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_add_related_radio_group(const RID &p_id, const RID &p_related_id) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
AccessibilityElement *other_ae = rid_owner.get_or_null(p_related_id);
|
|
ERR_FAIL_NULL(other_ae);
|
|
ERR_FAIL_COND(other_ae->window_id != ae->window_id);
|
|
_ensure_node(p_id, ae);
|
|
|
|
accesskit_node_push_to_radio_group(ae->node, (accesskit_node_id)p_related_id.get_id());
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_set_active_descendant(const RID &p_id, const RID &p_other_id) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
AccessibilityElement *other_ae = rid_owner.get_or_null(p_other_id);
|
|
ERR_FAIL_NULL(other_ae);
|
|
ERR_FAIL_COND(other_ae->window_id != ae->window_id);
|
|
_ensure_node(p_id, ae);
|
|
|
|
accesskit_node_set_active_descendant(ae->node, (accesskit_node_id)p_other_id.get_id());
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_set_next_on_line(const RID &p_id, const RID &p_other_id) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
AccessibilityElement *other_ae = rid_owner.get_or_null(p_other_id);
|
|
ERR_FAIL_NULL(other_ae);
|
|
ERR_FAIL_COND(other_ae->window_id != ae->window_id);
|
|
_ensure_node(p_id, ae);
|
|
|
|
accesskit_node_set_next_on_line(ae->node, (accesskit_node_id)p_other_id.get_id());
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_set_previous_on_line(const RID &p_id, const RID &p_other_id) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
AccessibilityElement *other_ae = rid_owner.get_or_null(p_other_id);
|
|
ERR_FAIL_NULL(other_ae);
|
|
ERR_FAIL_COND(other_ae->window_id != ae->window_id);
|
|
_ensure_node(p_id, ae);
|
|
|
|
accesskit_node_set_previous_on_line(ae->node, (accesskit_node_id)p_other_id.get_id());
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_set_member_of(const RID &p_id, const RID &p_group_id) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
AccessibilityElement *other_ae = rid_owner.get_or_null(p_group_id);
|
|
ERR_FAIL_NULL(other_ae);
|
|
ERR_FAIL_COND(other_ae->window_id != ae->window_id);
|
|
_ensure_node(p_id, ae);
|
|
|
|
accesskit_node_set_member_of(ae->node, (accesskit_node_id)p_group_id.get_id());
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_set_in_page_link_target(const RID &p_id, const RID &p_other_id) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
AccessibilityElement *other_ae = rid_owner.get_or_null(p_other_id);
|
|
ERR_FAIL_NULL(other_ae);
|
|
ERR_FAIL_COND(other_ae->window_id != ae->window_id);
|
|
_ensure_node(p_id, ae);
|
|
|
|
accesskit_node_set_in_page_link_target(ae->node, (accesskit_node_id)p_other_id.get_id());
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_set_error_message(const RID &p_id, const RID &p_other_id) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
AccessibilityElement *other_ae = rid_owner.get_or_null(p_other_id);
|
|
ERR_FAIL_NULL(other_ae);
|
|
ERR_FAIL_COND(other_ae->window_id != ae->window_id);
|
|
_ensure_node(p_id, ae);
|
|
|
|
accesskit_node_set_error_message(ae->node, (accesskit_node_id)p_other_id.get_id());
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_set_live(const RID &p_id, AccessibilityServerEnums::AccessibilityLiveMode p_live) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
_ensure_node(p_id, ae);
|
|
|
|
switch (p_live) {
|
|
case AccessibilityServerEnums::AccessibilityLiveMode::LIVE_OFF: {
|
|
accesskit_node_set_live(ae->node, ACCESSKIT_LIVE_OFF);
|
|
} break;
|
|
case AccessibilityServerEnums::AccessibilityLiveMode::LIVE_POLITE: {
|
|
accesskit_node_set_live(ae->node, ACCESSKIT_LIVE_POLITE);
|
|
} break;
|
|
case AccessibilityServerEnums::AccessibilityLiveMode::LIVE_ASSERTIVE: {
|
|
accesskit_node_set_live(ae->node, ACCESSKIT_LIVE_ASSERTIVE);
|
|
} break;
|
|
}
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_add_action(const RID &p_id, AccessibilityServerEnums::AccessibilityAction p_action, const Callable &p_callable) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
_ensure_node(p_id, ae);
|
|
|
|
ae->actions[_accessibility_action(p_action)] = p_callable;
|
|
|
|
accesskit_node_add_action(ae->node, _accessibility_action(p_action));
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_add_custom_action(const RID &p_id, int p_action_id, const String &p_action_description) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
_ensure_node(p_id, ae);
|
|
|
|
if (!p_action_description.is_empty()) {
|
|
accesskit_custom_action *ca = accesskit_custom_action_new(p_action_id);
|
|
accesskit_custom_action_set_description(ca, p_action_description.utf8().ptr());
|
|
accesskit_node_push_custom_action(ae->node, ca);
|
|
} else {
|
|
String cs_name = vformat("Custom Action %d", p_action_id);
|
|
accesskit_custom_action *ca = accesskit_custom_action_new(p_action_id);
|
|
accesskit_custom_action_set_description(ca, cs_name.utf8().ptr());
|
|
accesskit_node_push_custom_action(ae->node, ca);
|
|
}
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_set_table_row_count(const RID &p_id, int p_count) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
_ensure_node(p_id, ae);
|
|
|
|
accesskit_node_set_row_count(ae->node, p_count);
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_set_table_column_count(const RID &p_id, int p_count) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
_ensure_node(p_id, ae);
|
|
|
|
accesskit_node_set_column_count(ae->node, p_count);
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_set_table_row_index(const RID &p_id, int p_index) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
_ensure_node(p_id, ae);
|
|
|
|
accesskit_node_set_row_index(ae->node, p_index);
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_set_table_column_index(const RID &p_id, int p_index) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
_ensure_node(p_id, ae);
|
|
|
|
accesskit_node_set_column_index(ae->node, p_index);
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_set_table_cell_position(const RID &p_id, int p_row_index, int p_column_index) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
_ensure_node(p_id, ae);
|
|
|
|
accesskit_node_set_row_index(ae->node, p_row_index);
|
|
accesskit_node_set_column_index(ae->node, p_column_index);
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_set_table_cell_span(const RID &p_id, int p_row_span, int p_column_span) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
_ensure_node(p_id, ae);
|
|
|
|
accesskit_node_set_row_span(ae->node, p_row_span);
|
|
accesskit_node_set_column_span(ae->node, p_column_span);
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_set_list_item_count(const RID &p_id, int p_size) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
_ensure_node(p_id, ae);
|
|
|
|
accesskit_node_set_size_of_set(ae->node, p_size);
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_set_list_item_index(const RID &p_id, int p_index) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
_ensure_node(p_id, ae);
|
|
|
|
accesskit_node_set_position_in_set(ae->node, p_index);
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_set_list_item_level(const RID &p_id, int p_level) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
_ensure_node(p_id, ae);
|
|
|
|
accesskit_node_set_level(ae->node, p_level);
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_set_list_item_selected(const RID &p_id, bool p_selected) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
_ensure_node(p_id, ae);
|
|
|
|
accesskit_node_set_selected(ae->node, p_selected);
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_set_list_item_expanded(const RID &p_id, bool p_expanded) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
_ensure_node(p_id, ae);
|
|
|
|
accesskit_node_set_expanded(ae->node, p_expanded);
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_set_popup_type(const RID &p_id, AccessibilityServerEnums::AccessibilityPopupType p_popup) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
_ensure_node(p_id, ae);
|
|
|
|
switch (p_popup) {
|
|
case AccessibilityServerEnums::AccessibilityPopupType::POPUP_MENU: {
|
|
accesskit_node_set_has_popup(ae->node, ACCESSKIT_HAS_POPUP_MENU);
|
|
} break;
|
|
case AccessibilityServerEnums::AccessibilityPopupType::POPUP_LIST: {
|
|
accesskit_node_set_has_popup(ae->node, ACCESSKIT_HAS_POPUP_LISTBOX);
|
|
} break;
|
|
case AccessibilityServerEnums::AccessibilityPopupType::POPUP_TREE: {
|
|
accesskit_node_set_has_popup(ae->node, ACCESSKIT_HAS_POPUP_TREE);
|
|
} break;
|
|
case AccessibilityServerEnums::AccessibilityPopupType::POPUP_DIALOG: {
|
|
accesskit_node_set_has_popup(ae->node, ACCESSKIT_HAS_POPUP_DIALOG);
|
|
} break;
|
|
}
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_set_checked(const RID &p_id, bool p_checekd) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
_ensure_node(p_id, ae);
|
|
|
|
if (p_checekd) {
|
|
accesskit_node_set_toggled(ae->node, ACCESSKIT_TOGGLED_TRUE);
|
|
} else {
|
|
accesskit_node_set_toggled(ae->node, ACCESSKIT_TOGGLED_FALSE);
|
|
}
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_set_num_value(const RID &p_id, double p_position) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
_ensure_node(p_id, ae);
|
|
|
|
accesskit_node_set_numeric_value(ae->node, p_position);
|
|
ae->value = p_position;
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_set_num_range(const RID &p_id, double p_min, double p_max) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
_ensure_node(p_id, ae);
|
|
|
|
accesskit_node_set_min_numeric_value(ae->node, p_min);
|
|
accesskit_node_set_max_numeric_value(ae->node, p_max);
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_set_num_step(const RID &p_id, double p_step) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
_ensure_node(p_id, ae);
|
|
|
|
accesskit_node_set_numeric_value_step(ae->node, p_step);
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_set_num_jump(const RID &p_id, double p_jump) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
_ensure_node(p_id, ae);
|
|
|
|
accesskit_node_set_numeric_value_jump(ae->node, p_jump);
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_set_scroll_x(const RID &p_id, double p_position) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
_ensure_node(p_id, ae);
|
|
|
|
accesskit_node_set_scroll_x(ae->node, p_position);
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_set_scroll_x_range(const RID &p_id, double p_min, double p_max) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
_ensure_node(p_id, ae);
|
|
|
|
accesskit_node_set_scroll_x_min(ae->node, p_min);
|
|
accesskit_node_set_scroll_x_max(ae->node, p_max);
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_set_scroll_y(const RID &p_id, double p_position) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
_ensure_node(p_id, ae);
|
|
|
|
accesskit_node_set_scroll_y(ae->node, p_position);
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_set_scroll_y_range(const RID &p_id, double p_min, double p_max) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
_ensure_node(p_id, ae);
|
|
|
|
accesskit_node_set_scroll_y_min(ae->node, p_min);
|
|
accesskit_node_set_scroll_y_max(ae->node, p_max);
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_set_text_decorations(const RID &p_id, bool p_underline, bool p_strikethrough, bool p_overline, const Color &p_color) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
_ensure_node(p_id, ae);
|
|
|
|
accesskit_color color;
|
|
color.red = p_color.get_r8();
|
|
color.blue = p_color.get_b8();
|
|
color.green = p_color.get_g8();
|
|
color.alpha = p_color.get_a8();
|
|
|
|
if (p_underline) {
|
|
accesskit_node_set_underline(ae->node, { ACCESSKIT_TEXT_DECORATION_STYLE_SOLID, color });
|
|
} else {
|
|
accesskit_node_clear_underline(ae->node);
|
|
}
|
|
if (p_overline) {
|
|
accesskit_node_set_overline(ae->node, { ACCESSKIT_TEXT_DECORATION_STYLE_SOLID, color });
|
|
} else {
|
|
accesskit_node_clear_overline(ae->node);
|
|
}
|
|
if (p_strikethrough) {
|
|
accesskit_node_set_strikethrough(ae->node, { ACCESSKIT_TEXT_DECORATION_STYLE_SOLID, color });
|
|
} else {
|
|
accesskit_node_clear_strikethrough(ae->node);
|
|
}
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_set_text_align(const RID &p_id, HorizontalAlignment p_align) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
_ensure_node(p_id, ae);
|
|
|
|
switch (p_align) {
|
|
case HORIZONTAL_ALIGNMENT_LEFT: {
|
|
accesskit_node_set_text_align(ae->node, ACCESSKIT_TEXT_ALIGN_LEFT);
|
|
} break;
|
|
case HORIZONTAL_ALIGNMENT_CENTER: {
|
|
accesskit_node_set_text_align(ae->node, ACCESSKIT_TEXT_ALIGN_RIGHT);
|
|
} break;
|
|
case HORIZONTAL_ALIGNMENT_RIGHT: {
|
|
accesskit_node_set_text_align(ae->node, ACCESSKIT_TEXT_ALIGN_CENTER);
|
|
} break;
|
|
case HORIZONTAL_ALIGNMENT_FILL: {
|
|
accesskit_node_set_text_align(ae->node, ACCESSKIT_TEXT_ALIGN_JUSTIFY);
|
|
} break;
|
|
}
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_set_text_selection(const RID &p_id, const RID &p_text_start_id, int p_start_char, const RID &p_text_end_id, int p_end_char) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
AccessibilityElement *start_ae = rid_owner.get_or_null(p_text_start_id);
|
|
ERR_FAIL_NULL(start_ae);
|
|
ERR_FAIL_COND(start_ae->window_id != ae->window_id);
|
|
AccessibilityElement *end_ae = rid_owner.get_or_null(p_text_end_id);
|
|
ERR_FAIL_NULL(end_ae);
|
|
ERR_FAIL_COND(end_ae->window_id != ae->window_id);
|
|
|
|
int start_pos = p_start_char;
|
|
int end_pos = p_end_char;
|
|
RID start_rid;
|
|
RID end_rid;
|
|
for (const RID &rid : start_ae->children) {
|
|
const AccessibilityElement *child_ae = rid_owner.get_or_null(rid);
|
|
if (child_ae && child_ae->role == ACCESSKIT_ROLE_TEXT_RUN) {
|
|
if (p_start_char >= child_ae->run.x && p_start_char <= child_ae->run.y) {
|
|
start_rid = rid;
|
|
start_pos = p_start_char - child_ae->run.x;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
for (const RID &rid : end_ae->children) {
|
|
const AccessibilityElement *child_ae = rid_owner.get_or_null(rid);
|
|
if (child_ae && child_ae->role == ACCESSKIT_ROLE_TEXT_RUN) {
|
|
if (p_end_char >= child_ae->run.x && p_end_char <= child_ae->run.y) {
|
|
end_rid = rid;
|
|
end_pos = p_end_char - child_ae->run.x;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
ERR_FAIL_COND(start_rid.is_null() && end_rid.is_null());
|
|
_ensure_node(p_id, ae);
|
|
|
|
accesskit_text_selection sel;
|
|
sel.anchor.node = (accesskit_node_id)start_rid.get_id();
|
|
sel.anchor.character_index = start_pos;
|
|
sel.focus.node = (accesskit_node_id)end_rid.get_id();
|
|
sel.focus.character_index = end_pos;
|
|
accesskit_node_set_text_selection(ae->node, sel);
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_set_flag(const RID &p_id, AccessibilityServerEnums::AccessibilityFlags p_flag, bool p_value) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
_ensure_node(p_id, ae);
|
|
|
|
if (p_value) {
|
|
ae->flags |= (1ULL << (uint64_t)p_flag);
|
|
} else {
|
|
ae->flags &= ~(1ULL << (uint64_t)p_flag);
|
|
}
|
|
switch (p_flag) {
|
|
case AccessibilityServerEnums::AccessibilityFlags::FLAG_HIDDEN: {
|
|
if (p_value) {
|
|
accesskit_node_set_hidden(ae->node);
|
|
} else {
|
|
accesskit_node_clear_hidden(ae->node);
|
|
}
|
|
} break;
|
|
case AccessibilityServerEnums::AccessibilityFlags::FLAG_MULTISELECTABLE: {
|
|
if (p_value) {
|
|
accesskit_node_set_multiselectable(ae->node);
|
|
} else {
|
|
accesskit_node_clear_multiselectable(ae->node);
|
|
}
|
|
} break;
|
|
case AccessibilityServerEnums::AccessibilityFlags::FLAG_REQUIRED: {
|
|
if (p_value) {
|
|
accesskit_node_set_required(ae->node);
|
|
} else {
|
|
accesskit_node_clear_required(ae->node);
|
|
}
|
|
} break;
|
|
case AccessibilityServerEnums::AccessibilityFlags::FLAG_VISITED: {
|
|
if (p_value) {
|
|
accesskit_node_set_visited(ae->node);
|
|
} else {
|
|
accesskit_node_clear_visited(ae->node);
|
|
}
|
|
} break;
|
|
case AccessibilityServerEnums::AccessibilityFlags::FLAG_BUSY: {
|
|
if (p_value) {
|
|
accesskit_node_set_busy(ae->node);
|
|
} else {
|
|
accesskit_node_clear_busy(ae->node);
|
|
}
|
|
} break;
|
|
case AccessibilityServerEnums::AccessibilityFlags::FLAG_MODAL: {
|
|
if (p_value) {
|
|
accesskit_node_set_modal(ae->node);
|
|
} else {
|
|
accesskit_node_clear_modal(ae->node);
|
|
}
|
|
} break;
|
|
case AccessibilityServerEnums::AccessibilityFlags::FLAG_TOUCH_PASSTHROUGH: {
|
|
if (p_value) {
|
|
accesskit_node_set_touch_transparent(ae->node);
|
|
} else {
|
|
accesskit_node_clear_touch_transparent(ae->node);
|
|
}
|
|
} break;
|
|
case AccessibilityServerEnums::AccessibilityFlags::FLAG_READONLY: {
|
|
if (p_value) {
|
|
accesskit_node_set_read_only(ae->node);
|
|
} else {
|
|
accesskit_node_clear_read_only(ae->node);
|
|
}
|
|
} break;
|
|
case AccessibilityServerEnums::AccessibilityFlags::FLAG_DISABLED: {
|
|
if (p_value) {
|
|
accesskit_node_set_disabled(ae->node);
|
|
} else {
|
|
accesskit_node_clear_disabled(ae->node);
|
|
}
|
|
} break;
|
|
case AccessibilityServerEnums::AccessibilityFlags::FLAG_CLIPS_CHILDREN: {
|
|
if (p_value) {
|
|
accesskit_node_set_clips_children(ae->node);
|
|
} else {
|
|
accesskit_node_clear_clips_children(ae->node);
|
|
}
|
|
} break;
|
|
}
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_set_classname(const RID &p_id, const String &p_classname) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
_ensure_node(p_id, ae);
|
|
|
|
if (!p_classname.is_empty()) {
|
|
accesskit_node_set_class_name(ae->node, p_classname.utf8().ptr());
|
|
} else {
|
|
accesskit_node_clear_class_name(ae->node);
|
|
}
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_set_placeholder(const RID &p_id, const String &p_placeholder) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
_ensure_node(p_id, ae);
|
|
|
|
if (!p_placeholder.is_empty()) {
|
|
accesskit_node_set_placeholder(ae->node, p_placeholder.utf8().ptr());
|
|
} else {
|
|
accesskit_node_clear_placeholder(ae->node);
|
|
}
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_set_language(const RID &p_id, const String &p_language) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
_ensure_node(p_id, ae);
|
|
|
|
accesskit_node_set_language(ae->node, p_language.utf8().ptr());
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_set_text_orientation(const RID &p_id, bool p_vertical) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
_ensure_node(p_id, ae);
|
|
|
|
if (p_vertical) {
|
|
accesskit_node_set_text_direction(ae->node, ACCESSKIT_TEXT_DIRECTION_TOP_TO_BOTTOM);
|
|
} else {
|
|
accesskit_node_set_text_direction(ae->node, ACCESSKIT_TEXT_DIRECTION_LEFT_TO_RIGHT);
|
|
}
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_set_list_orientation(const RID &p_id, bool p_vertical) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
_ensure_node(p_id, ae);
|
|
|
|
if (p_vertical) {
|
|
accesskit_node_set_orientation(ae->node, ACCESSKIT_ORIENTATION_VERTICAL);
|
|
} else {
|
|
accesskit_node_set_orientation(ae->node, ACCESSKIT_ORIENTATION_HORIZONTAL);
|
|
}
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_set_shortcut(const RID &p_id, const String &p_shortcut) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
_ensure_node(p_id, ae);
|
|
|
|
if (!p_shortcut.is_empty()) {
|
|
accesskit_node_set_keyboard_shortcut(ae->node, p_shortcut.utf8().ptr());
|
|
} else {
|
|
accesskit_node_clear_keyboard_shortcut(ae->node);
|
|
}
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_set_url(const RID &p_id, const String &p_url) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
_ensure_node(p_id, ae);
|
|
|
|
if (!p_url.is_empty()) {
|
|
accesskit_node_set_url(ae->node, p_url.utf8().ptr());
|
|
} else {
|
|
accesskit_node_clear_url(ae->node);
|
|
}
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_set_role_description(const RID &p_id, const String &p_description) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
_ensure_node(p_id, ae);
|
|
|
|
if (!p_description.is_empty()) {
|
|
accesskit_node_set_role_description(ae->node, p_description.utf8().ptr());
|
|
} else {
|
|
accesskit_node_clear_role_description(ae->node);
|
|
}
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_set_state_description(const RID &p_id, const String &p_description) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
_ensure_node(p_id, ae);
|
|
|
|
if (!p_description.is_empty()) {
|
|
accesskit_node_set_state_description(ae->node, p_description.utf8().ptr());
|
|
} else {
|
|
accesskit_node_clear_state_description(ae->node);
|
|
}
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_set_color_value(const RID &p_id, const Color &p_color) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
_ensure_node(p_id, ae);
|
|
|
|
ae->value = p_color;
|
|
|
|
accesskit_color color;
|
|
color.red = p_color.get_r8();
|
|
color.blue = p_color.get_b8();
|
|
color.green = p_color.get_g8();
|
|
color.alpha = p_color.get_a8();
|
|
|
|
accesskit_node_set_color_value(ae->node, color);
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_set_background_color(const RID &p_id, const Color &p_color) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
_ensure_node(p_id, ae);
|
|
|
|
accesskit_color color;
|
|
color.red = p_color.get_r8();
|
|
color.blue = p_color.get_b8();
|
|
color.green = p_color.get_g8();
|
|
color.alpha = p_color.get_a8();
|
|
|
|
accesskit_node_set_background_color(ae->node, color);
|
|
}
|
|
|
|
void AccessibilityServerAccessKit::update_set_foreground_color(const RID &p_id, const Color &p_color) {
|
|
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
|
|
|
|
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
|
|
ERR_FAIL_NULL(ae);
|
|
_ensure_node(p_id, ae);
|
|
|
|
accesskit_color color;
|
|
color.red = p_color.get_r8();
|
|
color.blue = p_color.get_b8();
|
|
color.green = p_color.get_g8();
|
|
color.alpha = p_color.get_a8();
|
|
|
|
accesskit_node_set_foreground_color(ae->node, color);
|
|
}
|
|
|
|
AccessibilityServer *AccessibilityServerAccessKit::create_func(Error &r_error) {
|
|
print_verbose("Accessibility: AccessKit driver loaded.");
|
|
r_error = OK;
|
|
return memnew(AccessibilityServerAccessKit);
|
|
}
|
|
|
|
AccessibilityServerAccessKit::AccessibilityServerAccessKit() {
|
|
role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_UNKNOWN] = ACCESSKIT_ROLE_UNKNOWN;
|
|
role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_DEFAULT_BUTTON] = ACCESSKIT_ROLE_DEFAULT_BUTTON;
|
|
role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_AUDIO] = ACCESSKIT_ROLE_AUDIO;
|
|
role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_VIDEO] = ACCESSKIT_ROLE_VIDEO;
|
|
role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_STATIC_TEXT] = ACCESSKIT_ROLE_LABEL;
|
|
role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_CONTAINER] = ACCESSKIT_ROLE_GENERIC_CONTAINER;
|
|
role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_PANEL] = ACCESSKIT_ROLE_PANE;
|
|
role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_BUTTON] = ACCESSKIT_ROLE_BUTTON;
|
|
role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_LINK] = ACCESSKIT_ROLE_LINK;
|
|
role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_CHECK_BOX] = ACCESSKIT_ROLE_CHECK_BOX;
|
|
role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_RADIO_BUTTON] = ACCESSKIT_ROLE_RADIO_BUTTON;
|
|
role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_CHECK_BUTTON] = ACCESSKIT_ROLE_SWITCH;
|
|
role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_SCROLL_BAR] = ACCESSKIT_ROLE_SCROLL_BAR;
|
|
role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_SCROLL_VIEW] = ACCESSKIT_ROLE_SCROLL_VIEW;
|
|
role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_SPLITTER] = ACCESSKIT_ROLE_SPLITTER;
|
|
role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_SLIDER] = ACCESSKIT_ROLE_SLIDER;
|
|
role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_SPIN_BUTTON] = ACCESSKIT_ROLE_SPIN_BUTTON;
|
|
role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_PROGRESS_INDICATOR] = ACCESSKIT_ROLE_PROGRESS_INDICATOR;
|
|
role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_TEXT_FIELD] = ACCESSKIT_ROLE_TEXT_INPUT;
|
|
role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_MULTILINE_TEXT_FIELD] = ACCESSKIT_ROLE_MULTILINE_TEXT_INPUT;
|
|
role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_COLOR_PICKER] = ACCESSKIT_ROLE_COLOR_WELL;
|
|
role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_TABLE] = ACCESSKIT_ROLE_TABLE;
|
|
role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_CELL] = ACCESSKIT_ROLE_CELL;
|
|
role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_ROW] = ACCESSKIT_ROLE_ROW;
|
|
role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_ROW_GROUP] = ACCESSKIT_ROLE_ROW_GROUP;
|
|
role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_ROW_HEADER] = ACCESSKIT_ROLE_ROW_HEADER;
|
|
role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_COLUMN_HEADER] = ACCESSKIT_ROLE_COLUMN_HEADER;
|
|
role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_TREE] = ACCESSKIT_ROLE_TREE;
|
|
role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_TREE_ITEM] = ACCESSKIT_ROLE_TREE_ITEM;
|
|
role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_LIST] = ACCESSKIT_ROLE_LIST;
|
|
role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_LIST_ITEM] = ACCESSKIT_ROLE_LIST_ITEM;
|
|
role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_LIST_BOX] = ACCESSKIT_ROLE_LIST_BOX;
|
|
role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_LIST_BOX_OPTION] = ACCESSKIT_ROLE_LIST_BOX_OPTION;
|
|
role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_TAB_BAR] = ACCESSKIT_ROLE_TAB_LIST;
|
|
role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_TAB] = ACCESSKIT_ROLE_TAB;
|
|
role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_TAB_PANEL] = ACCESSKIT_ROLE_TAB_PANEL;
|
|
role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_MENU_BAR] = ACCESSKIT_ROLE_MENU_BAR;
|
|
role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_MENU] = ACCESSKIT_ROLE_MENU;
|
|
role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_MENU_ITEM] = ACCESSKIT_ROLE_MENU_ITEM;
|
|
role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_MENU_ITEM_CHECK_BOX] = ACCESSKIT_ROLE_MENU_ITEM_CHECK_BOX;
|
|
role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_MENU_ITEM_RADIO] = ACCESSKIT_ROLE_MENU_ITEM_RADIO;
|
|
role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_IMAGE] = ACCESSKIT_ROLE_IMAGE;
|
|
role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_WINDOW] = ACCESSKIT_ROLE_WINDOW;
|
|
role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_TITLE_BAR] = ACCESSKIT_ROLE_TITLE_BAR;
|
|
role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_DIALOG] = ACCESSKIT_ROLE_DIALOG;
|
|
role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_TOOLTIP] = ACCESSKIT_ROLE_TOOLTIP;
|
|
role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_REGION] = ACCESSKIT_ROLE_REGION;
|
|
role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_TEXT_RUN] = ACCESSKIT_ROLE_TEXT_RUN;
|
|
|
|
action_map[AccessibilityServerEnums::AccessibilityAction::ACTION_CLICK] = ACCESSKIT_ACTION_CLICK;
|
|
action_map[AccessibilityServerEnums::AccessibilityAction::ACTION_FOCUS] = ACCESSKIT_ACTION_FOCUS;
|
|
action_map[AccessibilityServerEnums::AccessibilityAction::ACTION_BLUR] = ACCESSKIT_ACTION_BLUR;
|
|
action_map[AccessibilityServerEnums::AccessibilityAction::ACTION_COLLAPSE] = ACCESSKIT_ACTION_COLLAPSE;
|
|
action_map[AccessibilityServerEnums::AccessibilityAction::ACTION_EXPAND] = ACCESSKIT_ACTION_EXPAND;
|
|
action_map[AccessibilityServerEnums::AccessibilityAction::ACTION_DECREMENT] = ACCESSKIT_ACTION_DECREMENT;
|
|
action_map[AccessibilityServerEnums::AccessibilityAction::ACTION_INCREMENT] = ACCESSKIT_ACTION_INCREMENT;
|
|
action_map[AccessibilityServerEnums::AccessibilityAction::ACTION_HIDE_TOOLTIP] = ACCESSKIT_ACTION_HIDE_TOOLTIP;
|
|
action_map[AccessibilityServerEnums::AccessibilityAction::ACTION_SHOW_TOOLTIP] = ACCESSKIT_ACTION_SHOW_TOOLTIP;
|
|
//action_map[AccessibilityServerEnums::AccessibilityAction::ACTION_INVALIDATE_TREE] = ACCESSKIT_ACTION_INVALIDATE_TREE;
|
|
//action_map[AccessibilityServerEnums::AccessibilityAction::ACTION_LOAD_INLINE_TEXT_BOXES] = ACCESSKIT_ACTION_LOAD_INLINE_TEXT_BOXES;
|
|
action_map[AccessibilityServerEnums::AccessibilityAction::ACTION_SET_TEXT_SELECTION] = ACCESSKIT_ACTION_SET_TEXT_SELECTION;
|
|
action_map[AccessibilityServerEnums::AccessibilityAction::ACTION_REPLACE_SELECTED_TEXT] = ACCESSKIT_ACTION_REPLACE_SELECTED_TEXT;
|
|
action_map[AccessibilityServerEnums::AccessibilityAction::ACTION_SCROLL_BACKWARD] = ACCESSKIT_ACTION_SCROLL_UP;
|
|
action_map[AccessibilityServerEnums::AccessibilityAction::ACTION_SCROLL_DOWN] = ACCESSKIT_ACTION_SCROLL_DOWN;
|
|
action_map[AccessibilityServerEnums::AccessibilityAction::ACTION_SCROLL_FORWARD] = ACCESSKIT_ACTION_SCROLL_DOWN;
|
|
action_map[AccessibilityServerEnums::AccessibilityAction::ACTION_SCROLL_LEFT] = ACCESSKIT_ACTION_SCROLL_LEFT;
|
|
action_map[AccessibilityServerEnums::AccessibilityAction::ACTION_SCROLL_RIGHT] = ACCESSKIT_ACTION_SCROLL_RIGHT;
|
|
action_map[AccessibilityServerEnums::AccessibilityAction::ACTION_SCROLL_UP] = ACCESSKIT_ACTION_SCROLL_UP;
|
|
action_map[AccessibilityServerEnums::AccessibilityAction::ACTION_SCROLL_INTO_VIEW] = ACCESSKIT_ACTION_SCROLL_INTO_VIEW;
|
|
action_map[AccessibilityServerEnums::AccessibilityAction::ACTION_SCROLL_TO_POINT] = ACCESSKIT_ACTION_SCROLL_TO_POINT;
|
|
action_map[AccessibilityServerEnums::AccessibilityAction::ACTION_SET_SCROLL_OFFSET] = ACCESSKIT_ACTION_SET_SCROLL_OFFSET;
|
|
//action_map[AccessibilityServerEnums::AccessibilityAction::ACTION_SET_SEQUENTIAL_FOCUS_NAVIGATION_STARTING_POINT] = ACCESSKIT_ACTION_SET_SEQUENTIAL_FOCUS_NAVIGATION_STARTING_POINT;
|
|
action_map[AccessibilityServerEnums::AccessibilityAction::ACTION_SET_VALUE] = ACCESSKIT_ACTION_SET_VALUE;
|
|
action_map[AccessibilityServerEnums::AccessibilityAction::ACTION_SHOW_CONTEXT_MENU] = ACCESSKIT_ACTION_SHOW_CONTEXT_MENU;
|
|
action_map[AccessibilityServerEnums::AccessibilityAction::ACTION_CUSTOM] = ACCESSKIT_ACTION_CUSTOM_ACTION;
|
|
}
|
|
|
|
AccessibilityServerAccessKit::~AccessibilityServerAccessKit() {}
|
|
|
|
void AccessibilityServerAccessKit::register_create_func() {
|
|
register_create_function("accesskit", create_func);
|
|
}
|
|
|
|
#endif // ACCESSKIT_ENABLED
|