use core::fmt::Debug;
use embedded_graphics::draw_target::DrawTarget;
use ratatui_core::backend::Backend;
use crate::backend::DrawTargetBackend;
use crate::wrapper::WrapTrait;
use crate::wrapper::traits;
#[derive(Debug, Clone, PartialEq, Eq, Copy)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct Blinked(pub bool);
#[derive(Debug, Clone, Copy)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum Blink {
Repeat(usize, usize),
}
pub trait ControlBlinking<D: DrawTarget>
where
Self: DrawTargetBackend<D>,
{
fn blinking(&self) -> bool;
fn start_blinking(&mut self);
fn stop_blinking(&mut self);
fn advance_blink(&mut self) -> Result<(), Self::Error> {
self.advance_blink_by(1)
}
}
pub trait ControlCursorBlinking
where
Self: Backend,
{
fn advance_cursor_blink_to(&mut self, blinked: Blinked) -> Result<(), Self::Error>;
}
impl Blink {
pub const fn with_period(period: usize) -> Self {
let blink = period / 2;
let delay = period - blink;
Self::Repeat(delay, blink)
}
pub const fn get(&self, index: usize) -> Blinked {
match *self {
Self::Repeat(delay, blink) => {
if let Some(period) = delay.checked_add(blink) {
if let Some(index) = index.checked_rem(period) {
Blinked(index >= delay)
} else {
Blinked(true)
}
} else {
Blinked(index >= delay)
}
}
}
}
}
impl<W, B, D> ControlBlinking<D> for W
where
B: ControlBlinking<D>,
D: DrawTarget,
D::Error: Debug,
W: DrawTargetBackend<D, Error = B::Error>,
W: WrapTrait<traits::ControlBlinking, Inner = B>,
{
fn blinking(&self) -> bool {
self.inner().blinking()
}
fn start_blinking(&mut self) {
self.inner_mut().start_blinking();
}
fn stop_blinking(&mut self) {
self.inner_mut().stop_blinking();
}
fn advance_blink(&mut self) -> Result<(), Self::Error> {
self.inner_mut().advance_blink()
}
}
impl<W, B> ControlCursorBlinking for W
where
B: ControlCursorBlinking,
W: Backend<Error = B::Error>,
W: WrapTrait<traits::ControlCursorBlinking, Inner = B>,
{
fn advance_cursor_blink_to(&mut self, blinked: Blinked) -> Result<(), Self::Error> {
self.inner_mut().advance_cursor_blink_to(blinked)
}
}