fltk_accesskit/
accessible.rs

1use accesskit::{Action, Affine, Node, NodeId, Rect, Role, TextPosition, TextSelection, Toggled};
2use fltk::{enums::*, prelude::*, *};
3
4pub trait Accessible {
5    fn make_node(&self, children: &[NodeId]) -> (NodeId, Node);
6}
7
8fn node_widget_common(builder: &mut Node, wid: &impl WidgetExt, children: &[NodeId]) -> NodeId {
9    let node_id = NodeId(wid.as_widget_ptr() as usize as u64);
10    if wid.parent().is_some() && wid.as_window().is_none() {
11        builder.set_bounds(Rect {
12            x0: wid.x() as f64,
13            y0: wid.y() as f64,
14            x1: (wid.w() + wid.x()) as f64,
15            y1: (wid.h() + wid.y()) as f64,
16        });
17    } else {
18        builder.set_bounds(Rect {
19            x0: 0.0,
20            y0: 0.0,
21            x1: wid.w() as f64,
22            y1: wid.h() as f64,
23        });
24    }
25    builder.set_label(&*wid.label());
26    if wid.trigger().contains(CallbackTrigger::Release) {
27        builder.add_action(Action::Click);
28    }
29    if wid.takes_events() && wid.has_visible_focus() {
30        builder.add_action(Action::Focus);
31    }
32    for c in children {
33        builder.push_child(*c);
34    }
35    node_id
36}
37
38impl Accessible for button::Button {
39    fn make_node(&self, children: &[NodeId]) -> (NodeId, Node) {
40        let mut builder = Node::new(Role::Button);
41        let id = node_widget_common(&mut builder, self, children);
42        (id, builder)
43    }
44}
45
46impl Accessible for button::RadioButton {
47    fn make_node(&self, children: &[NodeId]) -> (NodeId, Node) {
48        let mut builder = Node::new(Role::RadioButton);
49        builder.set_toggled(if self.value() {
50            Toggled::True
51        } else {
52            Toggled::False
53        });
54        let id = node_widget_common(&mut builder, self, children);
55        (id, builder)
56    }
57}
58
59impl Accessible for button::RadioRoundButton {
60    fn make_node(&self, children: &[NodeId]) -> (NodeId, Node) {
61        let mut builder = Node::new(Role::RadioButton);
62        builder.set_toggled(if self.value() {
63            Toggled::True
64        } else {
65            Toggled::False
66        });
67        let id = node_widget_common(&mut builder, self, children);
68        (id, builder)
69    }
70}
71
72impl Accessible for button::CheckButton {
73    fn make_node(&self, children: &[NodeId]) -> (NodeId, Node) {
74        let mut builder = Node::new(Role::CheckBox);
75        builder.set_toggled(if self.value() {
76            Toggled::True
77        } else {
78            Toggled::False
79        });
80        let id = node_widget_common(&mut builder, self, children);
81        (id, builder)
82    }
83}
84
85impl Accessible for button::ToggleButton {
86    fn make_node(&self, children: &[NodeId]) -> (NodeId, Node) {
87        let mut builder = Node::new(Role::RadioButton);
88        builder.set_toggled(if self.value() {
89            Toggled::True
90        } else {
91            Toggled::False
92        });
93        let id = node_widget_common(&mut builder, self, children);
94        (id, builder)
95    }
96}
97
98impl Accessible for window::Window {
99    fn make_node(&self, children: &[NodeId]) -> (NodeId, Node) {
100        let mut builder = Node::new(Role::Window);
101        builder.set_transform(Affine::scale(app::screen_scale(0) as f64));
102        let id = node_widget_common(&mut builder, self, children);
103        (id, builder)
104    }
105}
106
107impl Accessible for frame::Frame {
108    fn make_node(&self, children: &[NodeId]) -> (NodeId, Node) {
109        let mut builder = Node::default();
110        let id = node_widget_common(&mut builder, self, children);
111        if self.image().is_some() {
112            builder.set_role(Role::Image);
113        } else {
114            builder.set_role(Role::Label);
115        }
116        (id, builder)
117    }
118}
119
120impl Accessible for output::Output {
121    fn make_node(&self, children: &[NodeId]) -> (NodeId, Node) {
122        let mut builder = Node::new(Role::Label);
123        builder.set_value(&*self.value());
124        let id = node_widget_common(&mut builder, self, children);
125        (id, builder)
126    }
127}
128
129impl Accessible for input::Input {
130    fn make_node(&self, children: &[NodeId]) -> (NodeId, Node) {
131        let mut builder = Node::new(Role::TextInput);
132        builder.set_value(&*self.value());
133        builder.add_action(Action::Focus);
134        let id = node_widget_common(&mut builder, self, children);
135        (id, builder)
136    }
137}
138
139impl Accessible for input::IntInput {
140    fn make_node(&self, children: &[NodeId]) -> (NodeId, Node) {
141        let mut builder = Node::new(Role::TextInput);
142        builder.set_value(&*self.value());
143        builder.add_action(Action::Focus);
144        let id = node_widget_common(&mut builder, self, children);
145        (id, builder)
146    }
147}
148
149impl Accessible for input::FloatInput {
150    fn make_node(&self, children: &[NodeId]) -> (NodeId, Node) {
151        let mut builder = Node::new(Role::TextInput);
152        builder.set_value(&*self.value());
153        builder.add_action(Action::Focus);
154        let id = node_widget_common(&mut builder, self, children);
155        (id, builder)
156    }
157}
158
159impl Accessible for input::MultilineInput {
160    fn make_node(&self, children: &[NodeId]) -> (NodeId, Node) {
161        let mut builder = Node::new(Role::MultilineTextInput);
162        builder.set_value(&*self.value());
163        builder.add_action(Action::Focus);
164        let id = node_widget_common(&mut builder, self, children);
165        (id, builder)
166    }
167}
168
169impl Accessible for output::MultilineOutput {
170    fn make_node(&self, children: &[NodeId]) -> (NodeId, Node) {
171        let mut builder = Node::new(Role::Paragraph);
172        builder.set_value(&*self.value());
173        let id = node_widget_common(&mut builder, self, children);
174        (id, builder)
175    }
176}
177
178impl Accessible for text::TextDisplay {
179    fn make_node(&self, children: &[NodeId]) -> (NodeId, Node) {
180        let mut builder = Node::new(Role::Paragraph);
181        let id = node_widget_common(&mut builder, self, children);
182        if let Some(buf) = self.buffer() {
183            builder.set_value(&*buf.text());
184            if let Some((s, e)) = buf.selection_position() {
185                builder.set_text_selection(TextSelection {
186                    anchor: TextPosition {
187                        node: id,
188                        character_index: s as _,
189                    },
190                    focus: TextPosition {
191                        node: id,
192                        character_index: e as _,
193                    },
194                });
195            }
196        }
197        (id, builder)
198    }
199}
200
201impl Accessible for text::TextEditor {
202    fn make_node(&self, children: &[NodeId]) -> (NodeId, Node) {
203        let mut builder = Node::new(Role::TextInput);
204        builder.add_action(Action::Focus);
205        let id = node_widget_common(&mut builder, self, children);
206        if let Some(buf) = self.buffer() {
207            builder.set_value(&*buf.text());
208            if let Some((s, e)) = buf.selection_position() {
209                builder.set_text_selection(TextSelection {
210                    anchor: TextPosition {
211                        node: id,
212                        character_index: s as _,
213                    },
214                    focus: TextPosition {
215                        node: id,
216                        character_index: e as _,
217                    },
218                });
219            }
220        }
221        (id, builder)
222    }
223}
224
225#[allow(deprecated)]
226impl Accessible for text::SimpleTerminal {
227    fn make_node(&self, children: &[NodeId]) -> (NodeId, Node) {
228        let mut builder = Node::new(Role::Terminal);
229        builder.add_action(Action::Focus);
230        let id = node_widget_common(&mut builder, self, children);
231        if let Some(buf) = self.buffer() {
232            builder.set_value(&*buf.text());
233            if let Some((s, e)) = buf.selection_position() {
234                builder.set_text_selection(TextSelection {
235                    anchor: TextPosition {
236                        node: id,
237                        character_index: s as _,
238                    },
239                    focus: TextPosition {
240                        node: id,
241                        character_index: e as _,
242                    },
243                });
244            }
245        }
246        (id, builder)
247    }
248}
249
250impl Accessible for valuator::Slider {
251    fn make_node(&self, children: &[NodeId]) -> (NodeId, Node) {
252        let mut builder = Node::new(Role::Slider);
253        builder.set_numeric_value(self.value());
254        builder.set_min_numeric_value(self.minimum());
255        builder.set_max_numeric_value(self.maximum());
256        builder.set_numeric_value_step(self.step());
257        builder.add_action(Action::SetValue);
258        let id = node_widget_common(&mut builder, self, children);
259        (id, builder)
260    }
261}
262
263impl Accessible for valuator::NiceSlider {
264    fn make_node(&self, children: &[NodeId]) -> (NodeId, Node) {
265        let mut builder = Node::new(Role::Slider);
266        builder.set_numeric_value(self.value());
267        builder.set_min_numeric_value(self.minimum());
268        builder.set_max_numeric_value(self.maximum());
269        builder.set_numeric_value_step(self.step());
270        builder.add_action(Action::SetValue);
271        let id = node_widget_common(&mut builder, self, children);
272        (id, builder)
273    }
274}
275
276impl Accessible for valuator::ValueSlider {
277    fn make_node(&self, children: &[NodeId]) -> (NodeId, Node) {
278        let mut builder = Node::new(Role::Slider);
279        builder.set_numeric_value(self.value());
280        builder.set_min_numeric_value(self.minimum());
281        builder.set_max_numeric_value(self.maximum());
282        builder.set_numeric_value_step(self.step());
283        builder.add_action(Action::SetValue);
284        let id = node_widget_common(&mut builder, self, children);
285        (id, builder)
286    }
287}
288
289impl Accessible for valuator::FillSlider {
290    fn make_node(&self, children: &[NodeId]) -> (NodeId, Node) {
291        let mut builder = Node::new(Role::Slider);
292        builder.set_numeric_value(self.value());
293        builder.set_min_numeric_value(self.minimum());
294        builder.set_max_numeric_value(self.maximum());
295        builder.set_numeric_value_step(self.step());
296        builder.add_action(Action::SetValue);
297        let id = node_widget_common(&mut builder, self, children);
298        (id, builder)
299    }
300}
301
302impl Accessible for valuator::HorSlider {
303    fn make_node(&self, children: &[NodeId]) -> (NodeId, Node) {
304        let mut builder = Node::new(Role::Slider);
305        builder.set_numeric_value(self.value());
306        builder.set_min_numeric_value(self.minimum());
307        builder.set_max_numeric_value(self.maximum());
308        builder.set_numeric_value_step(self.step());
309        builder.add_action(Action::SetValue);
310        let id = node_widget_common(&mut builder, self, children);
311        (id, builder)
312    }
313}
314
315impl Accessible for valuator::HorFillSlider {
316    fn make_node(&self, children: &[NodeId]) -> (NodeId, Node) {
317        let mut builder = Node::new(Role::Slider);
318        builder.set_numeric_value(self.value());
319        builder.set_min_numeric_value(self.minimum());
320        builder.set_max_numeric_value(self.maximum());
321        builder.set_numeric_value_step(self.step());
322        builder.add_action(Action::SetValue);
323        let id = node_widget_common(&mut builder, self, children);
324        (id, builder)
325    }
326}
327
328impl Accessible for valuator::HorNiceSlider {
329    fn make_node(&self, children: &[NodeId]) -> (NodeId, Node) {
330        let mut builder = Node::new(Role::Slider);
331        builder.set_numeric_value(self.value());
332        builder.set_min_numeric_value(self.minimum());
333        builder.set_max_numeric_value(self.maximum());
334        builder.set_numeric_value_step(self.step());
335        builder.add_action(Action::SetValue);
336        let id = node_widget_common(&mut builder, self, children);
337        (id, builder)
338    }
339}
340
341impl Accessible for valuator::HorValueSlider {
342    fn make_node(&self, children: &[NodeId]) -> (NodeId, Node) {
343        let mut builder = Node::new(Role::Slider);
344        builder.set_numeric_value(self.value());
345        builder.set_min_numeric_value(self.minimum());
346        builder.set_max_numeric_value(self.maximum());
347        builder.set_numeric_value_step(self.step());
348        builder.add_action(Action::SetValue);
349        let id = node_widget_common(&mut builder, self, children);
350        (id, builder)
351    }
352}
353
354impl Accessible for valuator::Dial {
355    fn make_node(&self, children: &[NodeId]) -> (NodeId, Node) {
356        let mut builder = Node::new(Role::Slider);
357        builder.set_numeric_value(self.value());
358        builder.set_min_numeric_value(self.minimum());
359        builder.set_max_numeric_value(self.maximum());
360        builder.set_numeric_value_step(self.step());
361        builder.add_action(Action::SetValue);
362        let id = node_widget_common(&mut builder, self, children);
363        (id, builder)
364    }
365}
366
367impl Accessible for valuator::FillDial {
368    fn make_node(&self, children: &[NodeId]) -> (NodeId, Node) {
369        let mut builder = Node::new(Role::Slider);
370        builder.set_numeric_value(self.value());
371        builder.set_min_numeric_value(self.minimum());
372        builder.set_max_numeric_value(self.maximum());
373        builder.set_numeric_value_step(self.step());
374        builder.add_action(Action::SetValue);
375        let id = node_widget_common(&mut builder, self, children);
376        (id, builder)
377    }
378}
379
380impl Accessible for valuator::LineDial {
381    fn make_node(&self, children: &[NodeId]) -> (NodeId, Node) {
382        let mut builder = Node::new(Role::Slider);
383        builder.set_numeric_value(self.value());
384        builder.set_min_numeric_value(self.minimum());
385        builder.set_max_numeric_value(self.maximum());
386        builder.set_numeric_value_step(self.step());
387        builder.add_action(Action::SetValue);
388        let id = node_widget_common(&mut builder, self, children);
389        (id, builder)
390    }
391}
392
393impl Accessible for valuator::Counter {
394    fn make_node(&self, children: &[NodeId]) -> (NodeId, Node) {
395        let mut builder = Node::new(Role::Slider);
396        builder.set_numeric_value(self.value());
397        builder.set_min_numeric_value(self.minimum());
398        builder.set_max_numeric_value(self.maximum());
399        builder.set_numeric_value_step(self.step());
400        builder.add_action(Action::SetValue);
401        let id = node_widget_common(&mut builder, self, children);
402        (id, builder)
403    }
404}
405
406impl Accessible for valuator::Roller {
407    fn make_node(&self, children: &[NodeId]) -> (NodeId, Node) {
408        let mut builder = Node::new(Role::Slider);
409        builder.set_numeric_value(self.value());
410        builder.set_min_numeric_value(self.minimum());
411        builder.set_max_numeric_value(self.maximum());
412        builder.set_numeric_value_step(self.step());
413        builder.add_action(Action::SetValue);
414        let id = node_widget_common(&mut builder, self, children);
415        (id, builder)
416    }
417}
418
419impl Accessible for valuator::ValueInput {
420    fn make_node(&self, children: &[NodeId]) -> (NodeId, Node) {
421        let mut builder = Node::new(Role::Slider);
422        builder.set_numeric_value(self.value());
423        builder.set_min_numeric_value(self.minimum());
424        builder.set_max_numeric_value(self.maximum());
425        builder.set_numeric_value_step(self.step());
426        builder.add_action(Action::SetValue);
427        let id = node_widget_common(&mut builder, self, children);
428        (id, builder)
429    }
430}
431
432impl Accessible for valuator::ValueOutput {
433    fn make_node(&self, children: &[NodeId]) -> (NodeId, Node) {
434        let mut builder = Node::new(Role::Slider);
435        builder.set_numeric_value(self.value());
436        builder.set_min_numeric_value(self.minimum());
437        builder.set_max_numeric_value(self.maximum());
438        builder.set_numeric_value_step(self.step());
439        builder.add_action(Action::SetValue);
440        let id = node_widget_common(&mut builder, self, children);
441        (id, builder)
442    }
443}
444
445impl Accessible for valuator::Scrollbar {
446    fn make_node(&self, children: &[NodeId]) -> (NodeId, Node) {
447        let mut builder = Node::new(Role::ScrollBar);
448        builder.set_numeric_value(self.value());
449        builder.set_min_numeric_value(self.minimum());
450        builder.set_max_numeric_value(self.maximum());
451        builder.set_numeric_value_step(self.step());
452        let id = node_widget_common(&mut builder, self, children);
453        (id, builder)
454    }
455}
456
457impl Accessible for menu::MenuBar {
458    fn make_node(&self, children: &[NodeId]) -> (NodeId, Node) {
459        let mut builder = Node::new(Role::MenuBar);
460        let id = node_widget_common(&mut builder, self, children);
461        (id, builder)
462    }
463}
464
465impl Accessible for menu::Choice {
466    fn make_node(&self, children: &[NodeId]) -> (NodeId, Node) {
467        let mut builder = Node::new(Role::MenuListPopup);
468        let id = node_widget_common(&mut builder, self, children);
469        (id, builder)
470    }
471}
472
473impl Accessible for table::Table {
474    fn make_node(&self, children: &[NodeId]) -> (NodeId, Node) {
475        let mut builder = Node::new(Role::Table);
476        let id = node_widget_common(&mut builder, self, children);
477        (id, builder)
478    }
479}
480
481impl Accessible for tree::Tree {
482    fn make_node(&self, children: &[NodeId]) -> (NodeId, Node) {
483        let mut builder = Node::new(Role::Tree);
484        let id = node_widget_common(&mut builder, self, children);
485        (id, builder)
486    }
487}
488
489impl Accessible for group::Scroll {
490    fn make_node(&self, children: &[NodeId]) -> (NodeId, Node) {
491        let mut builder = Node::new(Role::ScrollView);
492        builder.add_action(Action::ScrollDown);
493        builder.add_action(Action::ScrollUp);
494        let id = node_widget_common(&mut builder, self, children);
495        (id, builder)
496    }
497}
498
499impl Accessible for group::Flex {
500    fn make_node(&self, children: &[NodeId]) -> (NodeId, Node) {
501        let mut builder = Node::new(Role::Group);
502        let id = node_widget_common(&mut builder, self, children);
503        (id, builder)
504    }
505}
506
507impl Accessible for group::Group {
508    fn make_node(&self, children: &[NodeId]) -> (NodeId, Node) {
509        let mut builder = Node::new(Role::Group);
510        let id = node_widget_common(&mut builder, self, children);
511        (id, builder)
512    }
513}
514
515impl Accessible for misc::Progress {
516    fn make_node(&self, children: &[NodeId]) -> (NodeId, Node) {
517        let mut builder = Node::new(Role::ProgressIndicator);
518        builder.set_numeric_value(self.value());
519        builder.set_min_numeric_value(self.minimum());
520        builder.set_max_numeric_value(self.maximum());
521        let id = node_widget_common(&mut builder, self, children);
522        (id, builder)
523    }
524}