Skip to main content

ling_ui/
layout.rs

1//! Flex layout engine (wraps Taffy when the `layout` feature is enabled).
2
3#[derive(Debug, Clone, Copy, PartialEq)]
4pub enum FlexDirection { Row, Column, RowReverse, ColumnReverse }
5
6#[derive(Debug, Clone, Copy)]
7pub struct LayoutNode {
8    pub x: f32, pub y: f32,
9    pub width: f32, pub height: f32,
10}
11
12#[derive(Debug, Clone)]
13pub struct Style {
14    pub direction: FlexDirection,
15    pub gap:       f32,
16    pub padding:   f32,
17}
18
19impl Default for Style {
20    fn default() -> Self {
21        Self { direction: FlexDirection::Column, gap: 4.0, padding: 8.0 }
22    }
23}
24
25/// Lay out `count` children of equal size inside `parent`.
26pub fn simple_layout(parent: LayoutNode, count: usize, style: &Style) -> Vec<LayoutNode> {
27    if count == 0 { return vec![]; }
28    let available = match style.direction {
29        FlexDirection::Row | FlexDirection::RowReverse =>
30            parent.width  - style.padding * 2.0 - style.gap * (count - 1) as f32,
31        _ =>
32            parent.height - style.padding * 2.0 - style.gap * (count - 1) as f32,
33    };
34    let child_size = (available / count as f32).max(0.0);
35    (0..count).map(|i| {
36        let offset = style.padding + i as f32 * (child_size + style.gap);
37        match style.direction {
38            FlexDirection::Row => LayoutNode {
39                x: parent.x + offset, y: parent.y + style.padding,
40                width: child_size, height: parent.height - style.padding * 2.0,
41            },
42            _ => LayoutNode {
43                x: parent.x + style.padding, y: parent.y + offset,
44                width: parent.width - style.padding * 2.0, height: child_size,
45            },
46        }
47    }).collect()
48}