slt/context/widget.rs
1/// Trait for creating custom widgets.
2///
3/// Implement this trait to build reusable, composable widgets with full access
4/// to the [`Context`] API — focus, events, theming, layout, and mouse interaction.
5/// Choose `Self::Response` based on what the widget needs to report:
6/// `()` for pure display, `bool` for simple changed/not-changed signals,
7/// or [`Response`] for click/hover/focus-aware interaction.
8///
9/// # Examples
10///
11/// A simple rating widget:
12///
13/// ```no_run
14/// use slt::{Context, Widget, Color};
15///
16/// struct Rating {
17/// value: u8,
18/// max: u8,
19/// }
20///
21/// impl Rating {
22/// fn new(value: u8, max: u8) -> Self {
23/// Self { value, max }
24/// }
25/// }
26///
27/// impl Widget for Rating {
28/// type Response = bool;
29///
30/// fn ui(&mut self, ui: &mut Context) -> bool {
31/// let focused = ui.register_focusable();
32/// let mut changed = false;
33///
34/// if focused {
35/// if ui.key('+') && self.value < self.max {
36/// self.value += 1;
37/// changed = true;
38/// }
39/// if ui.key('-') && self.value > 0 {
40/// self.value -= 1;
41/// changed = true;
42/// }
43/// }
44///
45/// let stars: String = (0..self.max).map(|i| {
46/// if i < self.value { '★' } else { '☆' }
47/// }).collect();
48///
49/// let color = if focused { Color::Yellow } else { Color::White };
50/// ui.styled(stars, slt::Style::new().fg(color));
51///
52/// changed
53/// }
54/// }
55///
56/// fn main() -> std::io::Result<()> {
57/// let mut rating = Rating::new(3, 5);
58/// slt::run(|ui| {
59/// if ui.key('q') { ui.quit(); }
60/// ui.text("Rate this:");
61/// ui.widget(&mut rating);
62/// })
63/// }
64/// ```
65pub trait Widget {
66 /// The value returned after rendering. Use `()` for widgets with no return,
67 /// `bool` for widgets that report changes, or [`Response`] for click/hover.
68 type Response;
69
70 /// Render the widget into the given context.
71 ///
72 /// Use [`Context::register_focusable`] to participate in Tab focus cycling,
73 /// [`Context::key`] / [`Context::key_code`] to handle keyboard input,
74 /// and [`Context::interaction`] to detect clicks and hovers.
75 fn ui(&mut self, ctx: &mut Context) -> Self::Response;
76}