use super::GridPosition;
use crate::error::ChartResult;
use embedded_graphics::{
pixelcolor::PixelColor,
prelude::*,
primitives::Rectangle,
};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct PanelId(pub u16);
pub type DrawFn<C> = Box<dyn Fn(Rectangle, &mut dyn DrawTarget<Color = C, Error = core::convert::Infallible>) -> ChartResult<()>>;
pub struct ChartPanel<C: PixelColor> {
id: PanelId,
position: GridPosition,
draw_fn: DrawFn<C>,
}
impl<C: PixelColor> ChartPanel<C> {
pub fn new(
id: PanelId,
position: GridPosition,
draw_fn: DrawFn<C>,
) -> Self {
Self {
id,
position,
draw_fn,
}
}
pub fn id(&self) -> PanelId {
self.id
}
pub fn position(&self) -> GridPosition {
self.position
}
pub fn draw<DT>(&self, viewport: Rectangle, target: &mut DT) -> ChartResult<()>
where
DT: DrawTarget<Color = C>,
{
let mut wrapper = DrawTargetWrapper { inner: target };
(self.draw_fn)(viewport, &mut wrapper)
}
}
struct DrawTargetWrapper<'a, DT> {
inner: &'a mut DT,
}
impl<'a, C, DT> DrawTarget for DrawTargetWrapper<'a, DT>
where
C: PixelColor,
DT: DrawTarget<Color = C>,
{
type Color = C;
type Error = core::convert::Infallible;
fn draw_iter<I>(&mut self, pixels: I) -> Result<(), Self::Error>
where
I: IntoIterator<Item = Pixel<Self::Color>>,
{
let _ = self.inner.draw_iter(pixels);
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
use embedded_graphics::pixelcolor::Rgb565;
#[test]
fn test_panel_creation() {
let draw_fn: DrawFn<Rgb565> = Box::new(|_viewport, _target| Ok(()));
let panel = ChartPanel::new(
PanelId(0),
GridPosition::new(0, 0),
draw_fn,
);
assert_eq!(panel.id(), PanelId(0));
assert_eq!(panel.position(), GridPosition::new(0, 0));
}
}