Commit 599088bf authored by Christopher Silva's avatar Christopher Silva

finish basic viewport

parent f637d3c1
use std::io::{Write, stdin, Stdout, stdout};
use std::ops::Range;
use anyhow::Result;
use termion::{clear, color, cursor};
......@@ -43,7 +44,7 @@ impl Viewport {
size: (h as usize, w as usize),
cursor: (1, 1),
previous: (1, 1),
cell_width: 7,
cell_width: 10,
origin: (1, 1),
changed: false,
}
......@@ -58,6 +59,14 @@ impl Viewport {
)
}
fn column_numbers(&self) -> Range<usize> {
(self.origin.1..(self.origin.1 + (self.size.1 / self.cell_width) - 1))
}
fn row_numbers(&self) -> Range<usize> {
(self.origin.0..(self.origin.0 + self.size.0 - 2))
}
fn move_cursor_up(&mut self) {
if self.cursor.0 > 1 {
self.previous = self.cursor;
......@@ -83,11 +92,19 @@ impl Viewport {
self.previous = self.cursor;
self.cursor.1 -= 1;
}
if self.cursor.1 < self.origin.1 {
self.origin.1 = self.cursor.1;
self.changed = true;
}
}
fn move_cursor_right(&mut self) {
self.previous = self.cursor;
self.cursor.1 += 1;
if self.origin.1 + ((self.size.1 / self.cell_width) - 2) < self.cursor.1 {
self.origin.1 = self.cursor.1 + 2 - (self.size.1 / self.cell_width);
self.changed = true;
}
}
fn set_cursor(&mut self, cursor: (usize, usize)) {
......@@ -96,8 +113,37 @@ impl Viewport {
}
}
/// invert colors if some condition is met then change back afterwards
macro_rules! invert_colors {
($viewport:expr, $condition:expr, $inverted:expr) => {
if $condition {
$viewport.buffer.push_str(&format!("{}{}", $viewport.ifg, $viewport.ibg)[..]);
}
$inverted;
if $condition {
$viewport.buffer.push_str(&format!("{}{}", $viewport.fg, $viewport.bg)[..]);
}
};
}
macro_rules! set_colors {
($ui:ident) => {
$ui.buffer.push_str(&format!("{}{}", $ui.fg, $ui.bg)[..])
}
}
macro_rules! buffer {
($ui:ident, false, $fmt_string:expr, $($args:expr),*) => {
$ui.buffer.push_str(&format!($fmt_string, $($args),*)[..])
};
($ui:ident, $fmt_string:expr, $($args:expr),*) => {
$ui.buffer.push_str(&format!($fmt_string, $($args),*, width=$ui.viewport.cell_width)[..])
};
}
struct UI<'a> {
stdout: RawTerminal<Stdout>,
buffer: String,
viewport: Viewport,
sheet: &'a mut Sheet,
cells: Vec<Vec<String>>,
......@@ -116,6 +162,7 @@ impl<'a> UI<'a> {
UI {
stdout: stdout().into_raw_mode().unwrap(),
buffer: String::new(),
viewport,
sheet,
cells,
......@@ -127,6 +174,7 @@ impl<'a> UI<'a> {
}
fn run(&mut self) -> Result<()> {
print!("{}", clear::All);
self.print_all();
let stdin = stdin();
......@@ -153,7 +201,7 @@ impl<'a> UI<'a> {
self.cells = self.sheet.render_range(r, c, h, w);
self.print_all();
} else {
self.print_changes();
self.print_all();
}
}
......@@ -163,64 +211,59 @@ impl<'a> UI<'a> {
}
fn print_all(&mut self) {
print!("{}{}{}", self.fg, self.bg, clear::All);
set_colors!(self);
self.print_column_numbers();
self.print_row_numbers();
self.print_cells();
self.print_command_area();
print!("{}", self.buffer);
self.buffer = String::new();
self.stdout.flush().unwrap();
}
fn print_column_numbers(&self) {
print!("{}{}{}{:width$}", self.fg, self.bg, cursor::Goto(1, 2), "", width=self.viewport.cell_width);
for i in 1..=self.cells[0].len() {
if i == self.viewport.cursor.1 {
print!("{}{}", self.ifg, self.ibg);
}
print!("{:^width$}", i, width=self.viewport.cell_width);
if i == self.viewport.cursor.1 {
print!("{}{}", self.fg, self.bg);
}
fn print_column_numbers(&mut self) {
set_colors!(self);
buffer!(self, "{}{:width$}", cursor::Goto(1, 2), "");
for c in self.viewport.column_numbers() {
invert_colors!(self, c == self.viewport.cursor.1,
buffer!(self, "{:^width$}", c)
);
}
}
fn print_row_numbers(&self) {
print!("{}{}", self.fg, self.bg);
for i in 1..=self.cells.len() {
if i == self.viewport.cursor.0 {
print!("{}{}", self.ifg, self.ibg);
}
print!("{}{:^width$}", cursor::Goto(1, (i+2) as u16), i, width=self.viewport.cell_width);
if i == self.viewport.cursor.0 {
print!("{}{}", self.fg, self.bg);
}
fn print_row_numbers(&mut self) {
self.buffer.push_str(&format!("{}{}", self.fg, self.bg)[..]);
for (i, r) in self.viewport.row_numbers().into_iter().enumerate() {
invert_colors!(self, r == self.viewport.cursor.0,
buffer!(self, "{}{:^width$}", cursor::Goto(1, (i+3) as u16), r)
);
}
}
fn print_cells(&self) {
print!("{}{}", self.bg, self.fg);
for (r, row) in self.cells.iter().enumerate() {
print!("{}", cursor::Goto((1+self.viewport.cell_width) as u16, (r+3) as u16));
for (c, cell) in row.iter().enumerate() {
if (r+1, c+1) == self.viewport.cursor {
print!("{}{}", self.ifg, self.ibg);
}
if cell.len() <= self.viewport.cell_width {
print!("{:<width$}", cell, width=self.viewport.cell_width);
} else {
print!("{:#<width$}", "", width=self.viewport.cell_width);
}
if (r+1, c+1) == self.viewport.cursor {
print!("{}{}", self.fg, self.bg);
}
fn print_cells(&mut self) {
set_colors!(self);
for (i, r) in self.viewport.row_numbers().into_iter().enumerate() {
buffer!(self, false, "{}", cursor::Goto((1+self.viewport.cell_width) as u16, (i+3) as u16));
for (j, c) in self.viewport.column_numbers().into_iter().enumerate() {
invert_colors!(self, (r, c) == self.viewport.cursor,
if self.cells[i][j].len() <= self.viewport.cell_width {
buffer!(self, "{:<width$}", self.cells[i][j]);
} else {
buffer!(self, "{:#<width$}", "");
}
);
}
}
}
fn print_command_area(&self) {
print!("{}{}{}{}{}", cursor::Goto(1, 1), self.fg, self.bg, clear::CurrentLine, self.cells[self.viewport.cursor.0-self.viewport.origin.0][self.viewport.cursor.1-self.viewport.origin.1]);
fn print_command_area(&mut self) {
set_colors!(self);
let i = self.viewport.cursor.0 - self.viewport.origin.0;
let j = self.viewport.cursor.1 - self.viewport.origin.1;
buffer!(self, false, "{}{}{}", cursor::Goto(1, 1), clear::CurrentLine, self.cells[i][j]);
}
// doesn't work after switch to viewport, needs to be redone
fn print_changes(&mut self) {
// reprint current/previous column numbers
print!(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment