110 lines
2.8 KiB
Rust
110 lines
2.8 KiB
Rust
use std::io::{stdout, Write};
|
|
|
|
use crossterm::{execute, queue};
|
|
use crossterm::cursor::{Hide, MoveTo, RestorePosition, SavePosition, Show};
|
|
use crossterm::style::Print;
|
|
use crossterm::terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen, SetSize, size};
|
|
|
|
use crate::{FOOTER_ROW, HEADER_ROW, HEIGHT, WIDTH};
|
|
|
|
pub struct Terminal {
|
|
cols: u16,
|
|
rows: u16,
|
|
}
|
|
|
|
pub fn setup() -> Terminal {
|
|
let (cols, rows) = size()
|
|
.expect("Failed to get terminal screen size");
|
|
|
|
execute!(
|
|
stdout(),
|
|
EnterAlternateScreen,
|
|
SetSize(WIDTH, HEIGHT),
|
|
Hide
|
|
).expect("Failed to set up terminal screen");
|
|
enable_raw_mode()
|
|
.expect("Failed to enable raw terminal mode");
|
|
|
|
write_header();
|
|
write_footer();
|
|
Terminal { cols, rows }
|
|
}
|
|
|
|
pub fn restore(terminal: Terminal) {
|
|
disable_raw_mode()
|
|
.expect("Failed to disable raw terminal mode");
|
|
execute!(
|
|
stdout(),
|
|
SetSize(terminal.cols, terminal.rows),
|
|
Show,
|
|
LeaveAlternateScreen
|
|
)
|
|
.expect("Failed to tear down terminal screen");
|
|
}
|
|
|
|
pub fn write_header() {
|
|
queue!(
|
|
stdout(),
|
|
MoveTo(0,HEADER_ROW),
|
|
Print(center_text("UFO goes RUST! ** by fritteli, ufo@fritteli.ch ** Have fun!", None))
|
|
).expect("Failed to write to terminal");
|
|
stdout().flush().expect("Failed to write to terminal");
|
|
}
|
|
|
|
pub fn write_footer() {
|
|
queue!(
|
|
stdout(),
|
|
MoveTo(0,FOOTER_ROW),
|
|
Print(center_text("v0.0.0-dev", None))
|
|
).expect("Failed to write to terminal");
|
|
stdout().flush().expect("Failed to write to terminal");
|
|
}
|
|
|
|
fn center_text(text: &str, filler: Option<&str>) -> String {
|
|
let length = text.len();
|
|
let surplus = (WIDTH as i16) - (length as i16) - 2;
|
|
if surplus < 0 {
|
|
return String::from(text);
|
|
}
|
|
let left: usize = (surplus as usize) / 2;
|
|
let right: usize;
|
|
if surplus % 2 == 0 {
|
|
right = left;
|
|
} else {
|
|
right = left + 1;
|
|
}
|
|
let left_fill = filler.unwrap_or("=").repeat(left);
|
|
let right_fill = filler.unwrap_or("=").repeat(right);
|
|
format!("{} {} {}", left_fill, text, right_fill)
|
|
}
|
|
|
|
fn print_char_at(col: u16, row: u16, char: char) {
|
|
execute!(
|
|
stdout(),
|
|
SavePosition,
|
|
MoveTo(col, row),
|
|
Print(char),
|
|
RestorePosition
|
|
)
|
|
.expect("Failed to print char to terminal");
|
|
}
|
|
|
|
pub fn print_str_at(col: u16, row: u16, s: &str) {
|
|
execute!(
|
|
stdout(),
|
|
SavePosition,
|
|
MoveTo(col, row),
|
|
Print(s),
|
|
RestorePosition
|
|
)
|
|
.expect("Failed to print string to terminal");
|
|
}
|
|
|
|
pub fn clear_pos(col: u16, row: u16) {
|
|
print_char_at(col, row, ' ');
|
|
}
|
|
|
|
pub fn clear_stretch(col: u16, row: u16, len: usize) {
|
|
print_str_at(col, row, " ".repeat(len).as_str());
|
|
}
|