Skip to main content

slt/context/
state.rs

1/// Handle to state created by `use_state()`. Access via `.get(ui)` / `.get_mut(ui)`.
2#[derive(Debug, Copy, Clone, PartialEq, Eq)]
3pub struct State<T> {
4    idx: usize,
5    _marker: std::marker::PhantomData<T>,
6}
7
8impl<T: 'static> State<T> {
9    /// Read the current value.
10    pub fn get<'a>(&self, ui: &'a Context) -> &'a T {
11        ui.hook_states[self.idx]
12            .downcast_ref::<T>()
13            .unwrap_or_else(|| {
14                panic!(
15                    "use_state type mismatch at hook index {} — expected {}",
16                    self.idx,
17                    std::any::type_name::<T>()
18                )
19            })
20    }
21
22    /// Mutably access the current value.
23    pub fn get_mut<'a>(&self, ui: &'a mut Context) -> &'a mut T {
24        ui.hook_states[self.idx]
25            .downcast_mut::<T>()
26            .unwrap_or_else(|| {
27                panic!(
28                    "use_state type mismatch at hook index {} — expected {}",
29                    self.idx,
30                    std::any::type_name::<T>()
31                )
32            })
33    }
34}
35
36/// Interaction response returned by all widgets.
37///
38/// Container methods return a [`Response`]. Check `.clicked`, `.changed`, etc.
39/// to react to user interactions.
40///
41/// # Examples
42///
43/// ```
44/// # use slt::*;
45/// # TestBackend::new(80, 24).render(|ui| {
46/// let r = ui.row(|ui| {
47///     ui.text("Save");
48/// });
49/// if r.clicked {
50///     // handle save
51/// }
52/// # });
53/// ```
54#[derive(Debug, Clone, Default)]
55#[must_use = "Response contains interaction state — check .clicked, .hovered, or .changed"]
56pub struct Response {
57    /// Whether the widget was clicked this frame.
58    pub clicked: bool,
59    /// Whether the mouse is hovering over the widget.
60    pub hovered: bool,
61    /// Whether the widget's value changed this frame.
62    pub changed: bool,
63    /// Whether the widget currently has keyboard focus.
64    pub focused: bool,
65    /// The rectangle the widget occupies after layout.
66    pub rect: Rect,
67}
68
69impl Response {
70    /// Create a Response with all fields false/default.
71    pub fn none() -> Self {
72        Self::default()
73    }
74}