bevy/crates/bevy_a11y/src/lib.rs

111 lines
3.3 KiB
Rust
Raw Normal View History

//! Accessibility for Bevy
#![forbid(unsafe_code)]
use std::sync::{
atomic::{AtomicBool, Ordering},
Arc,
};
pub use accesskit;
use accesskit::NodeBuilder;
use bevy_app::Plugin;
use bevy_derive::{Deref, DerefMut};
use bevy_ecs::{
prelude::{Component, Entity, Event},
schedule::SystemSet,
system::Resource,
};
/// Wrapper struct for [`accesskit::ActionRequest`]. Required to allow it to be used as an `Event`.
#[derive(Event, Deref, DerefMut)]
pub struct ActionRequest(pub accesskit::ActionRequest);
/// Resource that tracks whether an assistive technology has requested
/// accessibility information.
///
/// Useful if a third-party plugin needs to conditionally integrate with
/// `AccessKit`
#[derive(Resource, Default, Clone, Debug, Deref, DerefMut)]
pub struct AccessibilityRequested(Arc<AtomicBool>);
impl AccessibilityRequested {
/// Returns `true` if an access technology is active and accessibility tree
/// updates should be sent.
pub fn get(&self) -> bool {
self.load(Ordering::SeqCst)
}
/// Sets whether accessibility updates were requested by an access technology.
pub fn set(&self, value: bool) {
self.store(value, Ordering::SeqCst);
}
}
/// Resource whose value determines whether the accessibility tree is updated
/// via the ECS.
///
/// Set to `false` in cases where an external GUI library is sending
/// accessibility updates instead. Without this, the external library and ECS
/// will generate conflicting updates.
#[derive(Resource, Clone, Debug, Deref, DerefMut)]
pub struct ManageAccessibilityUpdates(bool);
impl Default for ManageAccessibilityUpdates {
fn default() -> Self {
Self(true)
}
}
impl ManageAccessibilityUpdates {
/// Returns `true` if the ECS should update the accessibility tree.
pub fn get(&self) -> bool {
self.0
}
/// Sets whether the ECS should update the accessibility tree.
pub fn set(&mut self, value: bool) {
self.0 = value;
}
}
/// Component to wrap a [`accesskit::Node`], representing this entity to the platform's
/// accessibility API.
///
/// If an entity has a parent, and that parent also has an `AccessibilityNode`,
/// the entity's node will be a child of the parent's node.
///
/// If the entity doesn't have a parent, or if the immediate parent doesn't have
/// an `AccessibilityNode`, its node will be an immediate child of the primary window.
#[derive(Component, Clone, Deref, DerefMut)]
pub struct AccessibilityNode(pub NodeBuilder);
impl From<NodeBuilder> for AccessibilityNode {
fn from(node: NodeBuilder) -> Self {
Self(node)
}
}
/// Resource representing which entity has keyboard focus, if any.
#[derive(Resource, Default, Deref, DerefMut)]
pub struct Focus(pub Option<Entity>);
/// Set enum for the systems relating to accessibility
#[derive(Debug, Hash, PartialEq, Eq, Clone, SystemSet)]
pub enum AccessibilitySystem {
/// Update the accessibility tree
Update,
}
/// Plugin managing non-GUI aspects of integrating with accessibility APIs.
pub struct AccessibilityPlugin;
impl Plugin for AccessibilityPlugin {
fn build(&self, app: &mut bevy_app::App) {
app.init_resource::<AccessibilityRequested>()
.init_resource::<ManageAccessibilityUpdates>()
resolve all internal ambiguities (#10411) - ignore all ambiguities that are not a problem - remove `.before(Assets::<Image>::track_assets),` that points into a different schedule (-> should this be caught?) - add some explicit orderings: - run `poll_receivers` and `update_accessibility_nodes` after `window_closed` in `bevy_winit::accessibility` - run `bevy_ui::accessibility::calc_bounds` after `CameraUpdateSystem` - run ` bevy_text::update_text2d_layout` and `bevy_ui::text_system` after `font_atlas_set::remove_dropped_font_atlas_sets` - add `app.ignore_ambiguity(a, b)` function for cases where you want to ignore an ambiguity between two independent plugins `A` and `B` - add `IgnoreAmbiguitiesPlugin` in `DefaultPlugins` that allows cross-crate ambiguities like `bevy_animation`/`bevy_ui` - Fixes https://github.com/bevyengine/bevy/issues/9511 ## Before **Render** ![render_schedule_Render dot](https://github.com/bevyengine/bevy/assets/22177966/1c677968-7873-40cc-848c-91fca4c8e383) **PostUpdate** ![schedule_PostUpdate dot](https://github.com/bevyengine/bevy/assets/22177966/8fc61304-08d4-4533-8110-c04113a7367a) ## After **Render** ![render_schedule_Render dot](https://github.com/bevyengine/bevy/assets/22177966/462f3b28-cef7-4833-8619-1f5175983485) **PostUpdate** ![schedule_PostUpdate dot](https://github.com/bevyengine/bevy/assets/22177966/8cfb3d83-7842-4a84-9082-46177e1a6c70) --------- Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com> Co-authored-by: Alice Cecile <alice.i.cecil@gmail.com> Co-authored-by: François <mockersf@gmail.com>
2024-01-09 19:08:15 +00:00
.init_resource::<Focus>()
.allow_ambiguous_component::<AccessibilityNode>();
}
}