use bytemuck::{Pod, Zeroable};
use rootvg_core::color::PackedSrgb;
use rootvg_core::math::{Point, Rect, Size};
use crate::border::Border;
use crate::shadow::Shadow;
use crate::Radius;
#[derive(Default, Debug, Clone, Copy, PartialEq)]
pub struct SolidQuad {
pub bounds: Rect,
pub bg_color: PackedSrgb,
pub border: Border,
pub shadow: Shadow,
}
impl SolidQuad {
pub fn packed(&self) -> SolidQuadPrimitive {
SolidQuadPrimitive {
color: self.bg_color,
position: self.bounds.origin.into(),
size: self.bounds.size.into(),
border_color: self.border.color,
border_radius: self.border.radius.into(),
border_width: self.border.width,
shadow_color: self.shadow.color,
shadow_offset: self.shadow.offset.into(),
shadow_blur_radius: self.shadow.blur_radius,
}
}
pub fn builder(size: Size) -> SolidQuadBuilder {
SolidQuadBuilder::new(size)
}
}
pub struct SolidQuadBuilder {
quad: SolidQuad,
}
impl SolidQuadBuilder {
pub fn new(size: Size) -> Self {
Self {
quad: SolidQuad {
bounds: Rect {
origin: Point::new(0.0, 0.0),
size,
},
..Default::default()
},
}
}
pub fn position(mut self, position: Point) -> Self {
self.quad.bounds.origin = position;
self
}
pub fn bg_color(mut self, color: impl Into<PackedSrgb>) -> Self {
self.quad.bg_color = color.into();
self
}
pub fn border_color(mut self, color: impl Into<PackedSrgb>) -> Self {
self.quad.border.color = color.into();
self
}
pub fn border_width(mut self, width: f32) -> Self {
self.quad.border.width = width;
self
}
pub fn border_radius(mut self, radius: impl Into<Radius>) -> Self {
self.quad.border.radius = radius.into();
self
}
pub fn border(mut self, border: Border) -> Self {
self.quad.border = border;
self
}
pub fn shadow_color(mut self, color: impl Into<PackedSrgb>) -> Self {
self.quad.shadow.color = color.into();
self
}
pub fn shadow_offset(mut self, offset: Point) -> Self {
self.quad.shadow.offset = offset;
self
}
pub fn shadow_blur_radius(mut self, blur_radius: f32) -> Self {
self.quad.shadow.blur_radius = blur_radius;
self
}
pub fn shadow(mut self, shadow: Shadow) -> Self {
self.quad.shadow = shadow;
self
}
pub fn build(self) -> SolidQuad {
self.quad
}
}
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Pod, Zeroable)]
pub struct SolidQuadPrimitive {
pub color: PackedSrgb,
pub position: [f32; 2],
pub size: [f32; 2],
pub border_color: PackedSrgb,
pub border_radius: [f32; 4],
pub border_width: f32,
pub shadow_color: PackedSrgb,
pub shadow_offset: [f32; 2],
pub shadow_blur_radius: f32,
}
impl SolidQuadPrimitive {
pub fn new(quad: &SolidQuad) -> Self {
Self {
color: quad.bg_color,
position: quad.bounds.origin.into(),
size: quad.bounds.size.into(),
border_color: quad.border.color,
border_radius: quad.border.radius.into(),
border_width: quad.border.width,
shadow_color: quad.shadow.color,
shadow_offset: quad.shadow.offset.into(),
shadow_blur_radius: quad.shadow.blur_radius,
}
}
}
impl From<SolidQuad> for SolidQuadPrimitive {
fn from(q: SolidQuad) -> SolidQuadPrimitive {
q.packed()
}
}
impl<'a> From<&'a SolidQuad> for SolidQuadPrimitive {
fn from(q: &'a SolidQuad) -> SolidQuadPrimitive {
q.packed()
}
}
impl From<SolidQuadBuilder> for SolidQuadPrimitive {
fn from(q: SolidQuadBuilder) -> SolidQuadPrimitive {
q.build().packed()
}
}
impl From<SolidQuadBuilder> for SolidQuad {
fn from(q: SolidQuadBuilder) -> SolidQuad {
q.build()
}
}