18_progress_bar/
18_progress_bar.rs1use crossterm::event::KeyCode;
13use std::time::Duration;
14use telex::prelude::*;
15
16telex::require_api!(0, 2);
17
18fn main() {
19 telex::run_with_theme(App, telex::theme::Theme::nord()).unwrap();
20}
21
22struct App;
23
24impl Component for App {
25 fn render(&self, cx: Scope) -> View {
26 let show_help = state!(cx, || false);
27
28 cx.use_command(
30 KeyBinding::key(KeyCode::F(1)),
31 with!(show_help => move || show_help.update(|v| *v = !*v)),
32 );
33
34 let progress = stream!(cx, || {
36 (0u64..).map(|i| {
37 if i > 0 {
38 std::thread::sleep(Duration::from_millis(50));
39 }
40 (i % 100) as f32 / 100.0
42 })
43 });
44
45 let current_progress = progress.get();
46
47 View::vstack()
48 .spacing(1)
49 .child(View::styled_text("Progress Bar Examples").bold().build())
50 .child(View::text(""))
51 .child(View::text("Basic (75%):"))
53 .child(View::progress_bar().value(0.75).build())
54 .child(View::text("With label (50%):"))
56 .child(View::progress_bar().value(0.5).label("Loading").build())
57 .child(View::text("No percentage (33%):"))
59 .child(
60 View::progress_bar()
61 .value(0.33)
62 .show_percentage(false)
63 .build(),
64 )
65 .child(View::text("Fixed width (20 chars, 60%):"))
67 .child(View::progress_bar().value(0.6).width(20).build())
68 .child(View::text("Custom characters (80%):"))
70 .child(
71 View::progress_bar()
72 .value(0.8)
73 .filled_char('=')
74 .empty_char('-')
75 .width(20)
76 .build(),
77 )
78 .child(View::text("Block style (65%):"))
80 .child(
81 View::progress_bar()
82 .value(0.65)
83 .filled_char('#')
84 .empty_char('.')
85 .width(25)
86 .build(),
87 )
88 .child(View::text("Animated (loops 0-100%):"))
90 .child(
91 View::progress_bar()
92 .value(current_progress)
93 .label("Progress")
94 .build(),
95 )
96 .child(View::text(""))
97 .child(View::styled_text("F1 help • Ctrl+Q quit").dim().build())
98 .child(
99 View::modal()
100 .visible(show_help.get())
101 .title("Example 18: Progress Bar")
102 .on_dismiss(with!(show_help => move || show_help.set(false)))
103 .child(
104 View::vstack()
105 .child(View::styled_text("What you're seeing").bold().build())
106 .child(View::text("• Progress bars with various styles"))
107 .child(View::text("• Animated progress using stream!() macro"))
108 .child(View::text("• Custom fill and empty characters"))
109 .child(View::gap(1))
110 .child(View::styled_text("Key concepts").bold().build())
111 .child(View::text("• View::progress_bar() creates bars"))
112 .child(View::text("• .value(0.0 to 1.0) sets progress"))
113 .child(View::text("• .label() adds text label"))
114 .child(View::text("• .filled_char() / .empty_char() customize"))
115 .child(View::gap(1))
116 .child(View::styled_text("Try this").bold().build())
117 .child(View::text("• Watch the animated bar loop"))
118 .child(View::text("• Compare different bar styles"))
119 .child(View::gap(1))
120 .child(View::styled_text("Next up").bold().build())
121 .child(View::text("→ 19_status_bar: status bar widget"))
122 .child(View::gap(1))
123 .child(View::styled_text("Press Escape to close").dim().build())
124 .build(),
125 )
126 .build(),
127 )
128 .build()
129 }
130}