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