tpaint/tools/
block.rs

1use crossterm::event::{KeyEvent, MouseEventKind};
2
3use std::{fs::read_to_string, path::Path};
4
5use crate::{buffer::Buffer, error::Result, state::State, tools::Tool};
6
7#[derive(Default)]
8pub struct Block {
9	chars: Vec<(usize, usize, char)>,
10}
11
12impl Block {
13	pub fn new(input_file: &Path) -> Result<Self> {
14		let file_str = read_to_string(input_file)?;
15		let chars = file_str
16			.lines()
17			.enumerate()
18			.flat_map(|(y, line)| line.chars().enumerate().map(move |(x, c)| (x, y, c)))
19			.filter(|(_, _, c)| *c != ' ')
20			.collect::<Vec<_>>();
21		Ok(Self { chars })
22	}
23}
24
25impl Tool for Block {
26	fn mouse_event(&mut self, _: isize, _: isize, _: MouseEventKind) -> fn(state: &mut State) {
27		|state| state.reset_current_mouse_element()
28	}
29
30	fn key_event(&mut self, _: KeyEvent) -> fn(state: &mut State) { |_| () }
31
32	fn bounding_box(&self) -> Option<(usize, usize, usize, usize)> {
33		self.chars
34			.iter()
35			.copied()
36			.fold(None, |acc, (x, y, _)| match acc {
37				Some((min_x, max_x, min_y, max_y)) => {
38					Some((min_x.min(x), max_x.max(x), min_y.min(y), max_y.max(y)))
39				}
40				None => Some((x, x, y, y)),
41			})
42	}
43
44	fn render(&self, buffer: &mut Buffer, _: bool) {
45		self.chars
46			.iter()
47			.copied()
48			.for_each(|(x, y, c)| buffer.render_point(x, y, c))
49	}
50
51	fn render_bounded(
52		&self,
53		min_x: usize,
54		max_x: usize,
55		min_y: usize,
56		max_y: usize,
57		buffer: &mut Buffer,
58		_: bool,
59	) {
60		self.chars
61			.iter()
62			.copied()
63			.filter(|(x, y, _)| (min_x <= *x && *x < max_x) && (min_y <= *y && *y < max_y))
64			.for_each(|(x, y, c)| buffer.render_point(x, y, c))
65	}
66
67	fn complete(&self) -> bool { true }
68}