use crate::layout_algorithm::axis_utils::Axis;
use crate::layout_struct::layout_states::ChildWrapping;
use crate::layout_struct::layout_tree::{LayoutTreeCursor, LayoutTreeNodeLocal};
pub fn recursive_wrap_left_to_right(local: &mut LayoutTreeCursor) -> bool {
let mut subtree_dirty = false;
for child in local.get_all_child_ids() {
subtree_dirty |= recursive_wrap_left_to_right(&mut local.get_child_cursor(child).unwrap());
}
let mut node = local.get_local();
let is_text_wrap = node.self_element.config.layout.wrapping == ChildWrapping::Text;
if is_text_wrap {
wrap_elements_left_to_right(&mut node);
subtree_dirty = true;
} else if subtree_dirty {
node.recalculate_min_height_from_children();
}
subtree_dirty
}
pub fn wrap_elements_left_to_right(local_node: &mut LayoutTreeNodeLocal) {
let padding = &local_node.self_element.config.layout.padding;
let total_width = local_node
.self_element
.info
.get_final_width()
.expect("Element must have final width at this point")
- padding.left
- padding.right;
let gap = local_node.self_element.config.layout.child_gap;
let mut finished_line_heights: Vec<f32> = Vec::new();
let mut row_width = 0.0f32;
let mut row_max_height = 0.0f32;
let mut has_in_flow_child = false;
let mut started = false;
for child in &local_node.children_elements {
if child.config.floating.config.is_some() {
continue;
}
has_in_flow_child = true;
let width = child
.info
.get_final_axis(Axis::Width)
.expect("Element must have final width at this point");
let height = child
.info
.min_axis(Axis::Height)
.expect("Element must have a minimum height at this point");
if !started {
row_width = width;
row_max_height = height;
started = true;
} else if row_width + gap + width > total_width {
finished_line_heights.push(row_max_height);
row_width = width;
row_max_height = height;
} else {
row_width += gap + width;
row_max_height = row_max_height.max(height);
}
}
let lines_inner_height = if has_in_flow_child {
let between_lines = gap * finished_line_heights.len() as f32;
finished_line_heights.iter().sum::<f32>() + row_max_height + between_lines
} else {
0.0
};
let total_height = lines_inner_height + padding.top + padding.bottom;
local_node.self_element.info.set_min_height(total_height);
local_node.self_element.info.set_tmp_height(total_height);
}