Skip to main content

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}