zenthra_core/element.rs
1// crates/zenthra-core/src/element.rs
2
3use crate::Id;
4use crate::rect::Rect;
5
6/// Represents the semantic role of a widget for accessibility and automation.
7/// This matches standard Web/ARIA roles but is tailored for Zenthra's native widgets.
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
9pub enum Role {
10 /// A top-level window.
11 Window,
12 /// A clickable button.
13 Button,
14 /// A navigational link.
15 Link,
16 /// A toggleable check box.
17 CheckBox,
18 /// A set of mutual exclusive options.
19 RadioButton,
20 /// A single-line text input.
21 TextInput,
22 /// A multi-line text editor.
23 TextArea,
24 /// A numeric range selector.
25 Slider,
26 /// Static text content.
27 Label,
28 /// A content heading.
29 Heading,
30 /// A collection of items.
31 List,
32 /// An item within a list.
33 ListItem,
34 /// A graphical asset.
35 Image,
36 /// A generic layout container (non-semantic by default).
37 Container,
38 /// A region that can be scrolled.
39 ScrollRegion,
40 /// A popup or contextual menu.
41 Menu,
42 /// A toggle switch.
43 Switch,
44}
45
46/// A node in the semantic/accessibility tree.
47/// This exists independently of the draw order and describes the "meaning" of the UI.
48#[derive(Debug, Clone, PartialEq)]
49pub struct SemanticNode {
50 /// The unique, persistent ID of the widget.
51 pub id: Id,
52 /// The semantic role of the widget.
53 pub role: Role,
54 /// The human-readable label or description (e.g. Button text).
55 pub label: Option<String>,
56 /// The screen-space bounding box.
57 pub rect: Rect,
58 /// The IDs of children nodes in the semantic hierarchy.
59 pub children: Vec<Id>,
60 /// Whether this node is currently focused by the keyboard.
61 pub focused: bool,
62 /// Whether this node is currently disabled (non-interactive).
63 pub disabled: bool,
64 /// Current numeric value (for sliders, progress bars, etc).
65 pub value: Option<f32>,
66 /// Minimum numeric value.
67 pub min_value: Option<f32>,
68 /// Maximum numeric value.
69 pub max_value: Option<f32>,
70}
71
72impl SemanticNode {
73 pub fn new(id: Id, role: Role, rect: Rect) -> Self {
74 Self {
75 id,
76 role,
77 label: None,
78 rect,
79 children: Vec::new(),
80 focused: false,
81 disabled: false,
82 value: None,
83 min_value: None,
84 max_value: None,
85 }
86 }
87
88 pub fn with_label(mut self, label: impl Into<String>) -> Self {
89 self.label = Some(label.into());
90 self
91 }
92
93 pub fn with_focus(mut self, focused: bool) -> Self {
94 self.focused = focused;
95 self
96 }
97
98 pub fn with_value(mut self, value: f32) -> Self {
99 self.value = Some(value);
100 self
101 }
102
103 pub fn with_min_value(mut self, min: f32) -> Self {
104 self.min_value = Some(min);
105 self
106 }
107
108 pub fn with_max_value(mut self, max: f32) -> Self {
109 self.max_value = Some(max);
110 self
111 }
112}