use lyon::tessellation::{LineCap, LineJoin, StrokeOptions};
use crate::draw::{Draw, drawing};
pub trait SetStroke: Sized {
fn stroke_options_mut(&mut self) -> &mut StrokeOptions;
fn stroke_opts(mut self, opts: StrokeOptions) -> Self {
*self.stroke_options_mut() = opts;
self
}
fn start_cap(mut self, cap: LineCap) -> Self {
self.stroke_options_mut().start_cap = cap;
self
}
fn end_cap(mut self, cap: LineCap) -> Self {
self.stroke_options_mut().end_cap = cap;
self
}
fn caps(self, cap: LineCap) -> Self {
self.start_cap(cap).end_cap(cap)
}
fn start_cap_butt(self) -> Self {
self.start_cap(LineCap::Butt)
}
fn start_cap_square(self) -> Self {
self.start_cap(LineCap::Square)
}
fn start_cap_round(self) -> Self {
self.start_cap(LineCap::Round)
}
fn end_cap_butt(self) -> Self {
self.end_cap(LineCap::Butt)
}
fn end_cap_square(self) -> Self {
self.end_cap(LineCap::Square)
}
fn end_cap_round(self) -> Self {
self.end_cap(LineCap::Round)
}
fn caps_butt(self) -> Self {
self.caps(LineCap::Butt)
}
fn caps_square(self) -> Self {
self.caps(LineCap::Square)
}
fn caps_round(self) -> Self {
self.caps(LineCap::Round)
}
fn join(mut self, join: LineJoin) -> Self {
self.stroke_options_mut().line_join = join;
self
}
fn join_miter(self) -> Self {
self.join(LineJoin::Miter)
}
fn join_miter_clip(self) -> Self {
self.join(LineJoin::MiterClip)
}
fn join_round(self) -> Self {
self.join(LineJoin::Round)
}
fn join_bevel(self) -> Self {
self.join(LineJoin::Bevel)
}
fn stroke_weight(mut self, stroke_weight: f32) -> Self {
self.stroke_options_mut().line_width = stroke_weight;
self
}
fn miter_limit(mut self, limit: f32) -> Self {
self.stroke_options_mut().miter_limit = limit;
self
}
fn stroke_tolerance(mut self, tolerance: f32) -> Self {
self.stroke_options_mut().tolerance = tolerance;
self
}
}
impl SetStroke for Option<StrokeOptions> {
fn stroke_options_mut(&mut self) -> &mut StrokeOptions {
self.get_or_insert_with(Default::default)
}
}
pub(crate) enum Update {
Opts(StrokeOptions),
StartCap(LineCap),
EndCap(LineCap),
Caps(LineCap),
Join(LineJoin),
Weight(f32),
MiterLimit(f32),
Tolerance(f32),
}
pub(crate) fn set_stroke(draw: &Draw, index: usize, update: Update) {
drawing::with_primitive(draw, index, |prim| match prim.stroke_options_mut() {
Some(opts) => apply_update(opts, update),
None => bevy::log::warn_once!("drawing primitive does not support `stroke` options"),
})
}
fn apply_update(opts: &mut StrokeOptions, update: Update) {
match update {
Update::Opts(new) => *opts = new,
Update::StartCap(cap) => opts.start_cap = cap,
Update::EndCap(cap) => opts.end_cap = cap,
Update::Caps(cap) => {
opts.start_cap = cap;
opts.end_cap = cap;
}
Update::Join(join) => opts.line_join = join,
Update::Weight(weight) => opts.line_width = weight,
Update::MiterLimit(limit) => opts.miter_limit = limit,
Update::Tolerance(tolerance) => opts.tolerance = tolerance,
}
}