use crate::{prelude::*, renderer::Rendering};
use std::iter::Iterator;
#[macro_use]
pub mod ellipse;
#[macro_use]
pub mod line;
#[macro_use]
pub mod point;
#[macro_use]
pub mod rect;
#[macro_use]
pub mod quad;
#[macro_use]
pub mod sphere;
#[macro_use]
pub mod triangle;
#[doc(inline)]
pub use ellipse::*;
#[doc(inline)]
pub use line::*;
#[doc(inline)]
pub use point::*;
#[doc(inline)]
pub use quad::*;
#[doc(inline)]
pub use rect::*;
#[doc(inline)]
pub use sphere::*;
#[doc(inline)]
pub use triangle::*;
pub trait Contains<S> {
fn contains(&self, shape: S) -> bool;
}
pub trait Intersects<S> {
type Result;
fn intersects(&self, shape: S) -> Option<Self::Result>;
}
impl PixState {
pub fn point<P>(&mut self, p: P) -> PixResult<()>
where
P: Into<Point<i32>>,
{
if let Some(stroke) = self.settings.stroke {
self.renderer.point(p.into(), stroke)?;
}
Ok(())
}
pub fn line<L>(&mut self, line: L) -> PixResult<()>
where
L: Into<Line<i32>>,
{
let s = &self.settings;
if let Some(stroke) = s.stroke {
self.renderer
.line(line.into(), s.smooth, s.stroke_weight as u8, stroke)?;
}
Ok(())
}
pub fn bezier<P, I>(&mut self, points: I) -> PixResult<()>
where
P: Into<Point<i32>>,
I: IntoIterator<Item = P>,
{
let s = &self.settings;
self.renderer.bezier(
points.into_iter().map(Into::into),
s.bezier_detail,
s.stroke,
)
}
pub fn triangle<T>(&mut self, tri: T) -> PixResult<()>
where
T: Into<Tri<i32>>,
{
let s = &self.settings;
self.renderer
.triangle(tri.into(), s.smooth, s.fill, s.stroke)
}
#[doc(alias = "rect")]
pub fn square<R>(&mut self, square: R) -> PixResult<()>
where
R: Into<Rect<i32>>,
{
self.rect(square)
}
#[doc(alias = "rounded_rect")]
pub fn rounded_square<R>(&mut self, square: R, radius: i32) -> PixResult<()>
where
R: Into<Rect<i32>>,
{
self.rounded_rect(square, radius)
}
pub fn rect<R>(&mut self, rect: R) -> PixResult<()>
where
R: Into<Rect<i32>>,
{
let s = &self.settings;
let rect = self.get_rect(rect);
self.renderer.rect(rect, None, s.fill, s.stroke)
}
pub fn rounded_rect<R>(&mut self, rect: R, radius: i32) -> PixResult<()>
where
R: Into<Rect<i32>>,
{
let s = &self.settings;
let rect = self.get_rect(rect);
self.renderer.rect(rect, Some(radius), s.fill, s.stroke)
}
pub fn quad<Q>(&mut self, quad: Q) -> PixResult<()>
where
Q: Into<Quad<i32>>,
{
let s = &self.settings;
self.renderer.quad(quad.into(), s.smooth, s.fill, s.stroke)
}
pub fn polygon<P, I>(&mut self, points: I) -> PixResult<()>
where
P: Into<Point<i32>>,
I: IntoIterator<Item = P>,
{
let s = &self.settings;
self.renderer.polygon(
points.into_iter().map(Into::into),
s.smooth,
s.fill,
s.stroke,
)
}
pub fn wireframe<V, P1, P2, A, S>(
&mut self,
vertexes: V,
pos: P2,
angle: A,
scale: S,
) -> PixResult<()>
where
V: IntoIterator<Item = P1>,
P1: Into<Point<f64>>,
P2: Into<Point<i32>>,
A: Into<Option<f64>>,
S: Into<Option<f64>>,
{
let s = &self.settings;
let pos = pos.into();
let mut angle = angle.into().unwrap_or(0.0);
if s.angle_mode == AngleMode::Degrees {
angle = angle.to_radians();
};
let scale = scale.into().unwrap_or(1.0);
let (sin, cos) = angle.sin_cos();
let (px, py) = (f64::from(pos.x()), f64::from(pos.y()));
let vs = vertexes.into_iter().map(|v| {
let v = v.into();
let x = (v.x() * cos - v.y() * sin).mul_add(scale, px).round() as i32;
let y = (v.x().mul_add(sin, v.y() * cos)).mul_add(scale, py).round() as i32;
point![x, y]
});
self.polygon(vs)
}
#[doc(alias = "ellipse")]
pub fn circle<C>(&mut self, circle: C) -> PixResult<()>
where
C: Into<Ellipse<i32>>,
{
self.ellipse(circle)
}
pub fn ellipse<E>(&mut self, ellipse: E) -> PixResult<()>
where
E: Into<Ellipse<i32>>,
{
let s = &self.settings;
let ellipse = self.get_ellipse(ellipse);
self.renderer.ellipse(ellipse, s.smooth, s.fill, s.stroke)
}
pub fn arc<P>(&mut self, p: P, radius: i32, start: i32, end: i32) -> PixResult<()>
where
P: Into<Point<i32>>,
{
let s = &self.settings;
let p = p.into();
self.renderer
.arc(p, radius, start, end, s.arc_mode, s.fill, s.stroke)
}
}