use crate::ffi;
use crate::{LedCanvas, LedMatrixOptions, LedRuntimeOptions};
#[cfg(feature = "embeddedgraphics")]
use embedded_graphics_core::{
draw_target::DrawTarget,
geometry::{Dimensions, Point, Size},
pixelcolor::Rgb888,
primitives::Rectangle,
Pixel,
};
pub struct LedMatrix {
handle: *mut ffi::CLedMatrix,
_options: LedMatrixOptions,
}
impl LedMatrix {
pub fn new(
options: Option<LedMatrixOptions>,
rt_options: Option<LedRuntimeOptions>,
) -> Result<Self, &'static str> {
let mut options = options.unwrap_or_default();
let mut rt_options = rt_options.unwrap_or_default();
let handle = unsafe {
ffi::led_matrix_create_from_options_and_rt_options(
&mut options.0 as *mut ffi::CLedMatrixOptions,
&mut rt_options.0 as *mut ffi::CLedRuntimeOptions,
)
};
if handle.is_null() {
Err("Couldn't create LedMatrix")
} else {
Ok(Self {
handle,
_options: options,
})
}
}
#[must_use]
pub fn canvas(&self) -> LedCanvas {
let handle = unsafe { ffi::led_matrix_get_canvas(self.handle) };
LedCanvas { handle }
}
#[must_use]
pub fn offscreen_canvas(&self) -> LedCanvas {
let handle = unsafe { ffi::led_matrix_create_offscreen_canvas(self.handle) };
LedCanvas { handle }
}
#[must_use]
#[allow(clippy::needless_pass_by_value)]
pub fn swap(&self, canvas: LedCanvas) -> LedCanvas {
let handle = unsafe { ffi::led_matrix_swap_on_vsync(self.handle, canvas.handle) };
LedCanvas { handle }
}
}
impl Drop for LedMatrix {
fn drop(&mut self) {
unsafe {
ffi::led_matrix_delete(self.handle);
}
}
}
#[cfg(feature = "embeddedgraphics")]
impl DrawTarget for LedCanvas {
type Color = Rgb888;
type Error = core::convert::Infallible;
fn draw_iter<I>(&mut self, pixels: I) -> Result<(), Self::Error>
where
I: IntoIterator<Item = Pixel<Self::Color>>,
{
for px in pixels {
self.set(px.0.x, px.0.y, &px.1.into());
}
Ok(())
}
fn clear(&mut self, color: Self::Color) -> Result<(), Self::Error> {
self.fill(&color.into());
Ok(())
}
}
#[cfg(feature = "embeddedgraphics")]
impl Dimensions for LedCanvas {
fn bounding_box(&self) -> Rectangle {
let size = self.canvas_size();
Rectangle::new(Point::new(0, 0), Size::new(size.0 as u32, size.1 as u32))
}
}
#[cfg(test)]
mod tests {
use super::*;
fn led_matrix() -> LedMatrix {
let mut options = LedMatrixOptions::new();
let mut rt_options = LedRuntimeOptions::new();
options.set_hardware_mapping("adafruit-hat-pwm");
options.set_chain_length(2);
options.set_hardware_pulsing(false);
options.set_refresh_rate(true);
options.set_brightness(10).unwrap();
rt_options.set_gpio_slowdown(2);
LedMatrix::new(Some(options), Some(rt_options)).unwrap()
}
#[test]
#[serial_test::serial]
fn matrix_create() {
let _matrix = led_matrix();
}
}