1use std::marker::PhantomData;
2use std::num::Saturating;
3
4use embedded_graphics::draw_target::DrawTarget;
5use embedded_graphics::geometry::Point;
6use embedded_graphics::prelude::{PixelColor, Size};
7use embedded_graphics::primitives::Rectangle;
8
9use crate::prelude::Layoutable;
10use crate::ComponentSize;
11
12pub fn padding<C: PixelColor, L: Layoutable<C>>(
37 layoutable: L,
38 top: i32,
39 right: i32,
40 bottom: i32,
41 left: i32,
42) -> impl Layoutable<C> {
43 Padding {
44 layoutable,
45 top,
46 right,
47 bottom,
48 left,
49 p: Default::default(),
50 }
51}
52
53struct Padding<C: PixelColor, L: Layoutable<C>> {
54 layoutable: L,
55 top: i32,
56 right: i32,
57 bottom: i32,
58 left: i32,
59 p: PhantomData<C>,
60}
61
62impl<C: PixelColor, L: Layoutable<C>> Layoutable<C> for Padding<C, L> {
63 fn size(&self) -> ComponentSize {
64 let ComponentSize { width, height } = self.layoutable.size();
65 ComponentSize {
66 width: width + (self.left + self.right),
67 height: height + (self.top + self.bottom),
68 }
69 }
70
71 fn draw_placed<DrawError>(
72 &self,
73 target: &mut impl DrawTarget<Color = C, Error = DrawError>,
74 position: Rectangle,
75 ) -> Result<(), DrawError> {
76 let Rectangle {
77 top_left: Point { x, y },
78 size: Size { width, height },
79 } = position;
80 let position = Rectangle {
81 top_left: Point {
82 x: x + self.left,
83 y: y + self.top,
84 },
85 size: Size {
86 width: (Saturating(width as i32) - Saturating(self.left + self.right)).0 as u32,
87 height: (Saturating(height as i32) - Saturating(self.top + self.bottom)).0 as u32,
88 },
89 };
90 self.layoutable.draw_placed(target, position)
91 }
92}