feat: implement nested border-box layout and alignment

This commit is contained in:
2026-11-10 22:17:19 +08:00
parent 525097a0b2
commit 32d7ada3ab
21 changed files with 1368 additions and 74 deletions
+23 -13
View File
@@ -76,11 +76,8 @@ pub fn project(vm: &mut Vm, table: &MountTable, root: &UiNode, frame: &mut Frame
.mounts
.iter()
.map(|m| {
let padding = match nodes[m.block_id.as_str()].kind {
UiKind::Scroll { padding, .. } => padding,
_ => 0.0,
};
(m.x + m.width - padding, m.y + m.height - padding)
let inset = layout::insets(nodes[m.block_id.as_str()]);
(m.x + m.width - inset.right, m.y + m.height - inset.bottom)
})
.collect();
for i in (0..frame.mounts.len()).rev() {
@@ -104,22 +101,20 @@ pub fn project(vm: &mut Vm, table: &MountTable, root: &UiNode, frame: &mut Frame
.parent
.and_then(|id| contexts.get(&id).copied())
.unwrap_or_default();
let padding = match nodes[m.block_id.as_str()].kind {
UiKind::Scroll { padding, .. } => padding,
_ => 0.0,
};
let node = nodes[m.block_id.as_str()];
let padding = layout::insets(node);
let axis = match nodes[m.block_id.as_str()].kind {
UiKind::Scroll { axis, .. } => axis,
_ => Axis::Both,
};
let limits = [
if axis.horizontal() {
(extent[i].0 + padding - m.x - m.width).max(0.0)
(extent[i].0 + padding.right - m.x - m.width).max(0.0)
} else {
0.0
},
if axis.vertical() {
(extent[i].1 + padding - m.y - m.height).max(0.0)
(extent[i].1 + padding.bottom - m.y - m.height).max(0.0)
} else {
0.0
},
@@ -128,6 +123,19 @@ pub fn project(vm: &mut Vm, table: &MountTable, root: &UiNode, frame: &mut Frame
m.y -= dy;
m.clip = clip;
let mut child = (dx, dy, clip);
if node.clip_children {
let border = node.border;
let viewport = [
m.x + border.left.min(m.width),
m.y + border.top.min(m.height),
(m.width - border.horizontal()).max(0.0),
(m.height - border.vertical()).max(0.0),
];
child.2 = Some(
clip.map(|clip| intersection(clip, viewport))
.unwrap_or(viewport),
);
}
if scrolling[i] {
let weak = table
.active
@@ -149,13 +157,15 @@ pub fn project(vm: &mut Vm, table: &MountTable, root: &UiNode, frame: &mut Frame
dx + x,
dy + y,
Some(
clip.map(|clip| intersection(clip, viewport))
child
.2
.map(|clip| intersection(clip, viewport))
.unwrap_or(viewport),
),
);
}
contexts.insert(m.id, child);
if let Some(command) = layout::paint_native(
for command in layout::paint_commands(
nodes[m.block_id.as_str()],
m.x,
m.y,