rust-ufo/src/terminal.rs

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());
}