Turtle Draw 布局系统

基本概念

turtle布局系统包含以下核心概念:

1pub struct Turtle {
2    // 当前海龟位置
3    walk: Walk,         // 布局行为
4    layout: Layout,     // 布局规则
5    wrap_spacing: f64,  // 换行间距
6    align_start: usize, // 对齐开始位置
7    defer_count: usize, // 延迟计数
8    shift: DVec2,      // 位移量
9    pos: DVec2,        // 当前位置
10    origin: DVec2,     // 起始位置
11    width: f64,        // 宽度
12    height: f64,       // 高度
13    width_used: f64,   // 已使用宽度
14    height_used: f64,  // 已使用高度
15}

基本绘制流程

1// 开始一个 turtle 布局
2cx.begin_turtle(walk, layout);
3
4// 绘制过程示例
5turtle.move_to(10.0, 10.0);  // 移动到指定位置
6turtle.line_to(100.0, 100.0); // 画线到指定位置
7turtle.rect(0.0, 0.0, 50.0, 30.0); // 绘制矩形
8
9// 结束布局
10cx.end_turtle();

位置计算实例

1impl Turtle {
2    // 计算下一个位置
3    pub fn next_pos(&mut self, size: DVec2) -> DVec2 {
4        match self.layout.flow {
5            Flow::Right => {
6                let pos = self.pos;
7                self.pos.x += size.x + self.layout.spacing;
8                self.width_used = self.width_used.max(self.pos.x);
9                pos
10            }
11            Flow::Down => {
12                let pos = self.pos;
13                self.pos.y += size.y + self.layout.spacing;
14                self.height_used = self.height_used.max(self.pos.y);
15                pos
16            }
17            // ... 其他流向的处理
18        }
19    }
20}

复杂布局示例

嵌套布局

1MyView = <View> {
2    // 外层 turtle
3    walk: {width: Fill, height: Fit},
4    layout: {flow: Down, spacing: 10},
5
6    // 内层 turtle
7    <View> {
8        walk: {width: Fill, height: Fit},
9        layout: {
10            flow: Right,
11            spacing: 5,
12            padding: {left: 10, right: 10}
13        },
14
15        // 内容组件
16        <Button> {}
17        <Button> {}
18    }
19}

延迟布局(Defer)机制

当布局需要等待某些条件满足时,可以使用延迟布局:

1impl Turtle {
2    pub fn defer_walk(&mut self, walk: Walk) -> Option<DeferWalk> {
3        if walk.abs_pos.is_some() {
4            return None;
5        }
6
7        // 处理延迟布局的逻辑
8        match self.layout.flow {
9            Flow::Right if walk.width.is_fill() => {
10                // 处理右向流式布局中的延迟
11                let spacing = self.child_spacing();
12                self.pos.x += spacing.x;
13                Some(DeferWalk::Unresolved{...})
14            }
15            // ... 其他情况处理
16        }
17    }
18}

Turtle 布局对齐系统

对齐方式

1pub struct AlignEntry {
2    align_range: TurtleAlignRange,
3    size: DVec2,
4    shift: f64,
5    index: usize
6}
7
8impl Cx2d {
9    pub fn align_items(&mut self) {
10        // 遍历所有需要对齐的项
11        for item in &self.draw_align_list {
12            // 计算对齐位置
13            let shift = match self.layout.align {
14                Align::Center => {
15                    (self.width - item.size.x) * 0.5
16                },
17                // ... 其他对齐方式
18            };
19
20            // 应用对齐
21            self.shift_align_range(&item.align_range, shift);
22        }
23    }
24}

实际对齐示例

1CenteredContent = <View> {
2    layout: {
3        flow: Down,
4        align: {x: 0.5, y: 0.0}  // 水平居中,顶部对齐
5    },
6
7    <Text> {
8        walk: {
9            width: Fit,
10            height: Fit
11        },
12        text: "Centered Text"
13    }
14}

Turtle 性能优化

缓存机制

1pub struct DrawStateWrap<T: Clone> {
2    state: Option<T>,
3    redraw_id: u64,
4}
5
6impl<T: Clone> DrawStateWrap<T> {
7    pub fn begin(&mut self, cx: &mut Cx2d, init: T) -> bool {
8        if self.redraw_id != cx.redraw_id() {
9            // 只在必要时更新状态
10            self.redraw_id = cx.redraw_id();
11            self.state = Some(init);
12            true
13        } else {
14            false
15        }
16    }
17}