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