1use crossterm::event::KeyCode;
9use crossterm::style::Color;
10use telex::prelude::*;
11
12telex::require_api!(0, 2);
13
14fn main() {
15 telex::run(App).unwrap();
16}
17
18struct App;
19
20impl Component for App {
21 fn render(&self, cx: Scope) -> View {
22 let show_help = state!(cx, || false);
23
24 cx.use_command(
25 KeyBinding::key(KeyCode::F(1)),
26 with!(show_help => move || show_help.update(|v| *v = !*v)),
27 );
28
29 let r = state!(cx, || 128.0);
30 let g = state!(cx, || 0.0);
31 let b = state!(cx, || 255.0);
32
33 let rv = r.get() as u8;
34 let gv = g.get() as u8;
35 let bv = b.get() as u8;
36
37 View::vstack()
38 .spacing(1)
39 .child(View::styled_text("RGB Color Mixer").bold().build())
40 .child(
41 View::slider()
42 .min(0.0)
43 .max(255.0)
44 .step(1.0)
45 .value(r.get())
46 .label(&format!("Red: {:>3}", rv))
47 .color(Color::Rgb { r: 255, g: 80, b: 80 })
48 .on_change(with!(r => move |v: f64| r.set(v)))
49 .build(),
50 )
51 .child(
52 View::slider()
53 .min(0.0)
54 .max(255.0)
55 .step(1.0)
56 .value(g.get())
57 .label(&format!("Green: {:>3}", gv))
58 .color(Color::Rgb { r: 80, g: 255, b: 80 })
59 .on_change(with!(g => move |v: f64| g.set(v)))
60 .build(),
61 )
62 .child(
63 View::slider()
64 .min(0.0)
65 .max(255.0)
66 .step(1.0)
67 .value(b.get())
68 .label(&format!("Blue: {:>3}", bv))
69 .color(Color::Rgb { r: 80, g: 80, b: 255 })
70 .on_change(with!(b => move |v: f64| b.set(v)))
71 .build(),
72 )
73 .child(
74 View::styled_text("████████████████")
75 .color(Color::Rgb { r: rv, g: gv, b: bv })
76 .bold()
77 .build(),
78 )
79 .child(View::styled_text(format!("#{:02X}{:02X}{:02X}", rv, gv, bv)).bold().build())
80 .child(View::styled_text("Tab: switch slider • Left/Right: adjust • F1: help • Ctrl+Q: quit").dim().build())
81 .child(
82 View::modal()
83 .visible(show_help.get())
84 .title("Example 35: Slider")
85 .on_dismiss(with!(show_help => move || show_help.set(false)))
86 .child(
87 View::vstack()
88 .child(View::styled_text("What you're seeing").bold().build())
89 .child(View::text("• Three sliders for R, G, B"))
90 .child(View::text("• Color preview swatch"))
91 .child(View::text("• Live hex code"))
92 .child(View::gap(1))
93 .child(View::styled_text("Key concepts").bold().build())
94 .child(View::text("• View::slider() with min/max/step"))
95 .child(View::text("• on_change callback with f64"))
96 .child(View::text("• Color::Rgb for true color"))
97 .child(View::gap(1))
98 .child(View::styled_text("Try this").bold().build())
99 .child(View::text("• Tab between sliders"))
100 .child(View::text("• Left/Right arrows to adjust"))
101 .child(View::text("• Watch the preview change"))
102 .child(View::gap(1))
103 .child(View::styled_text("Next up").bold().build())
104 .child(View::text("-> 36_reducer: state machine wizard"))
105 .child(View::gap(1))
106 .child(View::styled_text("Press Escape to close").dim().build())
107 .build(),
108 )
109 .build(),
110 )
111 .build()
112 }
113}