use crate::geometry::{Constraints, Rect, Transform, Vec2};
use crate::vector::{
Fill, Group, Node, Paint, Path, PathCommand, Stroke, VectorComponent, VectorGraphic,
};
use crate::Keyable;
#[crate::component(vector)]
#[derive(Keyable)]
pub struct DecoratedBox {
#[builder(into)]
pub child: Box<dyn VectorComponent>,
#[builder(into)]
pub background: Option<Paint>,
#[builder(into)]
pub border: Option<Stroke>,
}
impl VectorComponent for DecoratedBox {
fn layout(&self, constraints: Constraints) -> Vec2 {
self.child.layout(constraints)
}
fn render(&self, size: Vec2) -> VectorGraphic {
let inner = self.child.render(size);
let mut children: Vec<Node> = Vec::new();
if self.background.is_some() || self.border.is_some() {
children.push(Node::Path(Path {
commands: vec![
PathCommand::MoveTo(Vec2(0.0, 0.0)),
PathCommand::LineTo(Vec2(size.0, 0.0)),
PathCommand::LineTo(Vec2(size.0, size.1)),
PathCommand::LineTo(Vec2(0.0, size.1)),
PathCommand::Close,
],
fill: self.background.clone().map(|paint| Fill { paint }),
stroke: self.border.clone(),
transform: Transform::IDENTITY,
}));
}
children.push(inner.root);
VectorGraphic {
view_box: Rect {
origin: Vec2::ZERO,
size,
},
root: Node::Group(Group {
transform: Transform::IDENTITY,
opacity: 1.0,
children,
}),
}
}
}
pub(super) mod raster {
use crate::color::Color;
use crate::geometry::{Constraints, Rect, Vec2};
use crate::layer::composite_children;
use crate::raster::{Background, RasterComponent, RasterImage, Resolution};
use crate::render_context::RenderContext;
use crate::Keyable;
#[crate::component(raster)]
#[derive(Keyable)]
pub struct DecoratedBox {
#[builder(into)]
pub child: Box<dyn RasterComponent>,
#[builder(into)]
pub background: Option<Color>,
}
impl RasterComponent for DecoratedBox {
fn layout(&self, constraints: Constraints) -> Vec2 {
self.child.layout(constraints)
}
fn render(
&self,
size: Vec2,
target: Resolution,
ctx: &mut dyn RenderContext,
) -> RasterImage {
let paint_rect = Rect {
origin: Vec2::ZERO,
size,
};
match self.background {
Some(color) => {
let bg = Background::new(color);
let placed: Vec<(Vec2, Vec2, &dyn RasterComponent)> = vec![
(Vec2::ZERO, size, &bg as &dyn RasterComponent),
(Vec2::ZERO, size, self.child.as_ref()),
];
composite_children(paint_rect, target, &placed, ctx)
}
None => composite_children(
paint_rect,
target,
&[(Vec2::ZERO, size, self.child.as_ref())],
ctx,
),
}
}
}
}