use bevy::math::Vec2;
use lyon_tessellation::{
geom::Angle,
path::{
builder::WithSvg,
path::{Builder, BuilderImpl},
EndpointId,
},
};
use crate::{
entity::Path,
geometry::Geometry,
utils::{ToPoint, ToVector},
};
pub struct ShapePath(Builder);
impl ShapePath {
#[must_use]
pub fn new() -> Self {
Self(Builder::new())
}
#[allow(clippy::should_implement_trait)]
#[must_use]
pub fn add(mut self, shape: &impl Geometry) -> Self {
shape.add_geometry(&mut self.0);
self
}
#[must_use]
pub fn build(self) -> Path {
Path(self.0.build())
}
pub fn build_as(shape: &impl Geometry) -> Path {
Self::new().add(shape).build()
}
}
impl Default for ShapePath {
fn default() -> Self {
Self::new()
}
}
pub struct PathBuilder(WithSvg<BuilderImpl>);
impl PathBuilder {
#[must_use]
pub fn new() -> Self {
Self(Builder::new().with_svg())
}
#[must_use]
pub fn build(self) -> Path {
Path(self.0.build())
}
pub fn move_to(&mut self, to: Vec2) -> EndpointId {
self.0.move_to(to.to_point())
}
pub fn line_to(&mut self, to: Vec2) -> EndpointId {
self.0.line_to(to.to_point())
}
pub fn close(&mut self) {
self.0.close();
}
pub fn quadratic_bezier_to(&mut self, ctrl: Vec2, to: Vec2) -> EndpointId {
self.0.quadratic_bezier_to(ctrl.to_point(), to.to_point())
}
pub fn cubic_bezier_to(&mut self, ctrl1: Vec2, ctrl2: Vec2, to: Vec2) -> EndpointId {
self.0
.cubic_bezier_to(ctrl1.to_point(), ctrl2.to_point(), to.to_point())
}
pub fn arc(&mut self, center: Vec2, radii: Vec2, sweep_angle: f32, x_rotation: f32) {
self.0.arc(
center.to_point(),
radii.to_vector(),
Angle::radians(sweep_angle),
Angle::radians(x_rotation),
);
}
#[must_use]
pub fn current_position(&self) -> Vec2 {
let p = self.0.current_position();
Vec2::new(p.x, p.y)
}
}
impl Default for PathBuilder {
fn default() -> Self {
Self::new()
}
}