cosg 0.1.1

A wgpu-based UI library with a dark violet theme
Documentation
use crate::{
    esc::Esc,
    theme::Theme,
    widget::{DrawRect, Rect, TextCmd, Widget, WidgetEvent},
};

pub struct Container {
    children: Vec<Box<dyn Widget>>,
    esc:      Esc,
    padding:  f32,
    rect:     Rect,
}

impl Container {
    pub fn new() -> Self {
        Self { children: vec![], esc: Esc::default(), padding: 8.0, rect: Rect::default() }
    }
    pub fn padding(mut self, p: f32) -> Self { self.padding = p; self }
    pub fn esc(mut self, e: Esc) -> Self { self.esc = e; self }
    pub fn add(mut self, widget: impl Widget + 'static) -> Self {
        self.children.push(Box::new(widget)); self
    }
}

impl Widget for Container {
    fn layout(&mut self, bounds: Rect, theme: &Theme) {
        self.rect = bounds;
        let inner = Rect {
            x: bounds.x + self.padding,
            y: bounds.y + self.padding,
            w: bounds.w - self.padding * 2.0,
            h: bounds.h - self.padding * 2.0,
        };
        let child_h = if self.children.is_empty() { 0.0 } else {
            (inner.h - self.padding * (self.children.len() - 1) as f32)
                / self.children.len() as f32
        };
        let mut cy = inner.y;
        for child in &mut self.children {
            child.layout(Rect::new(inner.x, cy, inner.w, child_h), theme);
            cy += child_h + self.padding;
        }
    }

    fn draw(&self, theme: &Theme) -> Vec<DrawRect> {
        let mut out = vec![DrawRect {
            rect:          self.rect,
            color:         theme.surface,
            border_radius: self.esc.border_radius,
            border_width:  self.esc.border_width,
            border_color:  self.esc.border_color.unwrap_or(theme.border),
        }];
        for child in &self.children { out.extend(child.draw(theme)); }
        out
    }

    fn draw_text(&self, theme: &Theme) -> Vec<TextCmd> {
        self.children.iter().flat_map(|c| c.draw_text(theme)).collect()
    }

    fn handle_event(&mut self, event: &WidgetEvent) {
        for child in &mut self.children { child.handle_event(event); }
    }

    fn rect(&self) -> Rect { self.rect }
}