buffer_graphics_lib/
renderable_macros.rs

1use graphics_shapes::coord::Coord;
2
3#[macro_export]
4macro_rules! renderable {
5    ($name:ident, $struct_name:ty, $render:expr) => {
6        #[derive(Debug)]
7        pub struct $name {
8            xy: Coord,
9            item: $struct_name,
10        }
11
12        impl $name {
13            pub fn set_position<P: Into<Coord>>(&mut self, new_position: P) {
14                self.xy = new_position.into();
15            }
16
17            pub fn update_position<P: Into<Coord>>(&mut self, delta: P) {
18                self.xy = self.xy + delta.into();
19            }
20        }
21
22        impl Renderable<$struct_name> for $name {
23            fn render(&self, graphics: &mut Graphics) {
24                #[allow(clippy::redundant_closure_call)]
25                graphics.with_translate(self.xy, |g| $render(g, &self.item));
26            }
27        }
28    };
29}
30
31#[derive(Debug, Copy, Clone, Eq, PartialEq)]
32pub enum DrawOffset {
33    TopLeft,
34    Center,
35    Custom(Coord),
36}
37
38#[macro_export]
39macro_rules! sized_renderable {
40    ($name:ident, $struct_name:ty, $size:expr, $render:expr) => {
41        #[derive(Debug)]
42        pub struct $name {
43            xy: Coord,
44            offset: $crate::renderable_macros::DrawOffset,
45            item: $struct_name,
46        }
47
48        impl $name {
49            pub fn new<P: Into<Coord>>(
50                item: $struct_name,
51                pos: P,
52                draw_offset: $crate::renderable_macros::DrawOffset,
53            ) -> Self {
54                $name {
55                    xy: pos.into(),
56                    offset: draw_offset,
57                    item,
58                }
59            }
60        }
61
62        impl $name {
63            pub fn set_position<P: Into<Coord>>(&mut self, new_position: P) {
64                self.xy = new_position.into();
65            }
66
67            pub fn update_position<P: Into<Coord>>(&mut self, delta: P) {
68                self.xy = self.xy + delta.into();
69            }
70
71            pub fn set_offset(&mut self, offset: $crate::renderable_macros::DrawOffset) {
72                self.offset = offset;
73            }
74        }
75
76        impl Renderable<$struct_name> for $name {
77            fn render(&self, graphics: &mut Graphics) {
78                use std::ops::Neg;
79
80                #[allow(clippy::redundant_closure_call)]
81                let (width, height): (usize, usize) = $size(&self.item);
82                let offset = match self.offset {
83                    $crate::renderable_macros::DrawOffset::TopLeft => (0, 0).into(),
84                    $crate::renderable_macros::DrawOffset::Center => {
85                        (((width / 2) as isize).neg(), ((height / 2) as isize).neg()).into()
86                    }
87                    $crate::renderable_macros::DrawOffset::Custom(coord) => coord,
88                };
89
90                #[allow(clippy::redundant_closure_call)]
91                graphics.with_translate(self.xy + offset, |g| $render(g, &self.item));
92            }
93        }
94    };
95}