simple_layout/
placement.rs1use std::marker::PhantomData;
2use std::ops::DerefMut;
3use std::sync::Mutex;
4
5use embedded_graphics::draw_target::DrawTarget;
6use embedded_graphics::pixelcolor::PixelColor;
7use embedded_graphics::primitives::Rectangle;
8#[cfg(feature = "log")]
9use log::warn;
10
11use crate::layoutable::Layoutable;
12use crate::ComponentSize;
13
14pub fn callback_placement<L: Layoutable<C>, C: PixelColor, F: FnMut(Rectangle)>(
26 callback: F,
27 layoutable: L,
28) -> impl Layoutable<C> {
29 CallbackPlacement {
30 callback: Mutex::new(callback),
31 layoutable,
32 p: PhantomData,
33 }
34}
35pub fn optional_placement<'a, L: Layoutable<C> + 'a, C: PixelColor + 'a>(
46 target: &'a mut Option<Rectangle>,
47 layoutable: L,
48) -> impl Layoutable<C> + 'a {
49 callback_placement(|rectangle: Rectangle| *target = Some(rectangle), layoutable)
50}
51
52struct CallbackPlacement<L: Layoutable<C>, C: PixelColor, F: FnMut(Rectangle)> {
53 callback: Mutex<F>,
54 layoutable: L,
55 p: PhantomData<C>,
56}
57
58impl<L: Layoutable<C>, C: PixelColor, F: FnMut(Rectangle)> Layoutable<C>
59 for CallbackPlacement<L, C, F>
60{
61 fn size(&self) -> ComponentSize {
62 self.layoutable.size()
63 }
64
65 fn draw_placed<DrawError>(
66 &self,
67 target: &mut impl DrawTarget<Color = C, Error = DrawError>,
68 position: Rectangle,
69 ) -> Result<(), DrawError> {
70 if let Ok(mut mutex) = self.callback.try_lock() {
71 (mutex.deref_mut())(position);
72 } else {
73 #[cfg(feature = "log")]
74 warn!("Cannot lock callback");
75 }
76 self.layoutable.draw_placed(target, position)
77 }
78}