buffer_graphics_lib/shapes/collection/
mutation.rs

1use crate::prelude::*;
2use graphics_shapes::shape_box::ShapeBox;
3
4impl ShapeCollection {
5    pub fn with_draw_type(&self, draw_type: DrawType) -> ShapeCollection {
6        let shapes: Vec<Drawable<ShapeBox>> = self
7            .iter()
8            .map(|shape| shape.with_draw_type(draw_type))
9            .collect();
10        ShapeCollection {
11            shapes,
12            bounds: self.bounds.clone(),
13        }
14    }
15}
16
17impl ShapeCollection {
18    pub fn with_translation<P: Into<Coord>>(&self, delta: P) -> ShapeCollection {
19        let delta = delta.into();
20        let shapes: Vec<Drawable<ShapeBox>> = self
21            .iter()
22            .map(|shape| shape.with_translation(delta))
23            .collect();
24        let bounds = calc_bounds(&shapes);
25        ShapeCollection { shapes, bounds }
26    }
27
28    pub fn with_move<P: Into<Coord>>(&self, xy: P) -> ShapeCollection {
29        let xy = xy.into();
30        let collection_start = Coord::new(self.left(), self.top());
31        let diff = xy - collection_start;
32        let shapes: Vec<Drawable<ShapeBox>> = self
33            .iter()
34            .map(|shape| shape.with_translation(diff))
35            .collect();
36        let bounds = calc_bounds(&shapes);
37        ShapeCollection { shapes, bounds }
38    }
39}
40
41macro_rules! shapebox_mutate_one {
42    ($name: ident, $drawable_name: ident, $param: ident, $param_type: ty) => {
43        impl ShapeCollection {
44            pub fn $name(&self, $param: $param_type) -> ShapeCollection {
45                let center = self.center();
46                let shapes: Vec<Drawable<ShapeBox>> = self
47                    .shapes
48                    .iter()
49                    .map(|shape| shape.$drawable_name($param, center))
50                    .collect();
51                let bounds = calc_bounds(&shapes);
52                ShapeCollection { shapes, bounds }
53            }
54        }
55    };
56}
57
58macro_rules! shapebox_mutate_two {
59    ($name: ident, $param: ident, $param_type: ty) => {
60        impl ShapeCollection {
61            pub fn $name<P: Into<Coord>>(&self, $param: $param_type, center: P) -> ShapeCollection {
62                let center = center.into();
63                let shapes: Vec<Drawable<ShapeBox>> = self
64                    .shapes
65                    .iter()
66                    .map(|shape| shape.$name($param, center))
67                    .collect();
68                let bounds = calc_bounds(&shapes);
69                ShapeCollection { shapes, bounds }
70            }
71        }
72    };
73}
74
75shapebox_mutate_one!(with_scale, with_scale_around, scale, f32);
76shapebox_mutate_one!(with_rotation, with_rotation_around, degrees, isize);
77shapebox_mutate_two!(with_scale_around, scale, f32);
78shapebox_mutate_two!(with_rotation_around, degrees, isize);
79
80#[cfg(test)]
81mod test {
82    use crate::prelude::*;
83    use graphics_shapes::shape_box::ShapeBox;
84    use ici_files::prelude::*;
85
86    #[test]
87    fn check_with_translation() {
88        let mut collection = ShapeCollection::default();
89        InsertShape::insert_above(&mut collection, Rect::new((20, 20), (40, 40)), fill(RED));
90        InsertShape::insert_above(&mut collection, Rect::new((60, 20), (80, 40)), fill(RED));
91
92        let moved = collection.with_translation((0, 20));
93
94        assert_eq!(
95            moved.shapes,
96            vec![
97                Drawable::from_obj(ShapeBox::from(Rect::new((20, 40), (40, 60))), fill(RED)),
98                Drawable::from_obj(ShapeBox::from(Rect::new((60, 40), (80, 60))), fill(RED)),
99            ]
100        );
101    }
102
103    #[test]
104    fn check_with_move() {
105        let mut collection = ShapeCollection::default();
106        InsertShape::insert_above(&mut collection, Rect::new((20, 20), (40, 40)), fill(RED));
107        InsertShape::insert_above(&mut collection, Rect::new((60, 20), (80, 40)), fill(RED));
108
109        let moved = collection.with_move((0, 0));
110
111        assert_eq!(
112            moved.shapes,
113            vec![
114                Drawable::from_obj(ShapeBox::from(Rect::new((0, 0), (20, 20))), fill(RED)),
115                Drawable::from_obj(ShapeBox::from(Rect::new((40, 0), (60, 20))), fill(RED)),
116            ]
117        );
118    }
119}