use crate::{calc::Calc, unit::*, Style, StyleUpdater};
use derive_rich::Rich;
#[derive(Rich, Clone, Debug, PartialEq, Default)]
pub struct Position {
#[rich(write(rename = position), write(option, rename = try_position), value_fns = {
static_ = PositionType::Static,
absolute = PositionType::Absolute,
fixed = PositionType::Fixed,
relative = PositionType::Relative,
sticky = PositionType::Sticky,
initial = PositionType::Initial,
inherit = PositionType::Inherit,
})]
pub position: Option<PositionType>,
#[rich(write, write(option))]
pub left: Option<PostionLength>,
#[rich(write, write(option))]
pub top: Option<PostionLength>,
#[rich(write, write(option))]
pub right: Option<PostionLength>,
#[rich(write, write(option))]
pub bottom: Option<PostionLength>,
#[rich(write, write(option))]
pub z_index: Option<i32>,
#[rich(write, write(option))]
pub clip: Option<Clip>,
}
impl Position {
pub fn move_top(self) -> Self {
self.top(px(0))
}
pub fn move_right(self) -> Self {
self.right(px(0))
}
pub fn move_bottom(self) -> Self {
self.bottom(px(0))
}
pub fn move_left(self) -> Self {
self.left(px(0))
}
pub fn move_top_stretch(self) -> Self {
self.move_top().move_left().move_right()
}
pub fn move_right_stretch(self) -> Self {
self.move_right().move_top().move_bottom()
}
pub fn move_bottom_stretch(self) -> Self {
self.move_bottom().move_left().move_right()
}
pub fn move_left_stretch(self) -> Self {
self.move_left().move_top().move_bottom()
}
pub fn move_top_right(self) -> Self {
self.move_top().move_right()
}
pub fn move_top_left(self) -> Self {
self.move_top().move_left()
}
pub fn move_bottom_right(self) -> Self {
self.move_bottom().move_right()
}
pub fn move_bottom_left(self) -> Self {
self.move_bottom().move_left()
}
pub fn cover(self) -> Self {
self.move_top_right().move_bottom_left()
}
}
impl StyleUpdater for Position {
fn update_style(self, style: Style) -> Style {
style
.try_insert("position", self.position.as_ref())
.try_insert("left", self.left.as_ref())
.try_insert("top", self.top.as_ref())
.try_insert("right", self.right.as_ref())
.try_insert("bottom", self.bottom.as_ref())
.try_insert("z-index", self.z_index.as_ref())
.try_insert("clip", self.clip.as_ref())
}
}
impl<T> From<T> for Position
where
T: Into<PositionType>,
{
fn from(source: T) -> Self {
Self {
position: Some(source.into()),
..Position::default()
}
}
}
#[derive(Clone, Debug, PartialEq, Display, From)]
pub enum PostionLength {
#[display(fmt = "initial")]
Initial,
#[display(fmt = "inherit")]
Inherit,
#[display(fmt = "auto")]
Auto,
#[from]
Length(Length),
#[from(forward)]
Percent(Percent),
}
impl From<Calc> for PostionLength {
fn from(source: Calc) -> Self {
PostionLength::Length(source.into())
}
}
#[derive(Clone, Debug, PartialEq, Display, From)]
pub enum Clip {
#[display(fmt = "auto")]
Auto,
#[display(fmt = "rect({}, {}, {}, {})", top, right, bottom, left)]
ShapeRect {
top: ClipRectLength,
right: ClipRectLength,
bottom: ClipRectLength,
left: ClipRectLength,
},
#[display(fmt = "initial")]
Initial,
#[display(fmt = "inherit")]
Inherit,
}
impl Clip {
pub fn rect(
top: impl Into<ClipRectLength>,
right: impl Into<ClipRectLength>,
bottom: impl Into<ClipRectLength>,
left: impl Into<ClipRectLength>,
) -> Self {
Self::ShapeRect {
top: top.into(),
right: right.into(),
bottom: bottom.into(),
left: left.into(),
}
}
}
#[derive(Clone, Debug, PartialEq, Display, From)]
pub enum ClipRectLength {
#[display(fmt = "initial")]
Initial,
#[display(fmt = "inherit")]
Inherit,
#[display(fmt = "auto")]
Auto,
#[from]
Length(Length),
#[from(forward)]
Percent(Percent),
}
impl From<Calc> for ClipRectLength {
fn from(source: Calc) -> Self {
ClipRectLength::Length(source.into())
}
}
#[derive(Clone, Copy, Debug, PartialEq, Display, From)]
pub enum PositionType {
#[display(fmt = "static")]
Static,
#[display(fmt = "absolute")]
Absolute,
#[display(fmt = "fixed")]
Fixed,
#[display(fmt = "relative")]
Relative,
#[display(fmt = "sticky")]
Sticky,
#[display(fmt = "initial")]
Initial,
#[display(fmt = "inherit")]
Inherit,
}