aboutsummaryrefslogtreecommitdiff
path: root/src/tool/polygon_room_tool.rs
blob: 4aab7f7dcc98288180460c10bd15d23a9a1746f2 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
use super::Tool;
use crate::button::Button;
use crate::config::{PolygonRoomToolKeybindings, ToolKeybindings};
use crate::dimension_indicator::DimensionIndicator;
use crate::grid::{snap_to_grid, SNAP_SIZE};
use crate::map_data::MapData;
use crate::math::{Polygon, Vec2};
use crate::transform::Transform;
use raylib::core::drawing::RaylibDrawHandle;
use raylib::RaylibHandle;

pub struct PolygonRoomTool {
    keybindings: PolygonRoomToolKeybindings,
    unfinished_polygon: Option<Vec<Vec2<f32>>>,
    dimension_indicator: DimensionIndicator,
}

impl PolygonRoomTool {
    pub fn new(keybindings: PolygonRoomToolKeybindings) -> Self {
        Self {
            keybindings,
            unfinished_polygon: None,
            dimension_indicator: DimensionIndicator::new(),
        }
    }
}

impl Tool for PolygonRoomTool {
    fn activate(&mut self) {}

    fn deactivate(&mut self) {
        self.unfinished_polygon = None;
    }

    fn active_update(
        &mut self,
        map: &mut MapData,
        rl: &RaylibHandle,
        transform: &Transform,
        mouse_blocked: bool,
    ) {
        let mouse_pos_m = transform.point_px_to_m(rl.get_mouse_position().into());
        let snapped_mouse_pos_m = snap_to_grid(mouse_pos_m, SNAP_SIZE);
        // Update the position of the node that would be placed into the polygon next.
        if let Some(ref mut corners) = &mut self.unfinished_polygon {
            let last_element = corners.len() - 1;
            corners[last_element] = snapped_mouse_pos_m;
            self.dimension_indicator.update_dimensions(&corners);
        }

        if self.keybindings.finish.is_pressed(rl, mouse_blocked)
            && self.unfinished_polygon.is_some()
        {
            // Make sure the polygon is at least a triangle, so it can be drawn.
            if self.unfinished_polygon.as_ref().unwrap().len() >= 3 {
                let polygon = Polygon::new(self.unfinished_polygon.take().unwrap());
                self.dimension_indicator.clear_dimensions();
                map.polygons_mut().push(polygon);
            }
        }

        if self.keybindings.place_node.is_pressed(rl, mouse_blocked) {
            if let Some(ref mut corners) = self.unfinished_polygon.as_mut() {
                if snapped_mouse_pos_m == corners[0] {
                    // Make sure the polygon is at least a triangle, so it can be drawn.
                    if corners.len() >= 3 {
                        // The last corner is redundant.
                        corners.pop();
                        let polygon = Polygon::new(self.unfinished_polygon.take().unwrap());
                        self.dimension_indicator.clear_dimensions();
                        map.polygons_mut().push(polygon);
                    }
                } else {
                    corners.push(snapped_mouse_pos_m);
                }
            } else {
                self.unfinished_polygon = Some(vec![snapped_mouse_pos_m]);
            }
        }

        if self.keybindings.abort.is_pressed(rl, false) {
            self.unfinished_polygon = None;
        }
    }

    fn draw(&self, _map: &MapData, _rld: &mut RaylibDrawHandle, _transform: &Transform) {}

    fn activation_key(&self) -> Button {
        self.keybindings.activation_key()
    }
}