use super::{Context, FromWithContext};
use crate::{Point2, Real, ToReal, Size2};
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub enum CornerRadius<Num> {
Uniform(Num),
PerCorner {
top_left: Num,
top_right: Num,
bottom_right: Num,
bottom_left: Num,
},
}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub struct Rectangle<Num, Color> {
pub center: Point2<Num>,
pub size: Size2<Num>,
pub corner_radius: Option<CornerRadius<Num>>,
pub fill: Color,
pub stroke: Color,
pub weight: Num,
pub rotation: Num,
}
impl<X, Y, Width, Height, Num, Color> FromWithContext<(X, Y, Width, Height), Num, Color>
for Rectangle<Num, Color>
where
X: ToReal<Num>,
Y: ToReal<Num>,
Width: ToReal<Num>,
Height: ToReal<Num>,
Num: Real,
Color: Clone,
{
fn from_with_context(data: (X, Y, Width, Height), context: &Context<Num, Color>) -> Self {
let (x, y, width, height) = data;
let (x, y, width, height) = (x.to_real(), y.to_real(), width.to_real(), height.to_real());
let (center, size) = context.rectangle_mode.interpret(x, y, width, height);
Rectangle {
center,
size,
corner_radius: None,
fill: context.fill.clone(),
stroke: context.stroke.clone(),
weight: context.weight,
rotation: context.rotation,
}
}
}
impl<X, Y, Width, Height, Radius, Num, Color>
FromWithContext<(X, Y, Width, Height, Radius), Num, Color> for Rectangle<Num, Color>
where
X: ToReal<Num>,
Y: ToReal<Num>,
Width: ToReal<Num>,
Height: ToReal<Num>,
Radius: ToReal<Num>,
Num: Real,
Color: Clone,
{
fn from_with_context(
data: (X, Y, Width, Height, Radius),
context: &Context<Num, Color>,
) -> Self {
let (x, y, width, height, radius) = data;
let (x, y, width, height, radius) = (
x.to_real(),
y.to_real(),
width.to_real(),
height.to_real(),
radius.to_real(),
);
let (center, size) = context.rectangle_mode.interpret(x, y, width, height);
Rectangle {
center,
size,
corner_radius: Some(CornerRadius::Uniform(radius)),
fill: context.fill.clone(),
stroke: context.stroke.clone(),
weight: context.weight,
rotation: context.rotation,
}
}
}
impl<X, Y, Width, Height, TL, TR, BR, BL, Num, Color>
FromWithContext<(X, Y, Width, Height, TL, TR, BR, BL), Num, Color> for Rectangle<Num, Color>
where
X: ToReal<Num>,
Y: ToReal<Num>,
Width: ToReal<Num>,
Height: ToReal<Num>,
TL: ToReal<Num>,
TR: ToReal<Num>,
BR: ToReal<Num>,
BL: ToReal<Num>,
Num: Real,
Color: Clone,
{
fn from_with_context(
data: (X, Y, Width, Height, TL, TR, BR, BL),
context: &Context<Num, Color>,
) -> Self {
let (x, y, width, height, top_left, top_right, bottom_right, bottom_left) = data;
let (x, y, width, height, top_left, top_right, bottom_right, bottom_left) = (
x.to_real(),
y.to_real(),
width.to_real(),
height.to_real(),
top_left.to_real(),
top_right.to_real(),
bottom_right.to_real(),
bottom_left.to_real(),
);
let (center, size) = context.rectangle_mode.interpret(x, y, width, height);
Rectangle {
center,
size,
corner_radius: Some(CornerRadius::PerCorner {
top_left,
top_right,
bottom_right,
bottom_left,
}),
fill: context.fill.clone(),
stroke: context.stroke.clone(),
weight: context.weight,
rotation: context.rotation,
}
}
}