use super::*;
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub(crate) enum StateKey {
Indexed(usize),
Named(&'static str),
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct State<T> {
key: StateKey,
_marker: std::marker::PhantomData<T>,
}
impl<T: 'static> State<T> {
pub(crate) fn from_idx(idx: usize) -> Self {
Self {
key: StateKey::Indexed(idx),
_marker: std::marker::PhantomData,
}
}
pub(crate) fn from_named(id: &'static str) -> Self {
Self {
key: StateKey::Named(id),
_marker: std::marker::PhantomData,
}
}
pub fn get<'a>(&self, ui: &'a Context) -> &'a T {
match self.key {
StateKey::Indexed(idx) => {
ui.hook_states[idx].downcast_ref::<T>().unwrap_or_else(|| {
panic!(
"use_state type mismatch at hook index {} — expected {}",
idx,
std::any::type_name::<T>()
)
})
}
StateKey::Named(id) => ui
.named_states
.get(id)
.unwrap_or_else(|| {
panic!(
"use_state_named: no entry for id {:?} — was use_state_named called?",
id
)
})
.downcast_ref::<T>()
.unwrap_or_else(|| {
panic!(
"use_state_named type mismatch for id {:?} — expected {}",
id,
std::any::type_name::<T>()
)
}),
}
}
pub fn get_mut<'a>(&self, ui: &'a mut Context) -> &'a mut T {
match self.key {
StateKey::Indexed(idx) => {
ui.hook_states[idx].downcast_mut::<T>().unwrap_or_else(|| {
panic!(
"use_state type mismatch at hook index {} — expected {}",
idx,
std::any::type_name::<T>()
)
})
}
StateKey::Named(id) => ui
.named_states
.get_mut(id)
.unwrap_or_else(|| {
panic!(
"use_state_named: no entry for id {:?} — was use_state_named called?",
id
)
})
.downcast_mut::<T>()
.unwrap_or_else(|| {
panic!(
"use_state_named type mismatch for id {:?} — expected {}",
id,
std::any::type_name::<T>()
)
}),
}
}
}
#[derive(Debug, Clone, Default)]
#[must_use = "Response contains interaction state — check .clicked, .hovered, or .changed"]
pub struct Response {
pub clicked: bool,
pub hovered: bool,
pub changed: bool,
pub focused: bool,
pub rect: Rect,
}
impl Response {
pub fn none() -> Self {
Self::default()
}
}