use ratatui_core::layout; use ratatui_core::style; use ratatui_core::terminal::Frame; use ratatui_widgets::block; use ratatui_widgets::borders; use super::element::{Element, ElementWithChildren}; use crate::error; pub struct Container { border: Option, children: Vec>, constraint: layout::Constraint, direction: layout::Direction, fill: style::Style, layout: Option, } impl ElementWithChildren for Container { #[inline(always)] fn add_child(&mut self, child: Box) -> Result<(), error::LintuiniError>{ self.children.push(child); Ok(()) } #[inline(always)] fn children(&self) -> &[Box] { self.children.as_slice() } #[inline(always)] fn children_mut(&mut self) -> &mut [Box] { self.children.as_mut_slice() } } impl Element for Container { #[inline(always)] fn constraint(&self) -> &layout::Constraint { &self.constraint } fn render(&self, frm: &mut Frame, rect: layout::Rect) -> Result<(), error::LintuiniError> { let blk = match &self.border { Some(bs) => block::Block::bordered().style(self.fill).border_type(bs.kind).border_style(bs.style), None => block::Block::new().style(self.fill), }; frm.render_widget(blk, rect); if self.layout.is_none() { debug_assert!( self.children.len() == 0, "child count did not match number of layout fields" ); return Ok(()); } // TODO: children Ok(()) } } #[derive(Default)] pub struct ContainerBuilder { border: Option, constraint: layout::Constraint, direction: layout::Direction, fill: style::Style, } impl ContainerBuilder { #[inline(always)] pub fn new() -> Self { ContainerBuilder::default() } #[inline(always)] pub fn fill(mut self, style: style::Style) -> Self { self.fill = style; self } #[inline(always)] pub fn constraint(mut self, constraint: layout::Constraint) -> Self { self.constraint = constraint; self } #[inline(always)] pub fn direction(mut self, direction: layout::Direction) -> Self { self.direction = direction; self } #[inline(always)] pub fn border_style(mut self, style: style::Style) -> Self { match self.border { Some(mut bs) => { bs.style = style; }, None => { self.border = Some(ContainerBorder { style: style, ..Default::default() }) }, } self } #[inline(always)] pub fn border_type(mut self, kind: borders::BorderType) -> Self { match self.border { Some(mut bs) => { bs.kind = kind; }, None => { self.border = Some(ContainerBorder { kind: kind, ..Default::default() }) }, } self } #[inline(always)] pub fn build(self) -> Container { Container { border: self.border, constraint: self.constraint, children: Vec::new(), direction: self.direction, fill: self.fill, layout: None, } } } #[derive(Clone, Copy, Default)] pub struct ContainerBorder { style: style::Style, kind: borders::BorderType, }