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}