aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2021-12-04 19:48:28 -0500
committerJesse Luehrs <doy@tozt.net>2021-12-04 19:48:28 -0500
commitec6772bfd75aa2be226fe8763ab31a91b941cfc9 (patch)
treefc3f43ab664dd655dbc7ad7151cb62b1660e3352
parent7f9c724e1b7afe81e1c07a472db75f7c0592c123 (diff)
downloadttyrec-bin-ec6772bfd75aa2be226fe8763ab31a91b941cfc9.tar.gz
ttyrec-bin-ec6772bfd75aa2be226fe8763ab31a91b941cfc9.zip
add a bit of ui
-rw-r--r--src/bin/ttyplay/display.rs60
-rw-r--r--src/bin/ttyplay/event.rs4
-rw-r--r--src/bin/ttyplay/frames.rs4
-rw-r--r--src/bin/ttyplay/main.rs43
4 files changed, 99 insertions, 12 deletions
diff --git a/src/bin/ttyplay/display.rs b/src/bin/ttyplay/display.rs
index 4868154..32226e1 100644
--- a/src/bin/ttyplay/display.rs
+++ b/src/bin/ttyplay/display.rs
@@ -1,10 +1,36 @@
use textmode::Textmode as _;
-pub struct Display {}
+pub struct Display {
+ current_frame: usize,
+ total_frames: usize,
+ done_loading: bool,
+ paused: bool,
+}
impl Display {
pub fn new() -> Self {
- Self {}
+ Self {
+ current_frame: 0,
+ total_frames: 0,
+ done_loading: false,
+ paused: false,
+ }
+ }
+
+ pub fn current_frame(&mut self, idx: usize) {
+ self.current_frame = idx;
+ }
+
+ pub fn total_frames(&mut self, n: usize) {
+ self.total_frames = n;
+ }
+
+ pub fn done_loading(&mut self) {
+ self.done_loading = true;
+ }
+
+ pub fn paused(&mut self, paused: bool) {
+ self.paused = paused;
}
pub async fn render(
@@ -14,8 +40,38 @@ impl Display {
) -> anyhow::Result<()> {
output.clear();
output.move_to(0, 0);
+ output.reset_attributes();
output.write(&screen.contents_formatted());
+ let pos = output.screen().cursor_position();
+
+ output.move_to(0, 0);
+ output.reset_attributes();
+ output.set_fgcolor(textmode::color::BLACK);
+ if self.done_loading {
+ output.set_bgcolor(textmode::color::CYAN);
+ } else {
+ output.set_bgcolor(textmode::color::RED);
+ }
+ output.write_str(&format!(
+ " {}/{} ",
+ self.current_frame + 1,
+ self.total_frames
+ ));
+
+ if self.paused {
+ let size = output.screen().size();
+ output.move_to(0, size.1 - 1);
+ output.reset_attributes();
+ output.set_fgcolor(textmode::color::BLACK);
+ output.set_bgcolor(textmode::color::RED);
+ output.write_str("⏸")
+ }
+
+ output.reset_attributes();
+ output.move_to(pos.0, pos.1);
+
output.refresh().await?;
+
Ok(())
}
}
diff --git a/src/bin/ttyplay/event.rs b/src/bin/ttyplay/event.rs
index 82a200e..1c653c9 100644
--- a/src/bin/ttyplay/event.rs
+++ b/src/bin/ttyplay/event.rs
@@ -1,6 +1,8 @@
pub enum Event {
- Render(vt100::Screen),
+ Render((usize, vt100::Screen)),
Key(textmode::Key),
+ FrameLoaded(Option<usize>),
Pause,
+ Paused(bool),
Quit,
}
diff --git a/src/bin/ttyplay/frames.rs b/src/bin/ttyplay/frames.rs
index 231f84a..2f0b1a7 100644
--- a/src/bin/ttyplay/frames.rs
+++ b/src/bin/ttyplay/frames.rs
@@ -40,6 +40,10 @@ impl FrameData {
self.frames.get(i)
}
+ pub fn count(&self) -> usize {
+ self.frames.len()
+ }
+
pub async fn add_frame(&mut self, frame: Frame) {
self.frames.push(frame);
self.new_frame_w
diff --git a/src/bin/ttyplay/main.rs b/src/bin/ttyplay/main.rs
index 8446bd6..10e3d3e 100644
--- a/src/bin/ttyplay/main.rs
+++ b/src/bin/ttyplay/main.rs
@@ -18,6 +18,7 @@ enum TimerAction {
}
fn spawn_frame_reader_task(
+ event_w: async_std::channel::Sender<event::Event>,
frames: async_std::sync::Arc<async_std::sync::Mutex<frames::FrameData>>,
fh: async_std::fs::File,
) {
@@ -35,13 +36,17 @@ fn spawn_frame_reader_task(
std::time::Duration::from_secs(0)
};
parser.process(&frame.data);
+ let mut frames = frames.lock_arc().await;
frames
- .lock_arc()
- .await
.add_frame(frames::Frame::new(parser.screen().clone(), delay))
.await;
+ event_w
+ .send(event::Event::FrameLoaded(Some(frames.count())))
+ .await
+ .unwrap();
}
frames.lock_arc().await.done_reading().await;
+ event_w.send(event::Event::FrameLoaded(None)).await.unwrap();
});
}
@@ -86,13 +91,14 @@ fn spawn_timer_task(
let action = async { Res::TimerAction(timer_r.recv().await) };
match wait.race(action).await {
Res::Wait(Some(screen)) => {
- event_w.send(event::Event::Render(screen)).await.unwrap();
+ event_w
+ .send(event::Event::Render((idx, screen)))
+ .await
+ .unwrap();
idx += 1;
}
Res::Wait(None) => {
- if paused_time.is_none() {
- paused_time = Some(std::time::Instant::now());
- }
+ event_w.send(event::Event::Pause).await.unwrap();
}
Res::TimerAction(Ok(action)) => match action {
TimerAction::Pause => {
@@ -102,6 +108,10 @@ fn spawn_timer_task(
} else {
paused_time = Some(now);
}
+ event_w
+ .send(event::Event::Paused(paused_time.is_some()))
+ .await
+ .unwrap();
}
TimerAction::Quit => break,
},
@@ -138,22 +148,37 @@ async fn async_main(opt: Opt) -> anyhow::Result<()> {
let (event_w, event_r) = async_std::channel::unbounded();
let (timer_w, timer_r) = async_std::channel::unbounded();
- spawn_frame_reader_task(frames.clone(), fh);
+ spawn_frame_reader_task(event_w.clone(), frames.clone(), fh);
spawn_input_task(event_w.clone(), input);
let timer_task =
spawn_timer_task(event_w.clone(), frames.clone(), timer_r);
- let display = display::Display::new();
+ let mut display = display::Display::new();
+ let mut current_screen = vt100::Parser::default().screen().clone();
loop {
let event = event_r.recv().await?;
match event {
- event::Event::Render(screen) => {
+ event::Event::Render((idx, screen)) => {
+ current_screen = screen.clone();
+ display.current_frame(idx);
display.render(&screen, &mut output).await?;
}
event::Event::Key(key) => {
input::handle_input(key, event_w.clone()).await?
}
+ event::Event::FrameLoaded(n) => {
+ if let Some(n) = n {
+ display.total_frames(n);
+ } else {
+ display.done_loading();
+ }
+ display.render(&current_screen, &mut output).await?;
+ }
event::Event::Pause => timer_w.send(TimerAction::Pause).await?,
+ event::Event::Paused(paused) => {
+ display.paused(paused);
+ display.render(&current_screen, &mut output).await?;
+ }
event::Event::Quit => {
timer_w.send(TimerAction::Quit).await?;
break;