use { types, triangulation, DrawState, Graphics };
use types::{ Color, Radius };
use math::{ Matrix2d, Scalar };
#[derive(Copy, Clone)]
pub enum Shape {
Square,
Round,
Bevel,
}
#[derive(Copy, Clone)]
pub struct Line {
pub color: Color,
pub radius: Radius,
pub shape: Shape,
}
impl Line {
pub fn new(color: Color, radius: Radius) -> Line {
Line {
color: color,
radius: radius,
shape: Shape::Square,
}
}
pub fn new_round(color: Color, radius: Radius) -> Line {
Line {
color: color,
radius: radius,
shape: Shape::Round,
}
}
pub fn color(mut self, value: Color) -> Self {
self.color = value;
self
}
pub fn radius(mut self, value: Radius) -> Self {
self.radius = value;
self
}
pub fn width(mut self, value: types::Width) -> Self {
self.radius = 0.5 * value;
self
}
pub fn shape(mut self, value: Shape) -> Self {
self.shape = value;
self
}
#[inline(always)]
pub fn draw<L: Into<types::Line>, G>(
&self,
line: L,
draw_state: &DrawState,
transform: Matrix2d,
g: &mut G
)
where G: Graphics
{
g.line(self, line, draw_state, transform);
}
pub fn draw_tri<L: Into<types::Line>, G>(
&self,
line: L,
draw_state: &DrawState,
transform: Matrix2d,
g: &mut G
)
where G: Graphics
{
let line = line.into();
match self.shape {
Shape::Square => {
g.tri_list(
draw_state,
&self.color,
|f|
triangulation::with_round_border_line_tri_list(
2,
transform,
line,
self.radius,
|vertices| f(vertices)
));
}
Shape::Round => {
g.tri_list(
draw_state,
&self.color,
|f|
triangulation::with_round_border_line_tri_list(
64,
transform,
line,
self.radius,
|vertices| f(vertices)
));
}
Shape::Bevel => {
g.tri_list(
draw_state,
&self.color,
|f|
triangulation::with_round_border_line_tri_list(
3,
transform,
line,
self.radius,
|vertices| f(vertices)
));
}
}
}
pub fn draw_arrow<L: Into<types::Line>, G>(
&self,
line: L,
head_size: Scalar,
draw_state: &DrawState,
transform: Matrix2d,
g: &mut G
)
where G: Graphics
{
use Transformed;
let line = line.into();
self.draw(line, draw_state, transform, g);
let diff = [line[2] - line[0], line[3] - line[1]];
let arrow_head = transform
.trans(line[2], line[3])
.orient(diff[0], diff[1]);
self.draw([-head_size, head_size, 0.0, 0.0], draw_state, arrow_head, g);
self.draw([-head_size, -head_size, 0.0, 0.0], draw_state, arrow_head, g);
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_line() {
use Colored;
let _line = Line::new([0.0; 4], 3.0)
.color([1.0; 4])
.radius(3.0)
.shape(Shape::Round)
.hue_deg(1.0);
}
}