ptsd2 0.1.2

Crate built to bridge design systems to Prism
Documentation
use prism::event::{self, OnEvent, Event};
use prism::drawable::{Drawable, Component, SizedTree};
use prism::display::Enum;
use prism::layout::Stack;
use prism::{emitters, Context, Request, Hardware};

use std::sync::{Arc, Mutex};

#[derive(Component, Clone, Debug)]
pub struct Toggle(Stack, emitters::Button<_Toggle>);
impl OnEvent for Toggle {}
impl Toggle {
    pub fn new(
        on: impl Drawable + 'static,
        off: impl Drawable + 'static,
        is_selected: bool,
        on_click: impl FnMut(&mut Context, bool) + Send + Sync + 'static,
    ) -> Self {
        let toggle = _Toggle::new(on, off, is_selected, on_click);
        Self(Stack::default(), emitters::Button::new(toggle))
    }
}

impl std::ops::Deref for Toggle {
    type Target = _Toggle;
    fn deref(&self) -> &Self::Target {&self.1.1}
}

impl std::ops::DerefMut for Toggle {
    fn deref_mut(&mut self) -> &mut Self::Target {&mut self.1.1}
}

#[derive(Component, Clone)]
pub struct _Toggle(Stack, Enum<Box<dyn Drawable>>, #[skip] bool, #[skip] ToggleCallback);

impl _Toggle {
    pub fn new(
        on: impl Drawable + 'static,
        off: impl Drawable + 'static,
        is_selected: bool,
        on_click: impl FnMut(&mut Context, bool) + Send + Sync + 'static,
    ) -> Self {
        let start = if is_selected {"on"} else {"off"};
        _Toggle(Stack::default(), 
            Enum::new(vec![("on".to_string(), Box::new(on)), ("off".to_string(), Box::new(off))], start.to_string()), 
            !is_selected, Arc::new(Mutex::new(on_click))
        )
    }
}

impl OnEvent for _Toggle {
    fn on_event(&mut self, ctx: &mut Context, _sized: &SizedTree, event: Box<dyn Event>) -> Vec<Box<dyn Event>> {
        if let Some(event::Button::Pressed(true)) = event.downcast_ref::<event::Button>() {
            self.2 = !self.2;
            ctx.send(Request::Hardware(Hardware::Haptic));
            if let Ok(mut cb) = self.3.lock() { (cb)(ctx, !self.2); }
            match self.2 {
                false => self.1.display("on"),
                true => self.1.display("off"),
            }
        }
        Vec::new()
    }
}

impl std::fmt::Debug for _Toggle {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "_Toggle")
    }
}


type ToggleCallback = Arc<Mutex<dyn FnMut(&mut Context, bool) + Send + Sync + 'static>>;