use crate::core::{
AlignItems, AlignSelf, BorderStyle, Color, Dimension, Display, Edges, Element, ElementType,
FlexDirection, JustifyContent, Overflow, Position, Style,
};
#[derive(Debug, Clone, Default)]
pub struct Box {
style: Style,
children: Vec<Element>,
key: Option<String>,
scroll_offset_x: Option<u16>,
scroll_offset_y: Option<u16>,
}
impl Box {
pub fn new() -> Self {
Self {
style: Style::new(),
children: Vec::new(),
key: None,
scroll_offset_x: None,
scroll_offset_y: None,
}
}
pub fn key(mut self, key: impl Into<String>) -> Self {
self.key = Some(key.into());
self
}
pub fn display(mut self, display: Display) -> Self {
self.style.display = display;
self
}
pub fn hidden(mut self) -> Self {
self.style.display = Display::None;
self
}
pub fn visible(mut self) -> Self {
self.style.display = Display::Flex;
self
}
pub fn flex_direction(mut self, direction: FlexDirection) -> Self {
self.style.flex_direction = direction;
self
}
pub fn flex_wrap(mut self, wrap: bool) -> Self {
self.style.flex_wrap = wrap;
self
}
pub fn flex_grow(mut self, grow: f32) -> Self {
self.style.flex_grow = grow;
self
}
pub fn flex_shrink(mut self, shrink: f32) -> Self {
self.style.flex_shrink = shrink;
self
}
pub fn flex(mut self, value: f32) -> Self {
self.style.flex_grow = value;
self.style.flex_shrink = 1.0;
self
}
pub fn flex_basis(mut self, basis: impl Into<Dimension>) -> Self {
self.style.flex_basis = basis.into();
self
}
pub fn align_items(mut self, align: AlignItems) -> Self {
self.style.align_items = align;
self
}
pub fn align_self(mut self, align: AlignSelf) -> Self {
self.style.align_self = align;
self
}
pub fn justify_content(mut self, justify: JustifyContent) -> Self {
self.style.justify_content = justify;
self
}
pub fn padding(mut self, value: impl Into<Edges>) -> Self {
self.style.padding = value.into();
self
}
pub fn padding_top(mut self, value: f32) -> Self {
self.style.padding.top = value;
self
}
pub fn padding_right(mut self, value: f32) -> Self {
self.style.padding.right = value;
self
}
pub fn padding_bottom(mut self, value: f32) -> Self {
self.style.padding.bottom = value;
self
}
pub fn padding_left(mut self, value: f32) -> Self {
self.style.padding.left = value;
self
}
pub fn padding_x(mut self, value: f32) -> Self {
self.style.padding.left = value;
self.style.padding.right = value;
self
}
pub fn padding_y(mut self, value: f32) -> Self {
self.style.padding.top = value;
self.style.padding.bottom = value;
self
}
pub fn margin(mut self, value: impl Into<Edges>) -> Self {
self.style.margin = value.into();
self
}
pub fn margin_top(mut self, value: f32) -> Self {
self.style.margin.top = value;
self
}
pub fn margin_right(mut self, value: f32) -> Self {
self.style.margin.right = value;
self
}
pub fn margin_bottom(mut self, value: f32) -> Self {
self.style.margin.bottom = value;
self
}
pub fn margin_left(mut self, value: f32) -> Self {
self.style.margin.left = value;
self
}
pub fn margin_x(mut self, value: f32) -> Self {
self.style.margin.left = value;
self.style.margin.right = value;
self
}
pub fn margin_y(mut self, value: f32) -> Self {
self.style.margin.top = value;
self.style.margin.bottom = value;
self
}
pub fn gap(mut self, value: f32) -> Self {
self.style.gap = value;
self
}
pub fn column_gap(mut self, value: f32) -> Self {
self.style.column_gap = Some(value);
self
}
pub fn row_gap(mut self, value: f32) -> Self {
self.style.row_gap = Some(value);
self
}
pub fn width(mut self, value: impl Into<Dimension>) -> Self {
self.style.width = value.into();
self
}
pub fn height(mut self, value: impl Into<Dimension>) -> Self {
self.style.height = value.into();
self
}
pub fn min_width(mut self, value: impl Into<Dimension>) -> Self {
self.style.min_width = value.into();
self
}
pub fn min_height(mut self, value: impl Into<Dimension>) -> Self {
self.style.min_height = value.into();
self
}
pub fn max_width(mut self, value: impl Into<Dimension>) -> Self {
self.style.max_width = value.into();
self
}
pub fn max_height(mut self, value: impl Into<Dimension>) -> Self {
self.style.max_height = value.into();
self
}
pub fn border_style(mut self, style: BorderStyle) -> Self {
self.style.border_style = style;
self
}
pub fn border_color(mut self, color: Color) -> Self {
self.style.border_color = Some(color);
self
}
pub fn border_top_color(mut self, color: Color) -> Self {
self.style.border_top_color = Some(color);
self
}
pub fn border_right_color(mut self, color: Color) -> Self {
self.style.border_right_color = Some(color);
self
}
pub fn border_bottom_color(mut self, color: Color) -> Self {
self.style.border_bottom_color = Some(color);
self
}
pub fn border_left_color(mut self, color: Color) -> Self {
self.style.border_left_color = Some(color);
self
}
pub fn border_dim(mut self, dim: bool) -> Self {
self.style.border_dim = dim;
self
}
pub fn border(mut self, top: bool, right: bool, bottom: bool, left: bool) -> Self {
self.style.border_top = top;
self.style.border_right = right;
self.style.border_bottom = bottom;
self.style.border_left = left;
self
}
pub fn background(mut self, color: Color) -> Self {
self.style.background_color = Some(color);
self
}
pub fn bg(self, color: Color) -> Self {
self.background(color)
}
pub fn overflow(mut self, overflow: Overflow) -> Self {
self.style.overflow_x = overflow;
self.style.overflow_y = overflow;
self
}
pub fn overflow_x(mut self, overflow: Overflow) -> Self {
self.style.overflow_x = overflow;
self
}
pub fn overflow_y(mut self, overflow: Overflow) -> Self {
self.style.overflow_y = overflow;
self
}
pub fn scroll_offset_x(mut self, offset: u16) -> Self {
self.scroll_offset_x = Some(offset);
self
}
pub fn scroll_offset_y(mut self, offset: u16) -> Self {
self.scroll_offset_y = Some(offset);
self
}
pub fn scroll_offset(mut self, x: u16, y: u16) -> Self {
self.scroll_offset_x = Some(x);
self.scroll_offset_y = Some(y);
self
}
pub fn position(mut self, position: Position) -> Self {
self.style.position = position;
self
}
pub fn position_absolute(mut self) -> Self {
self.style.position = Position::Absolute;
self
}
pub fn top(mut self, value: f32) -> Self {
self.style.top = Some(value);
self
}
pub fn right(mut self, value: f32) -> Self {
self.style.right = Some(value);
self
}
pub fn bottom(mut self, value: f32) -> Self {
self.style.bottom = Some(value);
self
}
pub fn left(mut self, value: f32) -> Self {
self.style.left = Some(value);
self
}
pub fn child(mut self, element: Element) -> Self {
self.children.push(element);
self
}
pub fn children(mut self, elements: impl IntoIterator<Item = Element>) -> Self {
self.children.extend(elements);
self
}
pub fn into_element(self) -> Element {
let mut element = Element::new(ElementType::Box);
element.style = self.style;
element.key = self.key;
element.scroll_offset_x = self.scroll_offset_x;
element.scroll_offset_y = self.scroll_offset_y;
for child in self.children {
element.add_child(child);
}
element
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_box_builder() {
let element = Box::new()
.padding(1)
.flex_direction(FlexDirection::Column)
.into_element();
assert_eq!(element.style.padding.top, 1.0);
assert_eq!(element.style.flex_direction, FlexDirection::Column);
}
#[test]
fn test_box_with_children() {
let element = Box::new()
.child(Element::text("Hello"))
.child(Element::text("World"))
.into_element();
assert_eq!(element.children.len(), 2);
}
#[test]
fn test_box_border() {
let element = Box::new()
.border_style(BorderStyle::Round)
.border_color(Color::Cyan)
.into_element();
assert_eq!(element.style.border_style, BorderStyle::Round);
assert_eq!(element.style.border_color, Some(Color::Cyan));
}
}