#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
pub enum Role {
#[default]
Generic,
Window,
Group,
Navigation,
Text,
Heading,
Image,
Link,
Button,
CheckBox,
RadioButton,
Switch,
TextInput,
TextArea,
SearchInput,
Table,
Grid,
Row,
ColumnHeader,
Cell,
List,
ListItem,
Tree,
TreeItem,
ListBox,
Option,
Menu,
MenuItem,
MenuBar,
MenuItemCheckBox,
MenuItemRadio,
ComboBox,
Tooltip,
Status,
AlertDialog,
Slider,
Progress,
Tab,
TabList,
TabPanel,
Dialog,
Alert,
Separator,
}
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum SemanticAction {
Click,
Focus,
Blur,
Increment,
Decrement,
Expand,
Collapse,
SetValue,
ScrollIntoView,
}
#[derive(Clone, Debug, PartialEq)]
pub enum SemanticValue {
Text(String),
Number {
value: f64,
minimum: Option<f64>,
maximum: Option<f64>,
step: Option<f64>,
},
}
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
pub enum LiveRegion {
#[default]
Off,
Polite,
Assertive,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum Orientation {
Horizontal,
Vertical,
}
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct SemanticState {
pub protected: bool,
pub disabled: bool,
pub selected: bool,
pub multiselectable: bool,
pub checked: Option<CheckedState>,
pub pressed: Option<bool>,
pub expanded: Option<bool>,
pub required: bool,
pub read_only: bool,
pub invalid: bool,
pub modal: bool,
pub busy: bool,
}
#[derive(Clone, Debug, Default, PartialEq)]
pub struct Semantics {
pub role: Role,
pub label: Option<String>,
pub description: Option<String>,
pub value: Option<SemanticValue>,
pub state: SemanticState,
pub actions: Vec<SemanticAction>,
pub live: LiveRegion,
pub orientation: Option<Orientation>,
pub level: Option<u32>,
pub position_in_set: Option<u32>,
pub set_size: Option<u32>,
pub relations: crate::SemanticRelations,
pub grid: crate::GridPosition,
pub sort: Option<crate::SortDirection>,
pub popup: Option<crate::PopupKind>,
pub focus_policy: FocusPolicy,
}
#[derive(Clone, Debug, PartialEq)]
pub struct SemanticRequest {
pub target: crate::SemanticNodeId,
pub action: SemanticAction,
pub value: Option<SemanticValue>,
}
impl Semantics {
#[must_use]
pub const fn new(role: Role) -> Self {
Self {
role,
label: None,
description: None,
value: None,
state: SemanticState {
protected: false,
disabled: false,
selected: false,
multiselectable: false,
checked: None,
pressed: None,
expanded: None,
required: false,
read_only: false,
invalid: false,
modal: false,
busy: false,
},
actions: Vec::new(),
live: LiveRegion::Off,
orientation: None,
level: None,
position_in_set: None,
set_size: None,
relations: crate::SemanticRelations::new(),
grid: crate::GridPosition {
row_count: None,
column_count: None,
row_index: None,
column_index: None,
},
sort: None,
popup: None,
focus_policy: FocusPolicy::None,
}
}
#[must_use]
pub fn label(mut self, label: impl Into<String>) -> Self {
self.label = Some(label.into());
self
}
#[must_use]
pub fn description(mut self, description: impl Into<String>) -> Self {
self.description = Some(description.into());
self
}
#[must_use]
pub fn value(mut self, value: SemanticValue) -> Self {
self.value = Some(value);
self
}
#[must_use]
pub fn action(mut self, action: SemanticAction) -> Self {
if !self.actions.contains(&action) {
self.actions.push(action);
}
self
}
#[must_use]
pub fn state(mut self, state: SemanticState) -> Self {
self.state = state;
self
}
#[must_use]
pub const fn live(mut self, live: LiveRegion) -> Self {
self.live = live;
self
}
#[must_use]
pub const fn orientation(mut self, orientation: Orientation) -> Self {
self.orientation = Some(orientation);
self
}
#[must_use]
pub const fn level(mut self, level: u32) -> Self {
self.level = Some(level);
self
}
#[must_use]
pub const fn position_in_set(mut self, position: u32, size: u32) -> Self {
self.position_in_set = Some(position);
self.set_size = Some(size);
self
}
}
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
pub enum CheckedState {
#[default]
Unchecked,
Checked,
Mixed,
}
impl CheckedState {
#[must_use]
pub const fn toggled(self) -> Self {
match self {
Self::Checked => Self::Unchecked,
Self::Unchecked | Self::Mixed => Self::Checked,
}
}
}
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
pub enum FocusPolicy {
#[default]
None,
Programmatic,
TabStop,
}
impl FocusPolicy {
#[must_use]
pub const fn is_focusable(self) -> bool {
!matches!(self, Self::None)
}
#[must_use]
pub const fn is_tab_stop(self) -> bool {
matches!(self, Self::TabStop)
}
}