Skip to content

Commit

Permalink
feat: accessibility with some widget impls
Browse files Browse the repository at this point in the history
feat: stable ids

a11y: Don't unconditionally pull winit (iced-rs#43)
  • Loading branch information
wash2 authored and ryanabx committed Jul 28, 2024
1 parent 7cba9a3 commit 131ddc9
Show file tree
Hide file tree
Showing 62 changed files with 3,044 additions and 419 deletions.
37 changes: 22 additions & 15 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ all-features = true
maintenance = { status = "actively-developed" }

[features]
default = ["wgpu"]
default = ["wgpu", "winit", "multi-window", "a11y"]
# Enable the `wgpu` GPU-accelerated renderer backend
wgpu = ["iced_renderer/wgpu", "iced_widget/wgpu"]
# Enables the `Image` widget
Expand Down Expand Up @@ -53,6 +53,10 @@ highlighter = ["iced_highlighter"]
multi-window = ["iced_winit/multi-window"]
# Enables the advanced module
advanced = []
# Enables the `accesskit` accessibility library
a11y = ["iced_accessibility", "iced_core/a11y", "iced_widget/a11y", "iced_winit?/a11y"]
# Enables the winit shell. Conflicts with `wayland` and `glutin`.
winit = ["iced_winit", "iced_accessibility?/accesskit_winit"]

[dependencies]
iced_core.workspace = true
Expand All @@ -61,41 +65,43 @@ iced_renderer.workspace = true
iced_widget.workspace = true
iced_winit.features = ["application"]
iced_winit.workspace = true

iced_winit.optional = true
iced_highlighter.workspace = true
iced_highlighter.optional = true

iced_accessibility.workspace = true
iced_accessibility.optional = true
thiserror.workspace = true

image.workspace = true
image.optional = true

[profile.release-opt]
inherits = "release"
codegen-units = 1
debug = false
lto = true
incremental = false
opt-level = 3
overflow-checks = false
strip = "debuginfo"

[workspace]
members = [
"core",
"futures",
"graphics",
"highlighter",
"renderer",
"runtime",
"renderer",
"style",
"tiny_skia",
"wgpu",
"widget",
"winit",
"examples/*",
"accessibility",
]

[profile.release-opt]
inherits = "release"
codegen-units = 1
debug = false
lto = true
incremental = false
opt-level = 3
overflow-checks = false
strip = "debuginfo"

[workspace.package]
version = "0.12.0"
authors = ["Héctor Ramón Jiménez <hector@hecrj.dev>"]
Expand All @@ -118,7 +124,8 @@ iced_style = { version = "0.12", path = "style" }
iced_tiny_skia = { version = "0.12", path = "tiny_skia" }
iced_wgpu = { version = "0.12", path = "wgpu" }
iced_widget = { version = "0.12", path = "widget" }
iced_winit = { version = "0.12", path = "winit" }
iced_winit = { version = "0.12", path = "winit", features = ["application"] }
iced_accessibility = { version = "0.1", path = "accessibility" }

async-std = "1.0"
bitflags = "1.0"
Expand Down
19 changes: 19 additions & 0 deletions accessibility/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[package]
name = "iced_accessibility"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
# TODO Ashley re-export more platform adapters

[dependencies]
accesskit = { git = "https://github.com/wash2/accesskit.git", branch = "winit-0.29" }
accesskit_unix = { git = "https://github.com/wash2/accesskit.git", branch = "winit-0.29", optional = true }
accesskit_windows = { git = "https://github.com/wash2/accesskit.git", branch = "winit-0.29", optional = true}
accesskit_macos = { git = "https://github.com/wash2/accesskit.git", branch = "winit-0.29", optional = true}
accesskit_winit = { git = "https://github.com/wash2/accesskit.git", branch = "winit-0.29", optional = true}
# accesskit = { path = "../../fork/accesskit/common/", version = "0.11.0" }
# accesskit_unix = { path = "../../fork/accesskit/platforms/unix/", version = "0.4.0", optional = true }
# accesskit_windows = { path = "../../fork/accesskit/platforms/windows/", version = "0.14.0", optional = true}
# accesskit_macos = { path = "../../fork/accesskit/platforms/macos/", version = "0.7.0", optional = true}
# accesskit_winit = { path = "../../fork/accesskit/platforms/winit/", version = "0.13.0", optional = true}
80 changes: 80 additions & 0 deletions accessibility/src/a11y_tree.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
use crate::{A11yId, A11yNode};

#[derive(Debug, Clone, Default)]
/// Accessible tree of nodes
pub struct A11yTree {
/// The root of the current widget, children of the parent widget or the Window if there is no parent widget
root: Vec<A11yNode>,
/// The children of a widget and its children
children: Vec<A11yNode>,
}

impl A11yTree {
/// Create a new A11yTree
/// XXX if you use this method, you will need to manually add the children of the root nodes
pub fn new(root: Vec<A11yNode>, children: Vec<A11yNode>) -> Self {
Self { root, children }
}

pub fn leaf<T: Into<A11yId>>(node: accesskit::NodeBuilder, id: T) -> Self {
Self {
root: vec![A11yNode::new(node, id)],
children: vec![],
}
}

/// Helper for creating an A11y tree with a single root node and some children
pub fn node_with_child_tree(mut root: A11yNode, child_tree: Self) -> Self {
root.add_children(
child_tree.root.iter().map(|n| n.id()).cloned().collect(),
);
Self {
root: vec![root],
children: child_tree
.children
.into_iter()
.chain(child_tree.root)
.collect(),
}
}

/// Joins multiple trees into a single tree
pub fn join<T: Iterator<Item = Self>>(trees: T) -> Self {
trees.fold(Self::default(), |mut acc, A11yTree { root, children }| {
acc.root.extend(root);
acc.children.extend(children);
acc
})
}

pub fn root(&self) -> &Vec<A11yNode> {
&self.root
}

pub fn children(&self) -> &Vec<A11yNode> {
&self.children
}

pub fn root_mut(&mut self) -> &mut Vec<A11yNode> {
&mut self.root
}

pub fn children_mut(&mut self) -> &mut Vec<A11yNode> {
&mut self.children
}

pub fn contains(&self, id: &A11yId) -> bool {
self.root.iter().any(|n| n.id() == id)
|| self.children.iter().any(|n| n.id() == id)
}
}

impl From<A11yTree> for Vec<(accesskit::NodeId, accesskit::Node)> {
fn from(tree: A11yTree) -> Vec<(accesskit::NodeId, accesskit::Node)> {
tree.root
.into_iter()
.map(|node| node.into())
.chain(tree.children.into_iter().map(|node| node.into()))
.collect()
}
}
Loading

0 comments on commit 131ddc9

Please sign in to comment.