Skip to main content

18_progress_bar/
18_progress_bar.rs

1//! Example 18: Progress Bar
2//!
3//! Demonstrates the progress bar widget with various configurations:
4//! - Basic progress bar
5//! - Progress bar with label
6//! - Progress bar without percentage
7//! - Custom characters
8//! - Animated progress
9//!
10//! Run with: cargo run -p telex-tui --example 18_progress_bar
11
12use 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        // F1 toggles help
29        cx.use_command(
30            KeyBinding::key(KeyCode::F(1)),
31            with!(show_help => move || show_help.update(|v| *v = !*v)),
32        );
33
34        // Animated progress value using stream
35        let progress = stream!(cx, || {
36            (0u64..).map(|i| {
37                if i > 0 {
38                    std::thread::sleep(Duration::from_millis(50));
39                }
40                // Progress cycles from 0.0 to 1.0
41                (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            // Basic progress bar
52            .child(View::text("Basic (75%):"))
53            .child(View::progress_bar().value(0.75).build())
54            // With label
55            .child(View::text("With label (50%):"))
56            .child(View::progress_bar().value(0.5).label("Loading").build())
57            // Without percentage
58            .child(View::text("No percentage (33%):"))
59            .child(
60                View::progress_bar()
61                    .value(0.33)
62                    .show_percentage(false)
63                    .build(),
64            )
65            // Fixed width
66            .child(View::text("Fixed width (20 chars, 60%):"))
67            .child(View::progress_bar().value(0.6).width(20).build())
68            // Custom characters
69            .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            // Another style
79            .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            // Animated progress
89            .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}