use oino_ui::layout::{Constraint, Direction, Flex, Margin};
use ratatui::layout::{
Constraint as RConstraint, Direction as RDirection, Flex as RFlex, Layout, Margin as RMargin,
Rect,
};
#[must_use]
pub(crate) fn direction(direction: Option<Direction>) -> RDirection {
match direction.unwrap_or_default() {
Direction::Vertical => RDirection::Vertical,
Direction::Horizontal => RDirection::Horizontal,
}
}
#[must_use]
pub(crate) fn constraint(constraint: Constraint) -> RConstraint {
match constraint {
Constraint::Length(n) => RConstraint::Length(n),
Constraint::Percentage(p) => RConstraint::Percentage(p),
Constraint::Ratio(a, b) => RConstraint::Ratio(a, b),
Constraint::Min(n) => RConstraint::Min(n),
Constraint::Max(n) => RConstraint::Max(n),
Constraint::Fill(w) => RConstraint::Fill(w),
}
}
#[must_use]
pub(crate) fn flex(flex: Option<Flex>) -> RFlex {
match flex.unwrap_or_default() {
Flex::Legacy => RFlex::Legacy,
Flex::Start => RFlex::Start,
Flex::End => RFlex::End,
Flex::Center => RFlex::Center,
Flex::SpaceBetween => RFlex::SpaceBetween,
Flex::SpaceAround => RFlex::SpaceAround,
}
}
#[must_use]
pub(crate) fn margin(margin: Margin) -> RMargin {
match margin {
Margin::Uniform(n) => RMargin {
horizontal: n,
vertical: n,
},
Margin::Axes {
horizontal,
vertical,
} => RMargin {
horizontal,
vertical,
},
}
}
#[must_use]
pub(crate) fn constraints(layout: &oino_ui::layout::Layout) -> Vec<RConstraint> {
(0..layout.children.len())
.map(|i| {
layout
.constraints
.get(i)
.copied()
.map_or(RConstraint::Fill(1), constraint)
})
.collect()
}
#[must_use]
pub(crate) fn split(layout: &oino_ui::layout::Layout, area: Rect) -> Vec<Rect> {
let mut builder = Layout::default()
.direction(direction(layout.direction))
.constraints(constraints(layout))
.flex(flex(layout.flex));
if let Some(spacing) = layout.spacing {
builder = builder.spacing(spacing);
}
if let Some(m) = layout.margin {
let margin = margin(m);
builder = builder
.horizontal_margin(margin.horizontal)
.vertical_margin(margin.vertical);
}
builder.split(area).to_vec()
}
#[must_use]
pub(crate) fn split_vertical_auto(heights: &[u16], spacing: u16, area: Rect) -> Vec<Rect> {
let mut y = area.y;
let mut out = Vec::with_capacity(heights.len());
for (index, height) in heights.iter().enumerate() {
if index > 0 {
y = y.saturating_add(spacing);
}
let remaining = area.bottom().saturating_sub(y);
let h = (*height).min(remaining);
out.push(Rect {
x: area.x,
y,
width: area.width,
height: h,
});
y = y.saturating_add(h);
}
out
}
#[must_use]
pub(crate) fn collapses(layout: &oino_ui::layout::Layout, width: u16) -> bool {
let collapse = layout.collapse.unwrap_or(60);
collapse > 0 && matches!(layout.direction, Some(Direction::Horizontal)) && width < collapse
}