use bounding_box::{BoundingBox, ToBoundingBox};
use super::Style;
use crate::{Transformation, geometry::*};
pub struct Drawable {
pub geometry: Geometry,
pub style: Style,
}
impl Drawable {
pub fn new<G: Into<Geometry>>(geo: G, style: Style) -> Self {
Drawable {
geometry: geo.into(),
style,
}
}
pub fn draw(&self, context: &cairo::Context) -> Result<(), cairo::Error> {
DrawableRef::from(self).draw(context)
}
}
impl Transformation for Drawable {
fn translate(&mut self, shift: [f64; 2]) {
self.geometry.translate(shift);
}
fn rotate(&mut self, center: [f64; 2], angle: f64) {
self.geometry.rotate(center, angle);
}
fn scale(&mut self, factor: f64) {
self.geometry.scale(factor);
}
fn line_reflection(&mut self, start: [f64; 2], stop: [f64; 2]) -> () {
self.geometry.line_reflection(start, stop);
}
}
impl ToBoundingBox for Drawable {
fn bounding_box(&self) -> BoundingBox {
(&self.geometry).bounding_box()
}
}
impl<I> From<(I, Style)> for Drawable
where
I: Into<Geometry>,
{
fn from(value: (I, Style)) -> Self {
return Drawable {
geometry: value.0.into(),
style: value.1,
};
}
}
pub struct DrawableRef<'a> {
pub geometry: GeometryRef<'a>,
pub style: Style,
}
impl<'a> DrawableRef<'a> {
pub fn new<G: Into<GeometryRef<'a>>>(geo: G, style: Style) -> Self {
DrawableRef {
geometry: geo.into(),
style,
}
}
pub fn draw(&self, context: &cairo::Context) -> Result<(), cairo::Error> {
match self.geometry {
GeometryRef::Point(_) => Ok(()), GeometryRef::BoundingBox(elem) => {
crate::contour::Contour::from(elem).draw(&self.style, context)
}
GeometryRef::ArcSegment(elem) => elem.draw(&self.style, context),
GeometryRef::LineSegment(elem) => elem.draw(&self.style, context),
GeometryRef::Line(_) => Ok(()), GeometryRef::Segment(elem) => elem.draw(&self.style, context),
GeometryRef::Polysegment(elem) => elem.draw(&self.style, context),
GeometryRef::Contour(elem) => elem.draw(&self.style, context),
GeometryRef::Shape(elem) => elem.draw(&self.style, context),
}
}
}
impl<'a> ToBoundingBox for DrawableRef<'a> {
fn bounding_box(&self) -> BoundingBox {
return self.geometry.bounding_box();
}
}
impl<'a> From<DrawableRef<'a>> for Drawable {
fn from(value: DrawableRef<'a>) -> Self {
return Drawable {
geometry: value.geometry.into(),
style: value.style,
};
}
}
impl<'a> From<&'a Drawable> for DrawableRef<'a> {
fn from(value: &'a Drawable) -> Self {
return DrawableRef {
geometry: (&value.geometry).into(),
style: value.style.clone(),
};
}
}
impl<'a, I> From<(I, Style)> for DrawableRef<'a>
where
I: Into<GeometryRef<'a>>,
{
fn from(value: (I, Style)) -> Self {
return DrawableRef {
geometry: value.0.into(),
style: value.1,
};
}
}
pub struct DrawableCow<'a> {
pub geometry: GeometryCow<'a>,
pub style: Style,
}
impl<'a> DrawableCow<'a> {
pub fn new<G: Into<GeometryCow<'a>>>(geo: G, style: Style) -> Self {
DrawableCow {
geometry: geo.into(),
style,
}
}
pub fn draw(&self, context: &cairo::Context) -> Result<(), cairo::Error> {
DrawableRef::from(self).draw(context)
}
}
impl<'a> ToBoundingBox for DrawableCow<'a> {
fn bounding_box(&self) -> BoundingBox {
return self.geometry.bounding_box();
}
}
impl<'a> From<&'a Drawable> for DrawableCow<'a> {
fn from(value: &'a Drawable) -> Self {
return DrawableCow {
geometry: (&value.geometry).into(),
style: value.style.clone(),
};
}
}
impl<'a> From<&'a DrawableCow<'a>> for DrawableRef<'a> {
fn from(value: &'a DrawableCow<'a>) -> Self {
return DrawableRef {
geometry: (&value.geometry).into(),
style: value.style.clone(),
};
}
}
impl<'a> From<DrawableCow<'a>> for Drawable {
fn from(value: DrawableCow<'a>) -> Self {
return Drawable {
geometry: value.geometry.into(),
style: value.style,
};
}
}
impl<'a, I> From<(I, Style)> for DrawableCow<'a>
where
I: Into<GeometryCow<'a>>,
{
fn from(value: (I, Style)) -> Self {
return DrawableCow {
geometry: value.0.into(),
style: value.1,
};
}
}