2021-02-27 06:27:53 +00:00
|
|
|
//! UI module
|
2021-02-14 12:27:13 +00:00
|
|
|
|
2021-02-28 04:15:05 +00:00
|
|
|
mod drawbuf;
|
2021-02-12 13:21:00 +00:00
|
|
|
mod table;
|
2021-02-26 06:03:23 +00:00
|
|
|
mod tabs;
|
2021-02-27 06:27:53 +00:00
|
|
|
mod widget;
|
2021-02-12 13:21:00 +00:00
|
|
|
|
2021-02-16 10:45:41 +00:00
|
|
|
use std::fmt::Debug;
|
2021-02-26 06:26:37 +00:00
|
|
|
use std::io::{Stdout, Write};
|
2021-02-12 08:54:19 +00:00
|
|
|
use std::time::Duration;
|
2021-02-12 08:12:43 +00:00
|
|
|
|
|
|
|
use anyhow::Result;
|
2021-02-12 08:54:19 +00:00
|
|
|
use chrono::Local;
|
2021-02-12 08:12:43 +00:00
|
|
|
use crossterm::{
|
2021-02-28 04:15:05 +00:00
|
|
|
cursor::{self, MoveTo},
|
2021-02-12 08:54:19 +00:00
|
|
|
event::{self, Event, KeyCode, KeyEvent},
|
2021-02-28 04:15:05 +00:00
|
|
|
style::{self, Color, SetBackgroundColor, SetForegroundColor},
|
|
|
|
terminal::{self, Clear, ClearType},
|
2021-02-12 08:12:43 +00:00
|
|
|
};
|
2021-02-12 08:54:19 +00:00
|
|
|
use tokio::time;
|
2021-02-12 08:12:43 +00:00
|
|
|
|
2021-02-12 08:54:19 +00:00
|
|
|
use crate::ExitSender;
|
2021-02-12 08:12:43 +00:00
|
|
|
|
2021-02-28 04:15:05 +00:00
|
|
|
use self::drawbuf::DrawBuf;
|
2021-02-12 13:21:00 +00:00
|
|
|
use self::table::Table;
|
2021-02-26 06:26:37 +00:00
|
|
|
use self::tabs::Tabs;
|
2021-02-27 06:27:53 +00:00
|
|
|
use self::widget::Widget;
|
2021-02-12 13:21:00 +00:00
|
|
|
|
2021-02-23 04:30:20 +00:00
|
|
|
const FRAME_DURATION: Duration = Duration::from_millis(20);
|
2021-02-12 13:21:00 +00:00
|
|
|
|
2021-02-26 06:26:37 +00:00
|
|
|
/// Type alias for the screen object we're drawing to
|
|
|
|
pub type Screen = Stdout;
|
|
|
|
|
2021-02-28 04:15:05 +00:00
|
|
|
/// Rectangle
|
|
|
|
#[derive(Copy, Clone, Debug)]
|
|
|
|
#[allow(missing_docs)]
|
2021-02-27 07:10:23 +00:00
|
|
|
pub struct Rect {
|
2021-02-28 04:15:05 +00:00
|
|
|
pub x: u16,
|
|
|
|
pub y: u16,
|
|
|
|
pub w: u16,
|
|
|
|
pub h: u16,
|
2021-02-27 07:10:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Rect {
|
|
|
|
/// Construct a new rectangle from (x, y) and (w, h)
|
|
|
|
pub fn new(x: u16, y: u16, w: u16, h: u16) -> Self {
|
|
|
|
Rect { x, y, w, h }
|
|
|
|
}
|
|
|
|
}
|
2021-02-12 08:12:43 +00:00
|
|
|
|
2021-02-14 12:27:13 +00:00
|
|
|
/// UI entrypoint.
|
2021-02-26 06:26:37 +00:00
|
|
|
pub async fn run_ui(mut w: Stdout, exit: ExitSender) -> Result<()> {
|
2021-02-12 08:54:19 +00:00
|
|
|
execute!(w, cursor::Hide, terminal::EnterAlternateScreen)?;
|
|
|
|
terminal::enable_raw_mode()?;
|
2021-02-12 08:12:43 +00:00
|
|
|
|
2021-02-28 04:15:05 +00:00
|
|
|
let (term_width, term_height) = terminal::size()?;
|
|
|
|
let bounds = Rect::new(0, 0, term_width, term_height);
|
|
|
|
let mut drawbuf = DrawBuf::new(bounds);
|
|
|
|
|
2021-02-12 13:21:00 +00:00
|
|
|
let mut table = Table::default();
|
|
|
|
table.push_row(vec!["ur mom Lol!".to_owned()]);
|
|
|
|
table.push_row(vec!["hek".to_owned()]);
|
|
|
|
|
2021-02-27 06:27:53 +00:00
|
|
|
let mut tabs = Tabs::new();
|
|
|
|
tabs.add_tab("Mail", table);
|
|
|
|
|
2021-02-12 08:54:19 +00:00
|
|
|
loop {
|
2021-02-12 13:21:00 +00:00
|
|
|
queue!(
|
|
|
|
w,
|
2021-02-28 04:15:05 +00:00
|
|
|
SetBackgroundColor(Color::Reset),
|
|
|
|
SetForegroundColor(Color::Reset),
|
|
|
|
Clear(ClearType::All),
|
|
|
|
MoveTo(0, 0),
|
2021-02-12 13:21:00 +00:00
|
|
|
)?;
|
2021-02-12 08:12:43 +00:00
|
|
|
|
2021-02-28 04:15:05 +00:00
|
|
|
// let now = Local::now();
|
|
|
|
// println!("time {}", now);
|
2021-02-12 08:12:43 +00:00
|
|
|
|
2021-02-12 13:21:00 +00:00
|
|
|
let (term_width, term_height) = terminal::size()?;
|
2021-02-27 07:10:23 +00:00
|
|
|
let bounds = Rect::new(5, 5, term_width - 10, term_height - 10);
|
2021-02-27 06:27:53 +00:00
|
|
|
// table.draw(&mut w, bounds)?;
|
2021-02-28 04:15:05 +00:00
|
|
|
// tabs.draw(&mut w, bounds)?;
|
|
|
|
drawbuf.draw(&mut w)?;
|
2021-02-12 13:21:00 +00:00
|
|
|
w.flush()?;
|
|
|
|
|
2021-02-12 08:54:19 +00:00
|
|
|
// approx 60fps
|
2021-02-23 04:30:20 +00:00
|
|
|
time::sleep(FRAME_DURATION).await;
|
2021-02-12 08:12:43 +00:00
|
|
|
|
2021-02-14 12:11:17 +00:00
|
|
|
// check to see if there's even an event this frame. otherwise, just keep going
|
2021-02-27 06:27:53 +00:00
|
|
|
let event = if event::poll(FRAME_DURATION)? {
|
2021-02-12 13:21:00 +00:00
|
|
|
let event = event::read()?;
|
2021-02-27 06:27:53 +00:00
|
|
|
// table.update(&event);
|
2021-02-15 10:36:06 +00:00
|
|
|
|
|
|
|
if let Event::Key(KeyEvent {
|
|
|
|
code: KeyCode::Char('q'),
|
|
|
|
..
|
|
|
|
}) = event
|
|
|
|
{
|
|
|
|
break;
|
2021-02-12 08:12:43 +00:00
|
|
|
}
|
2021-02-27 06:27:53 +00:00
|
|
|
|
|
|
|
Some(event)
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
};
|
|
|
|
|
|
|
|
tabs.update(event);
|
2021-02-12 08:12:43 +00:00
|
|
|
}
|
|
|
|
|
2021-02-12 08:54:19 +00:00
|
|
|
execute!(
|
|
|
|
w,
|
|
|
|
style::ResetColor,
|
|
|
|
cursor::Show,
|
|
|
|
terminal::LeaveAlternateScreen
|
|
|
|
)?;
|
|
|
|
terminal::disable_raw_mode()?;
|
2021-02-12 08:12:43 +00:00
|
|
|
|
2021-02-14 13:20:35 +00:00
|
|
|
exit.send(()).await?;
|
|
|
|
debug!("sent exit");
|
2021-02-12 08:54:19 +00:00
|
|
|
Ok(())
|
2021-02-12 08:12:43 +00:00
|
|
|
}
|