milk_tea/
area.rs

1use crate::{
2    draw_call::{DrawCall, DrawCalls, NonAbsolute},
3    pair::*,
4    rect::Rect,
5};
6
7#[derive(Debug, Clone, PartialEq, Eq)]
8pub struct Area {
9    rect: Rect,
10    calls: DrawCalls,
11}
12
13impl Area {
14    pub fn new(rect: Rect) -> Self {
15        Self {
16            rect,
17            calls: DrawCalls::new(),
18        }
19    }
20
21    pub fn rect(&self) -> Rect {
22        self.rect.with_pos(Pair::fill(0))
23    }
24
25    pub fn size(&self) -> Pair<Size> {
26        self.rect.size
27    }
28
29    pub fn center(&self) -> Pair<Pos> {
30        self.rect.with_pos(Pair::fill(0)).center()
31    }
32
33    pub fn center_rect(&self, rect: Rect) -> Rect {
34        rect.center_in(self.rect())
35    }
36
37    pub fn push(&mut self, call: DrawCall<NonAbsolute>) {
38        let _ = self.try_push(call);
39    }
40
41    pub fn push_all(&mut self, calls: Vec<DrawCall<NonAbsolute>>) {
42        let _ = self.try_push_all(calls);
43    }
44
45    pub fn try_push(&mut self, call: DrawCall<NonAbsolute>) -> Result<(), AreaOverflowError> {
46        if let Some(absolute) = call.to_absolute(self.rect) {
47            self.calls.push(absolute);
48
49            return Ok(());
50        }
51
52        Err(AreaOverflowError)
53    }
54
55    pub fn try_push_all(
56        &mut self,
57        calls: Vec<DrawCall<NonAbsolute>>,
58    ) -> Result<(), AreaOverflowError> {
59        for call in calls {
60            self.try_push(call)?;
61        }
62
63        Ok(())
64    }
65
66    pub fn push_element(&mut self, rect: Rect, element: Element) {
67        let _ = self.try_push_element(rect, element);
68    }
69
70    pub fn try_push_element(
71        &mut self,
72        rect: Rect,
73        element: Element,
74    ) -> Result<(), AreaOverflowError> {
75        let mut area = Area::new(rect.map_pos(|pos| pos + self.rect.pos));
76
77        if !area.rect.is_inside(self.rect) {
78            return Err(AreaOverflowError);
79        }
80
81        element(&mut area);
82
83        self.calls.extend(area.collect());
84
85        Ok(())
86    }
87
88    pub(crate) fn collect(self) -> DrawCalls {
89        self.calls
90    }
91}
92
93#[derive(Debug)]
94pub struct AreaOverflowError;
95
96pub type Element = Box<dyn Fn(&mut Area)>;