use crate::view::style::{Align, Direction, Justify, Length, Overflow, Style};
use crate::core::Pixels;
use crate::view::layout_extra;
use taffy::prelude::*;
fn dimension(length: Option<Length>) -> Dimension {
match length {
Some(Length::Px(value)) => Dimension::length(value.0),
Some(Length::Percent(fraction)) => Dimension::percent(fraction),
Some(Length::Auto) | None => Dimension::auto(),
}
}
fn limit(length: Option<Length>) -> LengthPercentageAuto {
match length {
Some(Length::Px(value)) => LengthPercentageAuto::length(value.0),
Some(Length::Percent(fraction)) => LengthPercentageAuto::percent(fraction),
Some(Length::Auto) | None => LengthPercentageAuto::auto(),
}
}
fn padding(value: Option<Pixels>) -> LengthPercentage {
LengthPercentage::length(value.unwrap_or_default().0)
}
fn margin(value: Option<Pixels>) -> LengthPercentageAuto {
LengthPercentageAuto::length(value.unwrap_or_default().0)
}
fn inset(value: Option<Pixels>) -> LengthPercentageAuto {
match value {
Some(pixels) => LengthPercentageAuto::length(pixels.0),
None => LengthPercentageAuto::auto(),
}
}
fn align(value: Align) -> AlignItems {
match value {
Align::Baseline => AlignItems::BASELINE,
Align::Start => AlignItems::FLEX_START,
Align::Center => AlignItems::CENTER,
Align::End => AlignItems::FLEX_END,
Align::Stretch => AlignItems::STRETCH,
}
}
pub(crate) fn justify(value: Justify) -> JustifyContent {
match value {
Justify::Start => JustifyContent::FLEX_START,
Justify::Center => JustifyContent::CENTER,
Justify::End => JustifyContent::FLEX_END,
Justify::SpaceBetween => JustifyContent::SPACE_BETWEEN,
Justify::SpaceAround => JustifyContent::SPACE_AROUND,
Justify::SpaceEvenly => JustifyContent::SPACE_EVENLY,
}
}
fn overflow(value: Option<Overflow>) -> taffy::Overflow {
match value {
Some(Overflow::Hidden) => taffy::Overflow::Hidden,
Some(Overflow::Scroll) => taffy::Overflow::Scroll,
Some(Overflow::Visible) | None => taffy::Overflow::Visible,
}
}
pub fn to_taffy(style: &Style) -> taffy::Style {
let mut out = base(style);
layout_extra::apply(style, &mut out);
out
}
fn base(style: &Style) -> taffy::Style {
taffy::Style {
display: if style.hidden == Some(true) { Display::None } else { Display::Flex },
position: if style.absolute == Some(true) { Position::Absolute } else { Position::Relative },
flex_direction: match style.direction {
Some(Direction::Column) => FlexDirection::Column,
_ => FlexDirection::Row,
},
flex_wrap: if style.wrap == Some(true) { FlexWrap::Wrap } else { FlexWrap::NoWrap },
align_items: style.align_items.map(align).unwrap_or_default(),
align_self: style.align_self.map(align),
justify_content: style.justify_content.map(justify).unwrap_or_default(),
flex_grow: style.flex_grow.unwrap_or(0.0),
flex_shrink: style.flex_shrink.unwrap_or(1.0),
flex_basis: dimension(style.flex_basis),
size: taffy::Size { width: dimension(style.width), height: dimension(style.height) },
min_size: taffy::Size { width: limit(style.min_width), height: limit(style.min_height) },
max_size: taffy::Size { width: limit(style.max_width), height: limit(style.max_height) },
aspect_ratio: style.aspect_ratio,
padding: taffy::Rect {
left: padding(style.padding.left),
right: padding(style.padding.right),
top: padding(style.padding.top),
bottom: padding(style.padding.bottom),
},
margin: taffy::Rect {
left: margin(style.margin.left),
right: margin(style.margin.right),
top: margin(style.margin.top),
bottom: margin(style.margin.bottom),
},
inset: taffy::Rect {
left: inset(style.inset.left),
right: inset(style.inset.right),
top: inset(style.inset.top),
bottom: inset(style.inset.bottom),
},
gap: taffy::Size { width: padding(style.gap_x), height: padding(style.gap_y) },
overflow: taffy::Point { x: overflow(style.overflow_x), y: overflow(style.overflow_y) },
scrollbar_width: 0.0,
..Default::default()
}
}