add new example: stopwatch (#503)

Co-authored-by: Mckol <mckol363@gmail.com>
This commit is contained in:
Tianyi Shi 2020-10-09 08:41:57 +06:00 committed by GitHub
parent ac06b3ac3a
commit c7c5f7955f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 92 additions and 0 deletions

View File

@ -94,6 +94,7 @@ Here are some cool applications using cursive:
* [fui](https://github.com/xliiv/fui): Add CLI & form interface to your program. * [fui](https://github.com/xliiv/fui): Add CLI & form interface to your program.
* [grin-tui](https://github.com/mimblewimble/grin): Minimal implementation of the MimbleWimble protocol. * [grin-tui](https://github.com/mimblewimble/grin): Minimal implementation of the MimbleWimble protocol.
* [ripasso](https://github.com/cortex/ripasso): A simple password manager written in Rust. * [ripasso](https://github.com/cortex/ripasso): A simple password manager written in Rust.
* [clock-cli](https://github.com/TianyiShi2001/clock-cli-rs): A clock with stopwatch and countdown timer functionalities
* [sudoku-tui](https://github.com/TianyiShi2001/sudoku-tui): Play sudoku on the command line. * [sudoku-tui](https://github.com/TianyiShi2001/sudoku-tui): Play sudoku on the command line.
## Goals ## Goals

View File

@ -0,0 +1,91 @@
//! A simple stopwatch implementation.
//! Also check out `clock-cli` (https://github.com/TianyiShi2001/cl!ock-cli-rs),
//! which aims to implement a fully-fledged clock with stopwatch, countdown
//! timer, and possibly more functionalities.
use cursive::traits::{Nameable, Resizable};
use cursive::views::{Button, Canvas, Dialog, LinearLayout};
use std::time::{Duration, Instant};
fn main() {
let mut siv = cursive::default();
siv.add_layer(
Dialog::new()
.title("Stopwatch")
.content(
LinearLayout::horizontal()
.child(
Canvas::new(Watch {
last_started: Instant::now(),
last_elapsed: Duration::default(),
running: true,
})
.with_draw(|s, printer| {
printer.print(
(0, 1),
&format!("{:.2?}", s.elapsed()),
);
})
.with_name("stopwatch")
.fixed_size((8, 3)),
)
.child(
LinearLayout::vertical()
.child(Button::new("Start", run(Watch::start)))
.child(Button::new("Pause", run(Watch::pause)))
.child(Button::new("Stop", run(Watch::stop))),
),
)
.button("Quit", |s| s.quit())
.h_align(cursive::align::HAlign::Center),
);
siv.set_fps(20);
siv.run();
}
struct Watch {
last_started: Instant,
last_elapsed: Duration,
running: bool,
}
impl Watch {
fn start(&mut self) {
self.running = true;
self.last_started = Instant::now();
}
fn elapsed(&self) -> Duration {
self.last_elapsed
+ if self.running {
Instant::now() - self.last_started
} else {
Duration::default()
}
}
fn pause(&mut self) {
self.last_elapsed = self.elapsed();
self.running = false;
}
fn stop(&mut self) {
self.running = false;
self.last_elapsed = Duration::default();
}
}
// Helper function to find the stopwatch view and run a closure on it.
fn run<F>(f: F) -> impl Fn(&mut cursive::Cursive)
where
F: Fn(&mut Watch),
{
move |s| {
s.call_on_name("stopwatch", |c: &mut Canvas<Watch>| {
f(c.state_mut());
});
}
}