godoru 0.1.0

UI Framework for Rust using Godot
use crate::{FontHandle, Shader};

use super::{IntoSpacing, Spacing};

#[derive(Clone, Debug, PartialEq, Eq)]
pub enum FontWeight {
    Thin,
    ExtraLight,
    Light,
    Regular,
    Medium,
    SemiBold,
    Bold,
    ExtraBold,
    Black,
}

#[derive(Clone, Debug, PartialEq, Eq)]
pub enum VisualState {
    Normal,
    Hover,
    Pressed,
    Focus,
    Checked,
    Disabled,
}

#[derive(Clone, Debug, Default, PartialEq)]
pub struct Style {
    pub extends: Option<String>,
    pub background: Option<Color>,
    pub color: Option<Color>,
    pub padding: Option<Spacing>,
    pub margin: Option<Spacing>,
    pub radius: Option<u32>,
    pub border: Option<Border>,
    pub shadow: Option<Shadow>,
    pub fontSize: Option<u32>,
    pub font: Option<FontHandle>,
    pub fontWeight: Option<FontWeight>,
    pub shader: Option<Shader>,
}

impl Style {
    pub fn extends(&mut self, class: impl Into<String>) -> &mut Self {
        self.extends = Some(class.into());
        self
    }

    pub fn background(&mut self, color: Color) -> &mut Self {
        self.background = Some(color);
        self
    }

    pub fn color(&mut self, color: Color) -> &mut Self {
        self.color = Some(color);
        self
    }

    pub fn textColor(&mut self, color: Color) -> &mut Self {
        self.color = Some(color);
        self
    }

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

    pub fn paddingTop(&mut self, value: u32) -> &mut Self {
        self.padding = Some(self.padding.clone().unwrap_or_default().top(value));
        self
    }

    pub fn paddingRight(&mut self, value: u32) -> &mut Self {
        self.padding = Some(self.padding.clone().unwrap_or_default().right(value));
        self
    }

    pub fn paddingBottom(&mut self, value: u32) -> &mut Self {
        self.padding = Some(self.padding.clone().unwrap_or_default().bottom(value));
        self
    }

    pub fn paddingLeft(&mut self, value: u32) -> &mut Self {
        self.padding = Some(self.padding.clone().unwrap_or_default().left(value));
        self
    }

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

    pub fn marginTop(&mut self, value: u32) -> &mut Self {
        self.margin = Some(self.margin.clone().unwrap_or_default().top(value));
        self
    }

    pub fn marginRight(&mut self, value: u32) -> &mut Self {
        self.margin = Some(self.margin.clone().unwrap_or_default().right(value));
        self
    }

    pub fn marginBottom(&mut self, value: u32) -> &mut Self {
        self.margin = Some(self.margin.clone().unwrap_or_default().bottom(value));
        self
    }

    pub fn marginLeft(&mut self, value: u32) -> &mut Self {
        self.margin = Some(self.margin.clone().unwrap_or_default().left(value));
        self
    }

    pub fn radius(&mut self, radius: u32) -> &mut Self {
        self.radius = Some(radius);
        self
    }

    pub fn border(&mut self, color: Color, width: u32) -> &mut Self {
        self.border = Some(Border { color, width });
        self
    }

    pub fn shadow(&mut self, color: Color, size: u32, offsetX: f32, offsetY: f32) -> &mut Self {
        self.shadow = Some(Shadow {
            color,
            size,
            offsetX,
            offsetY,
        });
        self
    }

    pub fn fontSize(&mut self, size: u32) -> &mut Self {
        self.fontSize = Some(size);
        self
    }

    pub fn font(&mut self, font: FontHandle) -> &mut Self {
        self.font = Some(font);
        self
    }

    pub fn fontWeight(&mut self, weight: FontWeight) -> &mut Self {
        self.fontWeight = Some(weight);
        self
    }

    pub fn shader(&mut self, shader: Shader) -> &mut Self {
        self.shader = Some(shader);
        self
    }
}

#[derive(Clone, Debug, PartialEq)]
pub struct Border {
    pub color: Color,
    pub width: u32,
}

#[derive(Clone, Debug, PartialEq)]
pub struct Shadow {
    pub color: Color,
    pub size: u32,
    pub offsetX: f32,
    pub offsetY: f32,
}

#[derive(Clone, Debug, PartialEq)]
pub struct Color {
    pub red: f32,
    pub green: f32,
    pub blue: f32,
    pub alpha: f32,
}

impl Color {
    pub fn rgba(red: f32, green: f32, blue: f32, alpha: f32) -> Self {
        Self {
            red,
            green,
            blue,
            alpha,
        }
    }

    pub fn rgb(red: f32, green: f32, blue: f32) -> Self {
        Self::rgba(red, green, blue, 1.0)
    }
}

pub(crate) fn mergeStyle(target: &mut Style, local: &Style) {
    if local.extends.is_some() {
        target.extends = local.extends.clone();
    }
    if local.background.is_some() {
        target.background = local.background.clone();
    }
    if local.color.is_some() {
        target.color = local.color.clone();
    }
    if local.padding.is_some() {
        target.padding = local.padding.clone();
    }
    if local.margin.is_some() {
        target.margin = local.margin.clone();
    }
    if local.radius.is_some() {
        target.radius = local.radius;
    }
    if local.border.is_some() {
        target.border = local.border.clone();
    }
    if local.shadow.is_some() {
        target.shadow = local.shadow.clone();
    }
    if local.fontSize.is_some() {
        target.fontSize = local.fontSize;
    }
    if local.font.is_some() {
        target.font = local.font.clone();
    }
    if local.fontWeight.is_some() {
        target.fontWeight = local.fontWeight.clone();
    }
    if local.shader.is_some() {
        target.shader = local.shader.clone();
    }
}