aboutsummaryrefslogtreecommitdiff
path: root/libpsi-visualizer/src/cli/renderer.rs
diff options
context:
space:
mode:
authorhachem <im@hachem.wtf>2024-09-29 16:10:02 +0200
committerhachem <im@hachem.wtf>2024-09-29 16:10:02 +0200
commit88ae20ff8254dd60c3de252e49369d4125f9e1a2 (patch)
tree58529a8f1fc11c9719e975a7a3a21a48afdc5d8b /libpsi-visualizer/src/cli/renderer.rs
parent116e85e799971b857e14d70ba4397703d469c704 (diff)
ASCII rendering engine
Diffstat (limited to 'libpsi-visualizer/src/cli/renderer.rs')
-rw-r--r--libpsi-visualizer/src/cli/renderer.rs116
1 files changed, 116 insertions, 0 deletions
diff --git a/libpsi-visualizer/src/cli/renderer.rs b/libpsi-visualizer/src/cli/renderer.rs
new file mode 100644
index 0000000..d95d609
--- /dev/null
+++ b/libpsi-visualizer/src/cli/renderer.rs
@@ -0,0 +1,116 @@
+pub struct Quad {
+ pub x: usize,
+ pub y: usize,
+ pub width: usize,
+ pub height: usize,
+}
+
+impl Quad {
+ pub fn new(x: usize, y: usize, width: usize, height: usize) -> Quad {
+ Quad {
+ x,
+ y,
+ width,
+ height,
+ }
+ }
+}
+
+pub struct CLIRenderer {
+ buffer: Vec<Vec<char>>,
+}
+
+impl CLIRenderer {
+ pub fn new(width: usize) -> CLIRenderer {
+ CLIRenderer {
+ buffer: vec![vec![' '; width]; 1],
+ }
+ }
+
+ pub fn to_string(&self) -> String {
+ self.buffer
+ .clone()
+ .into_iter()
+ .map(|inner| inner.into_iter().collect::<String>())
+ .collect::<Vec<String>>()
+ .join("\n")
+ }
+
+ pub fn place(&mut self, x: usize, y: usize, character: char) {
+ if y >= self.buffer.len() {
+ self.buffer.resize(
+ y + 1,
+ vec![' '; self.buffer.get(0).map_or(0, |row| row.len())],
+ );
+ }
+
+ if x >= self.buffer[y].len() {
+ self.buffer[y].resize(x + 1, ' ');
+ }
+ self.buffer[y][x] = character;
+ }
+
+ pub fn get(&mut self, x: usize, y: usize) -> char {
+ if y >= self.buffer.len() {
+ self.buffer.resize(
+ y + 1,
+ vec![' '; self.buffer.get(0).map_or(0, |row| row.len())],
+ );
+ }
+
+ if x >= self.buffer[y].len() {
+ self.buffer[y].resize(x + 1, ' ');
+ }
+ self.buffer[y][x]
+ }
+
+ pub fn draw_text(&mut self, x: usize, y: usize, text: &'static str) {
+ for i in 0..text.len() {
+ self.place(x + i, y, text.as_bytes()[i].into());
+ }
+ }
+
+ pub fn draw_vline(&mut self, x: usize, y: usize, height: usize, thick: bool) {
+ for i in y..y + height {
+ if self.get(x, i) == '─' {
+ self.place(x, i, if thick { '╫' } else { '┼' });
+ } else if self.get(x, i) == '═' {
+ self.place(x, i, if thick { '║' } else { '╫' });
+ } else {
+ self.place(x, i, if thick { '║' } else { '│' })
+ }
+ }
+ }
+
+ pub fn draw_hline(&mut self, x: usize, y: usize, width: usize, thick: bool) {
+ for i in x..x + width {
+ if self.get(i, y) == '│' {
+ self.place(i, y, if thick { '╪' } else { '┼' });
+ } else if self.get(i, y) == '║' {
+ self.place(i, y, if thick { '║' } else { '╫' });
+ } else {
+ self.place(i, y, if thick { '═' } else { '─' })
+ }
+ }
+ }
+
+ pub fn draw_quad(&mut self, quad: Quad, thick: bool) {
+ for x in quad.x..quad.x + quad.width {
+ for y in quad.y..quad.y + quad.height {
+ if x == quad.x && y == quad.y {
+ self.place(x, y, if thick { '╔' } else { '┌' });
+ } else if x == quad.x + quad.width - 1 && y == quad.y {
+ self.place(x, y, if thick { '╗' } else { '┐' });
+ } else if x == quad.x && y == quad.y + quad.height - 1 {
+ self.place(x, y, if thick { '╚' } else { '└' });
+ } else if x == quad.x + quad.width - 1 && y == quad.y + quad.height - 1 {
+ self.place(x, y, if thick { '╝' } else { '┘' });
+ } else if y == quad.y || y == quad.y + quad.height - 1 {
+ self.draw_hline(x, y, 1, thick);
+ } else if x == quad.x || x == quad.x + quad.width - 1 {
+ self.draw_vline(x, y, 1, thick);
+ }
+ }
+ }
+ }
+}