buffer_graphics_lib/shapes/collection/
mod.rs1use crate::drawing::Renderable;
2use crate::prelude::*;
3use crate::{sized_renderable, Graphics};
4use graphics_shapes::coord::Coord;
5use graphics_shapes::rect::Rect;
6use graphics_shapes::shape_box::ShapeBox;
7use graphics_shapes::Shape;
8#[cfg(feature = "serde")]
9use serde::{Deserialize, Serialize};
10use std::fmt::Debug;
11use std::slice::Iter;
12
13pub mod mutation;
14
15#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
16#[derive(Debug, Clone, PartialEq)]
17pub struct ShapeCollection {
18 shapes: Vec<Drawable<ShapeBox>>,
19 bounds: Rect,
20}
21
22pub fn calc_bounds(list: &[Drawable<ShapeBox>]) -> Rect {
23 if list.is_empty() {
24 return Rect::new((0, 0), (0, 0));
25 }
26 let mut bounds = Rect::new(
27 (list[0].left(), list[0].top()),
28 (list[0].right(), list[0].bottom()),
29 );
30 for shape in list.iter().skip(1) {
31 bounds = Rect::new(
32 (
33 bounds.left().min(shape.left()),
34 bounds.top().min(shape.top()),
35 ),
36 (
37 bounds.right().max(shape.right()),
38 bounds.bottom().max(shape.bottom()),
39 ),
40 );
41 }
42 bounds
43}
44
45impl Default for ShapeCollection {
46 fn default() -> Self {
47 ShapeCollection {
48 shapes: vec![],
49 bounds: Rect::new((0, 0), (0, 0)),
50 }
51 }
52}
53
54impl ShapeCollection {
55 #[inline]
56 pub fn iter(&self) -> Iter<'_, Drawable<ShapeBox>> {
57 self.shapes.iter()
58 }
59
60 #[inline]
61 pub fn len(&self) -> usize {
62 self.shapes.len()
63 }
64
65 #[inline]
66 pub fn is_empty(&self) -> bool {
67 self.shapes.is_empty()
68 }
69
70 #[inline]
71 fn update_bounds(&mut self) {
72 self.bounds = calc_bounds(&self.shapes);
73 }
74
75 #[inline]
76 pub fn remove(&mut self, idx: usize) -> Drawable<ShapeBox> {
77 self.shapes.remove(idx)
78 }
79
80 #[inline]
81 pub fn bounds(&self) -> &Rect {
82 &self.bounds
83 }
84
85 #[inline]
86 pub fn left(&self) -> isize {
87 self.bounds.left()
88 }
89
90 #[inline]
91 pub fn top(&self) -> isize {
92 self.bounds.top()
93 }
94
95 #[inline]
96 pub fn bottom(&self) -> isize {
97 self.bounds.bottom()
98 }
99
100 #[inline]
101 pub fn right(&self) -> isize {
102 self.bounds.right()
103 }
104
105 #[inline]
106 pub fn center(&self) -> Coord {
107 self.bounds.center()
108 }
109}
110
111impl Renderable<ShapeCollection> for ShapeCollection {
112 fn render(&self, graphics: &mut Graphics) {
113 for shape in &self.shapes {
114 shape.render(graphics);
115 }
116 }
117}
118
119sized_renderable!(
120 RenderableShapeCollection,
121 ShapeCollection,
122 |col: &ShapeCollection| (col.bounds().width(), col.bounds().height()),
123 |g: &mut Graphics, col: &ShapeCollection| col.render(g)
124);
125
126impl InsertDrawable<ShapeBox> for ShapeCollection {
127 fn insert(&mut self, index: usize, drawable: Drawable<ShapeBox>) {
128 self.shapes.insert(index, drawable);
129 self.update_bounds();
130 }
131
132 fn insert_above(&mut self, drawable: Drawable<ShapeBox>) {
133 self.shapes.push(drawable);
134 self.update_bounds();
135 }
136
137 fn insert_under(&mut self, drawable: Drawable<ShapeBox>) {
138 InsertDrawable::<ShapeBox>::insert(self, 0, drawable);
139 }
140}
141
142impl<S: Shape> InsertShape<S> for ShapeCollection {
143 fn insert(&mut self, index: usize, shape: S, draw_type: DrawType) {
144 InsertShapeBox::insert(self, index, shape.to_shape_box(), draw_type);
145 }
146
147 fn insert_above(&mut self, shape: S, draw_type: DrawType) {
148 InsertShapeBox::insert_above(self, shape.to_shape_box(), draw_type);
149 }
150
151 fn insert_under(&mut self, shape: S, draw_type: DrawType) {
152 InsertShapeBox::insert_under(self, shape.to_shape_box(), draw_type);
153 }
154}
155
156impl InsertShapeBox for ShapeCollection {
157 fn insert(&mut self, index: usize, shape_box: ShapeBox, draw_type: DrawType) {
158 InsertDrawable::insert(self, index, Drawable::from_obj(shape_box, draw_type))
159 }
160
161 fn insert_above(&mut self, shape_box: ShapeBox, draw_type: DrawType) {
162 InsertDrawable::insert_above(self, Drawable::from_obj(shape_box, draw_type))
163 }
164
165 fn insert_under(&mut self, shape_box: ShapeBox, draw_type: DrawType) {
166 InsertDrawable::insert_under(self, Drawable::from_obj(shape_box, draw_type))
167 }
168}
169
170pub trait InsertDrawable<S: Clone>: InsertShapeBox {
171 fn insert(&mut self, index: usize, drawable: Drawable<S>);
172 fn insert_above(&mut self, drawable: Drawable<S>);
173 fn insert_under(&mut self, drawable: Drawable<S>);
174}
175
176pub trait InsertShape<S> {
177 fn insert(&mut self, index: usize, shape: S, draw_type: DrawType);
178 fn insert_above(&mut self, shape: S, draw_type: DrawType);
179 fn insert_under(&mut self, shape: S, draw_type: DrawType);
180}
181
182pub trait InsertShapeBox {
183 fn insert(&mut self, index: usize, shape_box: ShapeBox, draw_type: DrawType);
184 fn insert_above(&mut self, shape_box: ShapeBox, draw_type: DrawType);
185 fn insert_under(&mut self, shape_box: ShapeBox, draw_type: DrawType);
186}