use crate::{color::Color, unit::*, Style, StyleUpdater};
use derive_rich::Rich;
#[derive(Rich, Clone, Debug, PartialEq, Default)]
pub struct Background {
#[rich(write)]
pub color: Option<Color>,
#[rich(write, value_fns = { empty = Image::None })]
pub image: Option<Image>,
#[rich(value_fns = {
repeat_x = Repeat::RepeatX,
repeat_y = Repeat::RepeatY,
repeat = Repeat::Repeat,
repeat_with_space = Repeat::Space,
repeat_round = Repeat::Round,
no_repeat = Repeat::NoRepeat,
initial_repeat = Repeat::Initial,
inherit_repeat = Repeat::Inherit,
})]
pub repeat: Option<Repeat>,
#[rich(write(rename = attachment), value_fns = {
scroll = Attachment::Scroll,
fixed = Attachment::Fixed,
local = Attachment::Local,
initial_attachment = Attachment::Initial,
inherit_attachment = Attachment::Inherit,
})]
pub attachment: Option<Attachment>,
#[rich(write(rename = position), value_fns = {
center_top = (Horizontal::Center, Vertical::Top(None)),
center = (Horizontal::Center, Vertical::Center),
center_bottom = (Horizontal::Center, Vertical::Bottom(None)),
left_top = (Horizontal::Left(None), Vertical::Top(None)),
left_center = (Horizontal::Left(None), Vertical::Center),
left_bottom = (Horizontal::Left(None), Vertical::Bottom(None)),
right_top = (Horizontal::Right(None), Vertical::Top(None)),
right_center = (Horizontal::Right(None), Vertical::Center),
right_bottom = (Horizontal::Right(None), Vertical::Bottom(None)),
})]
pub position: Option<Position>,
#[rich(write(rename = clip), value_fns = {
fill_under_border = Clip::BorderBox,
fill_inside_border = Clip::PaddingBox,
fill_under_content = Clip::ContentBox,
})]
pub clip: Option<Clip>,
#[rich(write(rename = origin), value_fns = {
image_fill_under_border = Origin::BorderBox,
image_inside_border = Origin::PaddingBox,
image_under_content = Origin::ContentBox,
})]
pub origin: Option<Origin>,
#[rich(write(rename = size), value_fns = {
full = (1.0, 1.0),
half = (0.5, 0.5),
quarter = (0.25, 0.25),
auto_size = Size::Auto,
cover = Size::Cover,
contain = Size::Contain,
})]
pub size: Option<Size>,
}
impl<T: Into<Color>> From<T> for Background {
fn from(source: T) -> Self {
Background::default().color(source.into())
}
}
impl StyleUpdater for Background {
fn update_style(self, style: Style) -> Style {
style
.try_insert("background-color", self.color)
.try_insert("background-image", self.image.as_ref())
.try_insert("background-repeat", self.repeat)
.try_insert("background-attachment", self.attachment)
.try_insert("background-position", self.position)
}
}
#[derive(Clone, Debug, PartialEq, Display, From)]
pub enum Image {
#[display(fmt = "none")]
None,
#[display(fmt = "url({})", _0)]
#[from(forward)]
Url(String),
}
#[derive(Clone, Copy, Debug, PartialEq, Display, From)]
pub enum Repeat {
#[display(fmt = "repeat-x")]
RepeatX,
#[display(fmt = "repeat-y")]
RepeatY,
#[display(fmt = "repeat")]
Repeat,
#[display(fmt = "space")]
Space,
#[display(fmt = "round")]
Round,
#[display(fmt = "no-repeat")]
NoRepeat,
#[display(fmt = "initial")]
Initial,
#[display(fmt = "inherit")]
Inherit,
}
#[derive(Clone, Copy, Debug, PartialEq, Display, From)]
pub enum Attachment {
#[display(fmt = "scroll")]
Scroll,
#[display(fmt = "fixed")]
Fixed,
#[display(fmt = "local")]
Local,
#[display(fmt = "initial")]
Initial,
#[display(fmt = "inherit")]
Inherit,
}
fn display_helper(v: &Option<impl ToString>) -> String {
v.as_ref()
.map_or("".into(), |s| format!(" {}", s.to_string()))
}
#[derive(Clone, Debug, PartialEq, Display)]
pub enum Horizontal {
#[display(fmt = "center")]
Center,
#[display(fmt = "left{}", "display_helper(_0)")]
Left(Option<Length>),
#[display(fmt = "right{}", "display_helper(_0)")]
Right(Option<Length>),
}
#[derive(Clone, Debug, PartialEq, Display)]
pub enum Vertical {
#[display(fmt = "center")]
Center,
#[display(fmt = "top{}", "display_helper(_0)")]
Top(Option<Length>),
#[display(fmt = "bottom{}", "display_helper(_0)")]
Bottom(Option<Length>),
}
#[derive(Clone, Debug, PartialEq, Display, From)]
pub enum Position {
#[display(fmt = "{} {}", _0, _1)]
#[from]
Percent(Percent, Percent),
#[display(fmt = "{} {}", _0, _1)]
#[from]
Placement(Horizontal, Vertical),
}
impl From<(f32, f32)> for Position {
fn from((hor, ver): (f32, f32)) -> Self {
Position::Percent(hor.into(), ver.into())
}
}
#[derive(Clone, Copy, Debug, PartialEq, Display, From)]
pub enum Box {
#[display(fmt = "border-box")]
BorderBox,
#[display(fmt = "padding-box")]
PaddingBox,
#[display(fmt = "content-box")]
ContentBox,
#[display(fmt = "initial")]
Initial,
#[display(fmt = "inherit")]
Inherit,
}
pub type Clip = Box;
pub type Origin = Box;
#[derive(Clone, Debug, PartialEq, Display, From)]
pub enum Size {
#[display(fmt = "{} {}", _0, _1)]
WidthHeight(LengthPercent, LengthPercent),
#[display(fmt = "auto")]
Auto,
#[display(fmt = "cover")]
Cover,
#[display(fmt = "contain")]
Contain,
#[display(fmt = "initial")]
Initial,
}
impl From<(f32, f32)> for Size {
fn from((width, height): (f32, f32)) -> Self {
Self::WidthHeight(width.into(), height.into())
}
}