mirror of
https://gitlab.com/fabinfra/fabaccess/sute.git
synced 2025-03-12 14:41:52 +01:00
Event handling~
This commit is contained in:
parent
97bc38e74a
commit
02c310aa67
48
src/app.rs
48
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<Item=(u16,u16)> + Unpin> Signal for Sute<'a, S> {
|
||||
type Item = SuteState<'a>;
|
||||
fn poll_change(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
|
||||
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<LogDrain<'a>>,
|
||||
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: '|',
|
||||
}
|
||||
}
|
||||
}
|
||||
|
33
src/input.rs
33
src/input.rs
@ -13,7 +13,6 @@ use futures::SinkExt;
|
||||
pub struct Inputs {
|
||||
rx: mpsc::Receiver<Key>,
|
||||
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<String> {
|
||||
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<Option<Self::Item>> {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
10
src/main.rs
10
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;
|
||||
|
@ -31,14 +31,12 @@ fn draw_header<B: Backend>(f: &mut Frame<B>, app: &mut SuteState, layout_chunk:
|
||||
}
|
||||
|
||||
fn draw_main<B: Backend>(f: &mut Frame<B>, 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<B: Backend>(f: &mut Frame<B>, app: &mut SuteState, layout_chunk: Rect) {
|
||||
// TODO: Just use a signal.
|
||||
@ -53,5 +51,7 @@ fn draw_command_line<B: Backend>(f: &mut Frame<B>, 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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user