buffer_graphics_lib/
renderable_macros.rs1use 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}