use rdom_core::{Dom, NodeId};
use crate::ext::TuiExt;
use crate::layout::Direction;
use crate::node::TuiNodeExt;
use crate::style::ComputedStyle;
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
pub(super) enum CollapseEdge {
Top,
Bottom,
Left,
Right,
}
pub(super) fn has_effective_border_on_edge(
dom: &Dom<TuiExt>,
id: NodeId,
edge: CollapseEdge,
) -> bool {
let Some(computed) = dom.node(id).computed() else {
return false; };
match edge {
CollapseEdge::Top => !computed.border.top.is_none(),
CollapseEdge::Bottom => !computed.border.bottom.is_none(),
CollapseEdge::Left => !computed.border.left.is_none(),
CollapseEdge::Right => !computed.border.right.is_none(),
}
}
pub(super) fn collapse_parent_edge_insets(
dom: &Dom<TuiExt>,
children: &[NodeId],
parent: &ComputedStyle,
) -> (u16, u16, u16, u16) {
use crate::layout::BorderCollapse;
if parent.border_collapse != BorderCollapse::Collapse {
return (0, 0, 0, 0);
}
let parent_has_top = !parent.border.top.is_none();
let parent_has_bottom = !parent.border.bottom.is_none();
let parent_has_left = !parent.border.left.is_none();
let parent_has_right = !parent.border.right.is_none();
if !(parent_has_top || parent_has_bottom || parent_has_left || parent_has_right) {
return (0, 0, 0, 0);
}
let first = *children.first().unwrap();
let last = *children.last().unwrap();
let needs_inset =
|id: NodeId, edge: CollapseEdge| -> bool { !has_effective_border_on_edge(dom, id, edge) };
let (top, bottom, left, right) = match parent.direction {
Direction::Column => {
let top = if parent_has_top && needs_inset(first, CollapseEdge::Top) {
1
} else {
0
};
let bottom = if parent_has_bottom && needs_inset(last, CollapseEdge::Bottom) {
1
} else {
0
};
let left = if parent_has_left && needs_inset(first, CollapseEdge::Left) {
1
} else {
0
};
let right = if parent_has_right && needs_inset(first, CollapseEdge::Right) {
1
} else {
0
};
(top, bottom, left, right)
}
Direction::Row => {
let left = if parent_has_left && needs_inset(first, CollapseEdge::Left) {
1
} else {
0
};
let right = if parent_has_right && needs_inset(last, CollapseEdge::Right) {
1
} else {
0
};
let top = if parent_has_top && needs_inset(first, CollapseEdge::Top) {
1
} else {
0
};
let bottom = if parent_has_bottom && needs_inset(first, CollapseEdge::Bottom) {
1
} else {
0
};
(top, bottom, left, right)
}
};
(top, bottom, left, right)
}