use serde::{Deserialize, Serialize};
use crate::element::ElementData;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[repr(u8)]
pub enum EventType {
FocusChanged,
ValueChanged,
NameChanged,
StateChanged,
StructureChanged,
WindowOpened,
WindowClosed,
WindowActivated,
WindowDeactivated,
SelectionChanged,
MenuOpened,
MenuClosed,
Alert,
TextChanged,
}
#[derive(Debug, Clone)]
pub struct Event {
pub event_type: EventType,
pub app_name: String,
pub app_pid: u32,
pub target: Option<ElementData>,
pub state_flag: Option<StateFlag>,
pub state_value: Option<bool>,
pub text_change: Option<TextChangeData>,
pub timestamp: std::time::Instant,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TextChangeData {
pub change_type: TextChangeType,
pub position: Option<u32>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum TextChangeType {
Insert,
Delete,
Replace,
Unknown,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[repr(u8)]
pub enum StateFlag {
Enabled,
Visible,
Focused,
Checked,
Selected,
Expanded,
Editable,
Focusable,
Modal,
Required,
Busy,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum ElementState {
Attached,
Detached,
Visible,
Hidden,
Enabled,
Disabled,
Focused,
Unfocused,
}
impl ElementState {
pub fn is_met(self, element: Option<&ElementData>) -> bool {
match self {
Self::Attached => element.is_some(),
Self::Detached => element.is_none(),
Self::Visible => element.is_some_and(|e| e.states.visible),
Self::Hidden => element.is_none() || element.is_some_and(|e| !e.states.visible),
Self::Enabled => element.is_some_and(|e| e.states.enabled),
Self::Disabled => element.is_some_and(|e| !e.states.enabled),
Self::Focused => element.is_some_and(|e| e.states.focused),
Self::Unfocused => element.is_some_and(|e| !e.states.focused),
}
}
pub fn is_absence_state(self) -> bool {
matches!(self, Self::Detached | Self::Hidden)
}
}