1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
mod batch; mod circle; mod fill; mod geometry; mod path; mod stroke; pub use self::{batch::*, fill::*, path::*, stroke::*}; use crate::{ math::{Point, Points, Raw, Rect, Scaled}, scene::{Element, SceneTarget}, KludgineResult, }; use circle::Circle; use geometry::ShapeGeometry; #[derive(Default, Clone)] pub struct Shape<S> { geometry: ShapeGeometry<S>, stroke: Option<Stroke>, fill: Option<Fill>, } impl Shape<Scaled> { pub fn rect(rect: impl Into<Rect<f32, Scaled>>) -> Self { let rect = rect.into(); let path = PathBuilder::new(Point::new(rect.min_x(), rect.min_y())) .line_to(Point::new(rect.max_x(), rect.min_y())) .line_to(Point::new(rect.max_x(), rect.max_y())) .line_to(Point::new(rect.min_x(), rect.max_y())) .close() .build(); Self { geometry: ShapeGeometry::Path(path), stroke: None, fill: None, } } pub fn circle(center: Point<f32, Scaled>, radius: Points) -> Self { Self { geometry: ShapeGeometry::Circle(Circle { center, radius }), stroke: None, fill: None, } } pub fn polygon(points: impl IntoIterator<Item = Point<f32, Scaled>>) -> Self { let mut points = points.into_iter(); if let Some(start) = points.next() { let mut builder = PathBuilder::new(start); for point in points { builder = builder.line_to(point); } Self { geometry: ShapeGeometry::Path(builder.close().build()), stroke: None, fill: None, } } else { Self::default() } } pub fn fill(mut self, fill: Fill) -> Self { self.fill = Some(fill); self } pub fn stroke(mut self, stroke: Stroke) -> Self { self.stroke = Some(stroke); self } pub async fn draw_at(&self, location: Point<f32, Scaled>, scene: &SceneTarget) { let translated = self.convert_from_user_to_device(location, scene).await; scene.push_element(Element::Shape(translated)).await } async fn convert_from_user_to_device( &self, location: Point<f32, Scaled>, scene: &SceneTarget, ) -> Shape<Raw> { Shape { geometry: self .geometry .translate_and_convert_to_device(location, scene) .await, fill: self.fill.clone(), stroke: self.stroke.clone(), } } } impl Shape<Raw> { pub(crate) fn build(&self, builder: &mut rgx_lyon::ShapeBuilder) -> KludgineResult<()> { self.geometry.build(builder, &self.stroke, &self.fill) } }