rust_native 1.4.0

A modern, cross-platform UI framework for building native applications
Documentation
use std::sync::Arc;
use crate::style::{Style, Color};
use crate::renderer::Renderer;
use crate::event::Event;
use crate::geometry::Rect;
use super::Component;

type ClickCallback = Arc<dyn Fn() + Send + Sync>;

pub struct Button {
    label: String,
    style: Style,
    bounds: Rect,
    on_click: Option<ClickCallback>,
}

impl Button {
    pub fn new<S: Into<String>>(label: S) -> Self {
        Self {
            label: label.into(),
            style: Style::default()
                .set_background(Color::rgb(0.2, 0.2, 0.2))
                .set_padding(10.0),
            bounds: Rect::default(),
            on_click: None,
        }
    }

    pub fn with_style(mut self, style: Style) -> Self {
        self.style = style;
        self
    }

    pub fn on_click<F>(mut self, callback: F) -> Self 
    where
        F: Fn() + Send + Sync + 'static
    {
        self.on_click = Some(Arc::new(callback));
        self
    }
}

impl Component for Button {
    fn render(&self, renderer: &mut dyn Renderer) {
        renderer.begin_group(&self.style);
        renderer.draw_text(&self.label, &self.style);
        renderer.end_group();
    }

    fn handle_event(&mut self, event: Event) {
        if let Event::Click { .. } = event {
            if let Some(callback) = &self.on_click {
                (callback)();
            }
        }
    }

    fn bounds(&self) -> Rect {
        self.bounds.clone()
    }

    fn apply_style(&mut self, style: Style) {
        self.style = style;
    }

    fn style_name(&self) -> &str {
        "button"
    }

    fn style_mut(&mut self) -> &mut Style {
        &mut self.style
    }

    fn style(&self) -> &Style {
        &self.style
    }
}