~tm85/lintuini

3873712ae1cc616bff72c3dae4513bc21bf5f67f — TerraMaster85 27 days ago a247719
feat: element.rs: wow it compiles again. api general idea now stable ish?
M examples/empty_container.rs => examples/empty_container.rs +1 -5
@@ 11,11 11,7 @@ fn main() -> std::io::Result<()> {
    let fill = Style::default().bg(Color::Blue);
    let bord_style = Style::default().bg(Color::Green).fg(Color::Black);
    let bord_type = BorderType::Double;
    let cont = lintuini::elements::ContainerBuilder::new()
        .fill(fill)
        .border_style(bord_style)
        .border_type(bord_type)
        .build();
    let cont = lintuini::elements::Container::new();

    ratatui::run(|mut terminal| {
        loop {

A src/elements/.container.rs.swp => src/elements/.container.rs.swp +0 -0
A src/elements/.element.rs.swp => src/elements/.element.rs.swp +0 -0
M src/elements/container.rs => src/elements/container.rs +33 -74
@@ 1,5 1,5 @@
use ratatui_core::layout;
use ratatui_core::style;
use ratatui_core::style::Style;
use ratatui_core::terminal::Frame;

use ratatui_widgets::block;


@@ 8,19 8,20 @@ use ratatui_widgets::borders;
use super::element::{Element, ElementWithChildren};
use crate::error;

pub struct Container {
    border: Option<ContainerBorder>,
#[derive(Default)]
pub struct Container<'a> {
    children: Vec<Box<dyn Element>>,
    constraint: layout::Constraint,
    direction: layout::Direction,
    fill: style::Style,
    layout: Option<layout::Layout>,
    layout: layout::Layout,
    widgets: ContainerWidgets<'a>,
}

impl ElementWithChildren for Container {
impl ElementWithChildren for Container<'_> {
    #[inline(always)]
    fn add_child(&mut self, child: Box<dyn Element>) -> Result<(), error::LintuiniError>{
        self.children.push(child);
    fn add_child(&mut self, child: impl Into<Box<dyn Element>>) -> Result<(), error::LintuiniError>{
        self.children.push(child.into());
        

        Ok(())
    }
    #[inline(always)]


@@ 33,94 34,52 @@ impl ElementWithChildren for Container {
    }
}

impl Element for Container {
impl Element for Container<'_> {
    #[inline(always)]
    fn constraint(&self) -> &layout::Constraint {
        &self.constraint
    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(&self.widgets.block0, rect);

        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(());
        for (el, r) in self.children.iter().zip(&*self.layout.split(rect)) {
            el.render(frm, *r);
        }


        // TODO: children

        Ok(())
    }
}

#[derive(Default)]
pub struct ContainerBuilder {
    border: Option<ContainerBorder>,
    constraint: layout::Constraint,
    direction: layout::Direction,
    fill: style::Style,
}

impl ContainerBuilder {
impl Container<'_> {
    #[inline(always)]
    pub fn new() -> Self {
        ContainerBuilder::default()
    }
    #[inline(always)]
    pub fn fill(mut self, style: style::Style) -> Self {
        self.fill = style;
        self
        Container::default()
    }

    #[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
        self.layout = self.layout.direction(direction);
        self.regenerate_layout()
    }

    #[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,
        }
    fn regenerate_layout(mut self) -> Self {
        if self.children.len() == 0 { return self; }
        self.layout = self.layout.constraints(
            self.children
                .iter()
                .map(|el| el.constraint())
        );
        self
    }
}
#[derive(Clone, Copy, Default)]
pub struct ContainerBorder {
    style: style::Style,
    kind: borders::BorderType,
#[derive(Clone, Default)]
struct ContainerWidgets<'a> {
    block0: block::Block<'a>,
}

M src/elements/element.rs => src/elements/element.rs +2 -2
@@ 4,12 4,12 @@ use ratatui_core::terminal::Frame;
use crate::error;

pub trait Element {
    fn constraint(&self) -> &layout::Constraint;
    fn constraint(&self) -> layout::Constraint;
    fn render(&self, frm: &mut Frame, rect: layout::Rect) -> Result<(), error::LintuiniError>;
}

pub trait ElementWithChildren: Element {
    fn add_child(&mut self, child: Box<dyn Element>) -> Result<(), error::LintuiniError>;
    fn add_child(&mut self, child: impl Into<Box<dyn Element>>) -> Result<(), error::LintuiniError>;
    fn children(&self) -> &[Box<dyn Element>];
    fn children_mut(&mut self) -> &mut [Box<dyn Element>];
}