Closed DataTriny closed 1 month ago
These changes were tested on all platforms with the example below:
```rust use accesskit::{ Action, DefaultActionVerb, Node, NodeBuilder, NodeId, Orientation, Rect, Role, Tree, TreeUpdate, }; use accesskit_winit::{Adapter, Event as AccessKitEvent, WindowEvent as AccessKitWindowEvent}; use std::error::Error; use winit::{ application::ApplicationHandler, event::WindowEvent, event_loop::{ActiveEventLoop, EventLoop, EventLoopProxy}, window::{Window, WindowId}, }; const WINDOW_TITLE: &str = "Orientation test"; const WINDOW_ID: NodeId = NodeId(0); const HORIZONTAL_SCROLLBAR_ID: NodeId = NodeId(1); const VERTICAL_SCROLLBAR_ID: NodeId = NodeId(2); const INITIAL_FOCUS: NodeId = WINDOW_ID; const HORIZONTAL_SCROLLBAR_RECT: Rect = Rect { x0: 0.0, y0: 380.0, x1: 380.0, y1: 400.0, }; const VERTICAL_SCROLLBAR_RECT: Rect = Rect { x0: 380.0, y0: 0.0, x1: 400.0, y1: 380.0, }; fn build_scrollbar(bounds: Rect, orientation: Orientation, value: f64) -> Node { let mut builder = NodeBuilder::new(Role::ScrollBar); builder.set_bounds(bounds); builder.set_orientation(orientation); builder.set_min_numeric_value(0.0); builder.set_max_numeric_value(100.0); builder.set_numeric_value(value); builder.add_action(Action::Focus); builder.set_default_action_verb(DefaultActionVerb::Click); builder.build() } struct UiState; impl UiState { fn new() -> Self { Self {} } fn build_root(&mut self) -> Node { let mut builder = NodeBuilder::new(Role::Window); builder.set_children(&[HORIZONTAL_SCROLLBAR_ID, VERTICAL_SCROLLBAR_ID]); builder.set_name(WINDOW_TITLE); builder.build() } fn build_initial_tree(&mut self) -> TreeUpdate { let root = self.build_root(); let hbar = build_scrollbar(HORIZONTAL_SCROLLBAR_RECT, Orientation::Horizontal, 0.0); let vbar = build_scrollbar(VERTICAL_SCROLLBAR_RECT, Orientation::Vertical, 50.0); let mut tree = Tree::new(WINDOW_ID); tree.app_name = Some("orientation_example".to_string()); TreeUpdate { nodes: vec![ (WINDOW_ID, root), (HORIZONTAL_SCROLLBAR_ID, hbar), (VERTICAL_SCROLLBAR_ID, vbar), ], tree: Some(tree), focus: INITIAL_FOCUS, } } } struct WindowState { window: Window, adapter: Adapter, ui: UiState, } impl WindowState { fn new(window: Window, adapter: Adapter, ui: UiState) -> Self { Self { window, adapter, ui, } } } struct Application { event_loop_proxy: EventLoopProxy, window: Option, } impl Application { fn new(event_loop_proxy: EventLoopProxy) -> Self { Self { event_loop_proxy, window: None, } } fn create_window(&mut self, event_loop: &ActiveEventLoop) -> Result<(), Box> { let window_attributes = Window::default_attributes() .with_title(WINDOW_TITLE) .with_visible(false); let window = event_loop.create_window(window_attributes)?; let adapter = Adapter::with_event_loop_proxy(&window, self.event_loop_proxy.clone()); window.set_visible(true); self.window = Some(WindowState::new(window, adapter, UiState::new())); Ok(()) } } impl ApplicationHandler for Application { fn window_event(&mut self, _: &ActiveEventLoop, _: WindowId, event: WindowEvent) { let window = match &mut self.window { Some(window) => window, None => return, }; let adapter = &mut window.adapter; adapter.process_event(&window.window, &event); match event { WindowEvent::CloseRequested => { self.window = None; } _ => (), } } fn user_event(&mut self, _: &ActiveEventLoop, user_event: AccessKitEvent) { let window = match &mut self.window { Some(window) => window, None => return, }; let adapter = &mut window.adapter; let state = &mut window.ui; match user_event.window_event { AccessKitWindowEvent::InitialTreeRequested => { adapter.update_if_active(|| state.build_initial_tree()); } _ => (), } } fn resumed(&mut self, event_loop: &ActiveEventLoop) { self.create_window(event_loop) .expect("failed to create initial window"); } fn about_to_wait(&mut self, event_loop: &ActiveEventLoop) { if self.window.is_none() { event_loop.exit(); } } } fn main() -> Result<(), Box> { let event_loop = EventLoop::with_user_event().build()?; let mut state = Application::new(event_loop.create_proxy()); event_loop.run_app(&mut state).map_err(Into::into) } ```
These changes were tested on all platforms with the example below:
platforms/winit/examples/orientation.rs
```rust use accesskit::{ Action, DefaultActionVerb, Node, NodeBuilder, NodeId, Orientation, Rect, Role, Tree, TreeUpdate, }; use accesskit_winit::{Adapter, Event as AccessKitEvent, WindowEvent as AccessKitWindowEvent}; use std::error::Error; use winit::{ application::ApplicationHandler, event::WindowEvent, event_loop::{ActiveEventLoop, EventLoop, EventLoopProxy}, window::{Window, WindowId}, }; const WINDOW_TITLE: &str = "Orientation test"; const WINDOW_ID: NodeId = NodeId(0); const HORIZONTAL_SCROLLBAR_ID: NodeId = NodeId(1); const VERTICAL_SCROLLBAR_ID: NodeId = NodeId(2); const INITIAL_FOCUS: NodeId = WINDOW_ID; const HORIZONTAL_SCROLLBAR_RECT: Rect = Rect { x0: 0.0, y0: 380.0, x1: 380.0, y1: 400.0, }; const VERTICAL_SCROLLBAR_RECT: Rect = Rect { x0: 380.0, y0: 0.0, x1: 400.0, y1: 380.0, }; fn build_scrollbar(bounds: Rect, orientation: Orientation, value: f64) -> Node { let mut builder = NodeBuilder::new(Role::ScrollBar); builder.set_bounds(bounds); builder.set_orientation(orientation); builder.set_min_numeric_value(0.0); builder.set_max_numeric_value(100.0); builder.set_numeric_value(value); builder.add_action(Action::Focus); builder.set_default_action_verb(DefaultActionVerb::Click); builder.build() } struct UiState; impl UiState { fn new() -> Self { Self {} } fn build_root(&mut self) -> Node { let mut builder = NodeBuilder::new(Role::Window); builder.set_children(&[HORIZONTAL_SCROLLBAR_ID, VERTICAL_SCROLLBAR_ID]); builder.set_name(WINDOW_TITLE); builder.build() } fn build_initial_tree(&mut self) -> TreeUpdate { let root = self.build_root(); let hbar = build_scrollbar(HORIZONTAL_SCROLLBAR_RECT, Orientation::Horizontal, 0.0); let vbar = build_scrollbar(VERTICAL_SCROLLBAR_RECT, Orientation::Vertical, 50.0); let mut tree = Tree::new(WINDOW_ID); tree.app_name = Some("orientation_example".to_string()); TreeUpdate { nodes: vec![ (WINDOW_ID, root), (HORIZONTAL_SCROLLBAR_ID, hbar), (VERTICAL_SCROLLBAR_ID, vbar), ], tree: Some(tree), focus: INITIAL_FOCUS, } } } struct WindowState { window: Window, adapter: Adapter, ui: UiState, } impl WindowState { fn new(window: Window, adapter: Adapter, ui: UiState) -> Self { Self { window, adapter, ui, } } } struct Application { event_loop_proxy: EventLoopProxy,
window: Option,
}
impl Application {
fn new(event_loop_proxy: EventLoopProxy) -> Self {
Self {
event_loop_proxy,
window: None,
}
}
fn create_window(&mut self, event_loop: &ActiveEventLoop) -> Result<(), Box> {
let window_attributes = Window::default_attributes()
.with_title(WINDOW_TITLE)
.with_visible(false);
let window = event_loop.create_window(window_attributes)?;
let adapter = Adapter::with_event_loop_proxy(&window, self.event_loop_proxy.clone());
window.set_visible(true);
self.window = Some(WindowState::new(window, adapter, UiState::new()));
Ok(())
}
}
impl ApplicationHandler for Application {
fn window_event(&mut self, _: &ActiveEventLoop, _: WindowId, event: WindowEvent) {
let window = match &mut self.window {
Some(window) => window,
None => return,
};
let adapter = &mut window.adapter;
adapter.process_event(&window.window, &event);
match event {
WindowEvent::CloseRequested => {
self.window = None;
}
_ => (),
}
}
fn user_event(&mut self, _: &ActiveEventLoop, user_event: AccessKitEvent) {
let window = match &mut self.window {
Some(window) => window,
None => return,
};
let adapter = &mut window.adapter;
let state = &mut window.ui;
match user_event.window_event {
AccessKitWindowEvent::InitialTreeRequested => {
adapter.update_if_active(|| state.build_initial_tree());
}
_ => (),
}
}
fn resumed(&mut self, event_loop: &ActiveEventLoop) {
self.create_window(event_loop)
.expect("failed to create initial window");
}
fn about_to_wait(&mut self, event_loop: &ActiveEventLoop) {
if self.window.is_none() {
event_loop.exit();
}
}
}
fn main() -> Result<(), Box> {
let event_loop = EventLoop::with_user_event().build()?;
let mut state = Application::new(event_loop.create_proxy());
event_loop.run_app(&mut state).map_err(Into::into)
}
```