miraculous_ui/
lib.rs

1use std::io::{stdout, Write, Stdout};
2use std::collections::VecDeque;
3use termsize;
4use crossterm::{
5    terminal::ClearType,
6    self,
7    QueueableCommand, 
8    cursor,
9    style::{self, Stylize}, 
10    terminal
11};
12
13pub struct UI {
14    stdout: Stdout,
15    messages: VecDeque<String>,
16    info: String
17}
18
19impl UI {
20    pub fn new() -> UI {
21        let new_ui = UI {
22            stdout: stdout(),
23            messages: VecDeque::new(),
24            info: String::new()
25        };
26        new_ui
27    }
28    pub fn draw(&mut self) {
29        let size = match termsize::get() {
30            Some(s) => s,
31            None => std::process::exit(1)
32        };
33        self.stdout.queue(cursor::Hide);
34        self.stdout.queue(terminal::Clear(ClearType::All));
35        let mut msg_num = 0;
36        for line in (0..size.rows - 1).rev() {
37            self.stdout.queue(cursor::MoveTo(0,line));
38            if msg_num < self.messages.len() {
39                self.stdout.queue(style::Print(&self.messages[msg_num]));
40            }
41            msg_num += 1;
42        }
43        self.stdout.queue(cursor::MoveTo(0, size.rows));
44        self.stdout.queue(style::Print(&self.info));
45        self.stdout.flush();
46    }
47
48    pub fn push(&mut self, msg: &str) {
49        self.messages.push_front(msg.to_string());
50        if self.messages.len() > 50  {
51            self.messages.pop_back();
52        }
53    }
54
55    pub fn info(&mut self, msg: &str) {
56        self.info = msg.to_string();
57    }
58}