godoru 0.1.0

UI Framework for Rust using Godot
use crate::Shader;

use super::super::{
    Align, Color, Container, ContainerDirection, ContainerWrap, CursorIcon, IntoSpacing, Justify,
    NoAction, SizeMode, Style, Ui, UiNode,
};

pub struct ContainerBuilder<'a, A = NoAction> {
    ui: &'a mut Ui<A>,
    container: Option<Container<A>>,
}

impl<'a, A: Clone> ContainerBuilder<'a, A> {
    pub(crate) fn new(ui: &'a mut Ui<A>) -> Self {
        Self {
            ui,
            container: Some(Container::new()),
        }
    }

    pub fn id(mut self, id: impl Into<String>) -> Self {
        if let Some(container) = self.container.as_mut() {
            container.id = Some(id.into());
        }
        self
    }

    pub fn key(mut self, key: impl Into<String>) -> Self {
        if let Some(container) = self.container.as_mut() {
            container.key = Some(key.into());
        }
        self
    }

    pub fn class(mut self, class: impl Into<String>) -> Self {
        if let Some(container) = self.container.as_mut() {
            container.class = Some(class.into());
        }
        self
    }

    pub fn direction(mut self, direction: ContainerDirection) -> Self {
        if let Some(container) = self.container.as_mut() {
            container.direction = direction;
        }
        self
    }

    pub fn wrap(mut self, wrap: ContainerWrap) -> Self {
        if let Some(container) = self.container.as_mut() {
            container.wrap = wrap;
        }
        self
    }

    pub fn padding(mut self, padding: impl IntoSpacing) -> Self {
        if let Some(container) = self.container.as_mut() {
            container.padding = Some(padding.intoSpacing());
        }
        self
    }

    pub fn margin(mut self, margin: impl IntoSpacing) -> Self {
        if let Some(container) = self.container.as_mut() {
            container.margin = Some(margin.intoSpacing());
        }
        self
    }

    pub fn gap(mut self, gap: u32) -> Self {
        if let Some(container) = self.container.as_mut() {
            container.gap = Some(gap);
        }
        self
    }

    pub fn customMinimumSize(mut self, width: u32, height: u32) -> Self {
        if let Some(container) = self.container.as_mut() {
            container.customMinimumSize = Some((width, height));
        }
        self
    }

    pub fn backgroundColor(mut self, color: Color) -> Self {
        if let Some(container) = self.container.as_mut() {
            container.style.background = Some(color);
        }
        self
    }

    pub fn size(mut self, width: SizeMode, height: SizeMode) -> Self {
        if let Some(container) = self.container.as_mut() {
            container.width = width;
            container.height = height;
        }
        self
    }

    pub fn align(mut self, align: Align) -> Self {
        if let Some(container) = self.container.as_mut() {
            container.align = align;
        }
        self
    }

    pub fn justify(mut self, justify: Justify) -> Self {
        if let Some(container) = self.container.as_mut() {
            container.justify = justify;
        }
        self
    }

    pub fn style(mut self, configure: impl FnOnce(&mut Style)) -> Self {
        if let Some(container) = self.container.as_mut() {
            configure(&mut container.style);
        }
        self
    }

    pub fn shader(mut self, shader: Shader) -> Self {
        if let Some(container) = self.container.as_mut() {
            container.style.shader = Some(shader);
        }
        self
    }

    pub fn onClick(mut self, action: A) -> Self {
        if let Some(container) = self.container.as_mut() {
            container.interactions.click = Some(action);
        }
        self
    }

    pub fn onHover(mut self, action: A) -> Self {
        if let Some(container) = self.container.as_mut() {
            container.interactions.hover = Some(action);
        }
        self
    }

    pub fn onUnhover(mut self, action: A) -> Self {
        if let Some(container) = self.container.as_mut() {
            container.interactions.unhover = Some(action);
        }
        self
    }

    pub fn onFocus(mut self, action: A) -> Self {
        if let Some(container) = self.container.as_mut() {
            container.interactions.focus = Some(action);
        }
        self
    }

    pub fn onBlur(mut self, action: A) -> Self {
        if let Some(container) = self.container.as_mut() {
            container.interactions.blur = Some(action);
        }
        self
    }

    pub fn onPointerDown(mut self, action: A) -> Self {
        if let Some(container) = self.container.as_mut() {
            container.interactions.pointerDown = Some(action);
        }
        self
    }

    pub fn onPointerUp(mut self, action: A) -> Self {
        if let Some(container) = self.container.as_mut() {
            container.interactions.pointerUp = Some(action);
        }
        self
    }

    pub fn cursor(mut self, cursor: CursorIcon) -> Self {
        if let Some(container) = self.container.as_mut() {
            container.cursor = Some(cursor);
        }
        self
    }

    pub fn children(mut self, build: impl FnOnce(&mut Ui<A>)) {
        if let Some(mut container) = self.container.take() {
            let mut ui = Ui::new();
            build(&mut ui);
            container.children = ui.nodes;
            self.ui.nodes.push(UiNode::Container(container));
        }
    }

    pub fn empty(mut self) {
        if let Some(container) = self.container.take() {
            self.ui.nodes.push(UiNode::Container(container));
        }
    }
}

impl<A> Drop for ContainerBuilder<'_, A> {
    fn drop(&mut self) {
        if let Some(container) = self.container.take() {
            self.ui.nodes.push(UiNode::Container(container));
        }
    }
}