use accesskit::{Node, NodeId, Rect};
use crate::types::{AccessibilityNode, AccessibilityRelationships, Bounds, ElementId, LiveRegion};
#[inline]
pub fn element_id_to_node_id(id: ElementId) -> NodeId {
NodeId(id.as_u64())
}
pub fn to_accesskit_node(node: &AccessibilityNode) -> Node {
let info = &node.info;
let mut ak = Node::new(info.role.into());
if let Some(label) = &info.label {
ak.set_label(label.clone());
}
if let Some(description) = &info.description {
ak.set_description(description.clone());
}
if let Some(value) = &info.value {
ak.set_value(value.clone());
}
if info.is_disabled {
ak.set_disabled();
}
if let Some(expanded) = info.is_expanded {
ak.set_expanded(expanded);
}
if let Some(selected) = info.is_selected {
ak.set_selected(selected);
}
if let Some(live) = info.live_region {
ak.set_live(match live {
LiveRegion::Polite => accesskit::Live::Polite,
LiveRegion::Assertive => accesskit::Live::Assertive,
});
}
apply_relationships(&mut ak, &info.relationships);
if !node.actions.is_empty() {
for action in &node.actions {
ak.add_action((*action).into());
}
}
ak.set_bounds(bounds_to_rect(node.bounds));
if !node.children.is_empty() {
let child_ids: Vec<NodeId> = node
.children
.iter()
.map(|c| element_id_to_node_id(c.id))
.collect();
ak.set_children(child_ids);
}
let _ = info.tab_index;
ak
}
pub fn to_accesskit_tree(node: &AccessibilityNode) -> Vec<(NodeId, Node)> {
let mut out = Vec::new();
push_node_recursive(node, &mut out);
out
}
fn push_node_recursive(node: &AccessibilityNode, out: &mut Vec<(NodeId, Node)>) {
out.push((element_id_to_node_id(node.id), to_accesskit_node(node)));
for child in &node.children {
push_node_recursive(child, out);
}
}
fn apply_relationships(ak: &mut Node, rel: &AccessibilityRelationships) {
if !rel.labelled_by.is_empty() {
ak.set_labelled_by(translate_ids(&rel.labelled_by));
}
if !rel.described_by.is_empty() {
ak.set_described_by(translate_ids(&rel.described_by));
}
if !rel.controls.is_empty() {
ak.set_controls(translate_ids(&rel.controls));
}
if !rel.owns.is_empty() {
ak.set_owns(translate_ids(&rel.owns));
}
}
fn translate_ids(ids: &[ElementId]) -> Vec<NodeId> {
ids.iter().copied().map(element_id_to_node_id).collect()
}
fn bounds_to_rect(b: Bounds) -> Rect {
let x0 = b.origin.x as f64;
let y0 = b.origin.y as f64;
let x1 = x0 + b.size.width as f64;
let y1 = y0 + b.size.height as f64;
Rect { x0, y0, x1, y1 }
}