aura-gui 0.2.2

UI nativa acelerada por GPU para escritorio, Android e iOS, en un solo crate: estilo tipo Tailwind, componentes, sombras, animaciones y agentes de IA. Reposo a cero. Licencia AGPL-3.0 o comercial.
//! Elemento `canvas`: pinta con un cierre sobre el rectángulo que le toca, para gráficos pequeños
//! (barras de uso, minigráficos) sin crear un elemento por cada pieza.

use crate::core::Bounds;
use crate::view::context::ElementContext;
use crate::view::element::Element;
use crate::view::style::Style;
use crate::view::styled::Styled;
use taffy::NodeId;

type PaintFn = Box<dyn FnMut(Bounds, &mut ElementContext)>;

pub struct Canvas {
    paint: PaintFn,
    style: Style,
    node: Option<NodeId>,
}

/// `paint` recibe el rectángulo del elemento ya maquetado y dibuja con las operaciones de `ElementContext`.
pub fn canvas(paint: impl FnMut(Bounds, &mut ElementContext) + 'static) -> Canvas {
    Canvas { paint: Box::new(paint), style: Style::default(), node: None }
}

impl Styled for Canvas {
    fn style(&mut self) -> &mut Style {
        &mut self.style
    }
}

impl Element for Canvas {
    fn request_layout(&mut self, cx: &mut ElementContext) -> NodeId {
        let node = cx.request_node(&self.style, &[]);
        self.node = Some(node);
        node
    }

    fn prepaint(&mut self, _cx: &mut ElementContext) {}

    fn paint(&mut self, cx: &mut ElementContext) {
        let Some(node) = self.node else { return };
        let bounds = cx.node_bounds(node);
        cx.with_mask(bounds, |cx| (self.paint)(bounds, cx));
    }
}