use envision::prelude::*;
struct ProgressBarApp;
#[derive(Clone)]
struct State {
download: ProgressBarState,
install: ProgressBarState,
verify: ProgressBarState,
}
#[derive(Clone, Debug)]
enum Msg {
AdvanceDownload,
AdvanceInstall,
CompleteVerify,
Quit,
}
impl App for ProgressBarApp {
type State = State;
type Message = Msg;
fn init() -> (State, Command<Msg>) {
let state = State {
download: ProgressBarState::with_label("Downloading..."),
install: ProgressBarState::with_label("Installing..."),
verify: ProgressBarState::with_label("Verifying..."),
};
(state, Command::none())
}
fn update(state: &mut State, msg: Msg) -> Command<Msg> {
match msg {
Msg::AdvanceDownload => {
ProgressBar::update(&mut state.download, ProgressBarMessage::Increment(0.35));
}
Msg::AdvanceInstall => {
ProgressBar::update(&mut state.install, ProgressBarMessage::SetProgress(0.6));
}
Msg::CompleteVerify => {
ProgressBar::update(&mut state.verify, ProgressBarMessage::Complete);
}
Msg::Quit => return Command::quit(),
}
Command::none()
}
fn view(state: &State, frame: &mut Frame) {
let theme = Theme::default();
let area = frame.area();
let chunks = Layout::vertical([
Constraint::Length(3),
Constraint::Length(3),
Constraint::Length(3),
Constraint::Min(0),
])
.split(area);
ProgressBar::view(
&state.download,
frame,
chunks[0],
&theme,
&ViewContext::default(),
);
ProgressBar::view(
&state.install,
frame,
chunks[1],
&theme,
&ViewContext::default(),
);
ProgressBar::view(
&state.verify,
frame,
chunks[2],
&theme,
&ViewContext::default(),
);
}
fn handle_event(event: &Event) -> Option<Msg> {
if let Some(key) = event.as_key() {
match key.code {
KeyCode::Char('q') | KeyCode::Esc => Some(Msg::Quit),
_ => None,
}
} else {
None
}
}
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut vt = Runtime::<ProgressBarApp, _>::virtual_terminal(50, 10)?;
println!("=== ProgressBar Example ===\n");
vt.tick()?;
println!("Initial state (all at 0%):");
println!("{}\n", vt.display());
vt.dispatch(Msg::AdvanceDownload);
vt.tick()?;
println!("After advancing download to 35%:");
println!("{}\n", vt.display());
vt.dispatch(Msg::AdvanceDownload);
vt.dispatch(Msg::AdvanceInstall);
vt.tick()?;
println!("After download 70%, install 60%:");
println!("{}\n", vt.display());
vt.dispatch(Msg::CompleteVerify);
vt.tick()?;
println!("After completing verification:");
println!("{}\n", vt.display());
Ok(())
}