From 02c310aa6757e9c777155b0a63910e95c15dccb2 Mon Sep 17 00:00:00 2001 From: Gregor Reitzenstein Date: Tue, 3 Nov 2020 13:33:37 +0100 Subject: [PATCH] Event handling~ --- src/app.rs | 48 ++++++++++++++++++++++++++++++++++++------------ src/input.rs | 33 ++------------------------------- src/main.rs | 10 ++++++++++ src/ui/mod.rs | 16 ++++++++-------- 4 files changed, 56 insertions(+), 51 deletions(-) diff --git a/src/app.rs b/src/app.rs index cd81422..099fe94 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,10 +1,14 @@ +use std::mem; use std::pin::Pin; -use std::task::{Context, Poll}; +use std::task::{Context, Poll, Waker}; use std::sync::{Arc, Mutex, MutexGuard}; use futures::prelude::*; +use futures::ready; use futures_signals::signal::{Mutable, Signal, MutableSignalCloned, MutableLockMut}; +use termion::event::Key; + use crate::input::Inputs; use crate::schema::API; @@ -32,7 +36,6 @@ pub struct Sute<'a, S> { // change the state. state: SuteState<'a>, - modified: bool, signal: S, inputs: Inputs, @@ -47,7 +50,6 @@ impl<'a, S: Unpin> Sute<'a, S> { Self { state: state, - modified: false, signal: s, inputs: inputs, @@ -66,31 +68,51 @@ impl<'a, S: Unpin> Sute<'a, S> { fn handle_resize(&mut self, new_size: (u16,u16)) { self.state.size = new_size; - self.modified = true } pub fn get_state(&self) -> SuteState<'a> { self.state.clone() } + + pub fn handle_key(&mut self, key: Key) { + match key { + Key::Char('\n') => { + let cmd = mem::replace(&mut self.state.cmd_line, String::new()); + self.run_cmd(cmd); + }, + Key::Char(c) => { + self.state.cmd_line.push(c); + }, + Key::Backspace => { + self.state.cmd_line.pop(); + }, + _ => {} + } + } } impl<'a, S: Signal + Unpin> Signal for Sute<'a, S> { type Item = SuteState<'a>; fn poll_change(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll> { - match Pin::new(&mut self.inputs).poll_next(cx) { - Poll::Ready(Some(line)) => self.run_cmd(line), + let mut dirty = false; + + if let Poll::Ready(Some(size)) = Pin::new(&mut self.signal).poll_change(cx) { + dirty = true; + self.handle_resize(size); + } + match ready!(Pin::new(&mut self.inputs).poll_next(cx)) { + Some(key) => { + dirty = true; + self.handle_key(key); + }, // If the input closes stop the program - Poll::Ready(None) => { + None => { self.state.running = false; return Poll::Ready(None); }, - Poll::Pending => { }, - } - if let Poll::Ready(Some(size)) = Pin::new(&mut self.signal).poll_change(cx) { - self.handle_resize(size); } - if self.modified { + if dirty { Poll::Ready(Some(self.get_state())) } else { Poll::Pending @@ -125,6 +147,7 @@ pub struct SuteState<'a> { pub server: Option<&'a str>, pub log: Arc>, pub cmd_line: String, + pub tick_c: char, } impl<'a> SuteState<'a> { @@ -137,6 +160,7 @@ impl<'a> SuteState<'a> { server: None, log: log, cmd_line: String::new(), + tick_c: '|', } } } diff --git a/src/input.rs b/src/input.rs index 04c9459..1195637 100644 --- a/src/input.rs +++ b/src/input.rs @@ -13,7 +13,6 @@ use futures::SinkExt; pub struct Inputs { rx: mpsc::Receiver, hndl: thread::JoinHandle<()>, - cmd_line: String, } impl Inputs { @@ -32,42 +31,14 @@ impl Inputs { Self { rx: rx, hndl: hndl, - cmd_line: String::new(), - } - } - - pub fn get_line(&self) -> &str { - self.cmd_line.as_ref() - } - - pub fn handle_key(&mut self, key: Key) -> Option { - match key { - Key::Char('\n') => Some(mem::replace(&mut self.cmd_line, String::new())), - Key::Char(c) => { - self.cmd_line.push(c); - None - }, - Key::Backspace => { - self.cmd_line.pop(); - None - }, - _ => None } } } impl Stream for Inputs { - type Item = String; + type Item = Key; fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll> { - if let Some(key) = ready!(Pin::new(&mut self.rx).poll_next(cx)) { - if let Some(line) = self.handle_key(key) { - Poll::Ready(Some(line)) - } else { - Poll::Pending - } - } else { - Poll::Pending - } + Pin::new(&mut self.rx).poll_next(cx) } } diff --git a/src/main.rs b/src/main.rs index b122627..b95f617 100644 --- a/src/main.rs +++ b/src/main.rs @@ -79,6 +79,8 @@ fn main() -> Result<(), io::Error> { let mut terminal = Terminal::new(backend)?; terminal.hide_cursor()?; + let mut tick_c = '|'; + // Refresh the screen once by resizing the terminal if let Ok((x,y)) = termion::terminal_size() { terminal.resize(tui::layout::Rect::new(0, 0, x,y)).unwrap(); @@ -90,6 +92,14 @@ fn main() -> Result<(), io::Error> { break; } + tick_c = match tick_c { + '\\' => '|', + '|' => '/', + '/' => '-', + '-' => '\\', + _ => '|', + }; + state.tick_c = tick_c; terminal.draw(|f| ui::draw_ui(f, &mut state))?; } else { break; diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 203993b..b32cfe7 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -31,14 +31,12 @@ fn draw_header(f: &mut Frame, app: &mut SuteState, layout_chunk: } fn draw_main(f: &mut Frame, app: &mut SuteState, layout_chunk: Rect) { - let chunk = Layout::default() - .direction(Direction::Horizontal) - .constraints([Constraint::Percentage(20), Constraint::Percentage(80)].as_ref()) - .split(layout_chunk); + // let chunk = Layout::default() + // .direction(Direction::Horizontal) + // .constraints([Constraint::Percentage(20), Constraint::Percentage(80)].as_ref()) + // .split(layout_chunk); - f.render_widget(Paragraph::new(app.server.unwrap_or("Not connected")), chunk[0]); - - draw_logs(f, app, chunk[1]) + draw_logs(f, app, layout_chunk) } fn draw_logs(f: &mut Frame, app: &mut SuteState, layout_chunk: Rect) { // TODO: Just use a signal. @@ -53,5 +51,7 @@ fn draw_command_line(f: &mut Frame, app: &mut SuteState, layout_c let inner_rect = block.inner(layout_chunk); f.render_widget(block, layout_chunk); - f.render_widget(Paragraph::new(app.cmd_line.as_ref()), inner_rect); + + let cmdline = format!("{} > {}", app.tick_c, app.cmd_line); + f.render_widget(Paragraph::new(&cmdline[..]), inner_rect); }