pub mod window;
pub mod terminal;
use std::io::Write;
use terminal::Terminal;
use window::{Config, Location, Window};
pub fn init(alternative_screen: bool) -> App {
if alternative_screen {
print!("\x1b[?1049h\x1b[H");
std::io::stdout().flush().unwrap();
}
let term = Terminal::default();
let wins = Vec::new();
App { term, wins }
}
pub struct App {
term: Terminal,
pub wins: Vec<Window>
}
impl App {
pub fn push(&mut self, window: Window) {
self.wins.push(window);
}
pub fn render(&self, conf: &Config) {
print!("\x1b[2J\x1b[H");
std::io::stdout().flush().unwrap();
for i in &self.wins {
let mut line_number = 0;
let mut left_side_line_num = i.left_side_line_num;
let mut right_side_line_num = i.right_side_line_num;
if !i.left_column {
left_side_line_num = None;
}
if !i.right_column {
right_side_line_num = None;
}
let size = i.dimensions.width as usize - (conf.border_len[0] + conf.border_len[1]);
let border_h = conf.border_h.to_string();
let border_h = &border_h[..];
let msg = match i.title.chars().count() <= size {
| true => match conf.title {
| Location::Left => format!("{}{}", &i.title, border_h.repeat(size - i.title.chars().count() + 1)),
| Location::Right => format!("{}{}", border_h.repeat(size - i.title.chars().count() + 1), &i.title),
| Location::Center => {
let total_spaces = size - i.title.chars().count();
let mod_spaces = match total_spaces % 2 {
| 0 => "",
| _ => border_h
};
format!("{}{}{}{}", border_h.repeat(total_spaces / 2 + 1), &i.title, border_h.repeat(total_spaces / 2), mod_spaces)
}
},
| false => {
if (i.dimensions.width as usize) <= conf.border_len[0] + conf.border_len[1] {
if (i.dimensions.width as usize) == conf.border_len[0] + conf.border_len[1] {
i.title[0 .. 1].to_string()
} else {
String::new()
}
} else {
i.title[0 .. size + 1].to_owned()
}
},
};
if i.top_bar {
println!("\x1b[{};{}H{}{}{}", i.pos.y + 1, i.pos.x + 1, conf.border_connector[0], msg, conf.border_connector[1]);
line_number += 1;
}
let mut lines: Vec<&str> = i.content.split('\n').collect();
let window_vert_taken_size = match (i.top_bar, i.bottom_bar) {
| (true, true) => 2,
| (false, false) => 0,
| _ => 1
};
while lines.len() > i.dimensions.height as usize - window_vert_taken_size {
lines.pop();
}
for line_num in line_number .. lines.len() + line_number {
match left_side_line_num {
| Some((ln, cn)) => {
let sub_num = line_number;
let mut line_num_bar = (ln + line_num - 1).to_string();
while line_num_bar.len() < lines.len().to_string().len() {
line_num_bar.push(' ');
}
let line_num_format = match line_num_bar.replace(" ", "") == cn.to_string() {
| false => format!("{}{}\x1b[0m", conf.line_num.std_num_color, line_num_bar),
| true => format!("{}{}\x1b[0m", conf.line_num.current_num_color, line_num_bar)
};
if i.left_column {
print!("\x1b[{};{}H{}{}", i.pos.y as usize + line_num + 1, i.pos.x + 1, line_num_format, lines[line_num - sub_num]);
} else {
print!("\x1b[{};{}H{}", i.pos.y as usize + line_num + 1, i.pos.x + 1, lines[line_num - sub_num]);
}
if right_side_line_num == None {
if i.right_column {
print!("\x1b[{};{}H{}", i.pos.y as usize + line_num + 1, size + 3 + i.pos.x as usize, conf.border_v);
}
} else if i.right_column {
print!("\x1b[{};{}H{}", i.pos.y as usize + line_num + 1, size + 4 + i.pos.x as usize - line_num_bar.len(), line_num_format);
}
},
| None => match right_side_line_num {
| None => {
let sub_num = line_number;
if i.left_column {
print!("\x1b[{};{}H{}{}", i.pos.y as usize + line_num + 1, i.pos.x + 1, conf.border_v, lines[line_num - sub_num]);
} else {
print!("\x1b[{};{}H{}", i.pos.y as usize + line_num + 1, i.pos.x + 1, lines[line_num - sub_num]);
}
if i.right_column {
print!("\x1b[{};{}H{}", i.pos.y as usize + line_num + 1, size + 3 + i.pos.x as usize, conf.border_v);
}
},
| Some((ln, cn)) => {
let sub_num = line_number;
let mut line_num_bar = (ln + line_num).to_string();
while line_num_bar.len() < lines.len().to_string().len() {
line_num_bar.push(' ');
}
let line_num_format = match line_num_bar.replace(" ", "") == cn.to_string() {
| false => format!("{}{}\x1b[0m", conf.line_num.std_num_color, line_num_bar),
| true => format!("{}{}\x1b[0m", conf.line_num.current_num_color, line_num_bar)
};
if i.left_column {
print!("\x1b[{};{}H{}{}", i.pos.y as usize + line_num + 1, i.pos.x + 1, conf.border_v, lines[line_num - sub_num]);
} else {
print!("\x1b[{};{}H{}", i.pos.y as usize + line_num + 1, i.pos.x + 1, lines[line_num - sub_num]);
}
if i.right_column {
print!("\x1b[{};{}H{}", i.pos.y as usize + line_num + 1, size + 3 + i.pos.x as usize, line_num_format);
}
}
}
}
}
if !i.top_bar {
line_number = 1;
} else {
line_number = 0;
}
let mut bottom_number = 0;
if !i.bottom_bar {
bottom_number = 1;
}
if lines.len() - line_number < i.dimensions.height as usize - window_vert_taken_size - line_number + bottom_number {
for j in lines.len() - line_number .. i.dimensions.height as usize - window_vert_taken_size - line_number + bottom_number {
if left_side_line_num == None {
if i.left_column {
print!("\x1b[{};{}H{}", i.pos.y as usize + j + 2, i.pos.x + 1, conf.border_v);
}
} else {
let vert_col = format!("{}{}\x1b[0m", conf.line_num.std_num_color, " ".repeat(lines.len().to_string().len()));
if i.left_column {
print!("\x1b[{};{}H{}", i.pos.y as usize + j + 2, i.pos.x + 1, vert_col);
}
}
if right_side_line_num == None {
if i.right_column {
print!("\x1b[{};{}H{}", i.pos.y as usize + j + 2, size + 3 + i.pos.x as usize, conf.border_v);
}
} else if i.right_column {
let vert_col = format!("{}{}\x1b[0m", conf.line_num.std_num_color, " ".repeat(lines.len().to_string().len()));
print!("\x1b[{};{}H{}", i.pos.y as usize + j + 2, size + 4 + i.pos.x as usize - lines.len().to_string().len(), vert_col);
}
}
}
if i.bottom_bar {
print!("\x1b[{};{}H{}{}{}", i.pos.y + i.dimensions.height, i.pos.x + 1, conf.border_connector[2], border_h.repeat(size + 1), conf.border_connector[3]);
}
std::io::stdout().flush().unwrap();
}
}
}