Grow Scenario frames with preserved descendant padding

This commit is contained in:
2026-09-12 22:07:06 -07:00
parent 68a81c3f50
commit 37be41092b
2 changed files with 38 additions and 6 deletions
@@ -348,12 +348,14 @@ impl Plan {
if covered.y < rect.y { if covered.y < rect.y {
return Err(GeometryIssue::FixedFrameHeaderWouldMove { frame: id }); return Err(GeometryIssue::FixedFrameHeaderWouldMove { frame: id });
} }
if covered.y + covered.height > rect.y + rect.height { let old_covered = old_coverage[&id];
let old_covered = old_coverage[&id]; let padding =
let padding = (original.y + original.height - old_covered.y - old_covered.height).max(0.);
(original.y + original.height - old_covered.y - old_covered.height).max(0.); // Preserve padding before the footprint itself reaches the old
rect.height = covered.y + covered.height + padding - rect.y; // frame edge: operand scopes already retain their own padding.
} rect.height = rect
.height
.max(covered.y + covered.height + padding - rect.y);
} }
frames.insert(id, rect); frames.insert(id, rect);
drawn.insert(id, rect); drawn.insert(id, rect);
@@ -1050,6 +1050,19 @@ fn post_fragment_death_cannot_disappear_and_feasible_operand_spacing_retains_its
let (document, owner, _, second, delete, right) = alternatives_with_death(); let (document, owner, _, second, delete, right) = alternatives_with_death();
let mut p = document.project().clone(); let mut p = document.project().clone();
let baseline = Scene::sequence(&p, owner, owner); let baseline = Scene::sequence(&p, owner, owner);
let operand = p.elements[&second].parent.unwrap();
let fragment = p.elements[&operand].parent.unwrap();
let baseline_frame = baseline
.boxes
.iter()
.find(|item| item.id == fragment)
.unwrap()
.rect;
assert_eq!(
(baseline_frame.y, baseline_frame.y + baseline_frame.height),
(148., 567.)
);
assert_eq!(baseline.sequence_bounds[&operand], (433., 525.));
let x = baseline.render_lanes[&right]; let x = baseline.render_lanes[&right];
assert_eq!(baseline.rows[&delete].1, 631.); assert_eq!(baseline.rows[&delete].1, 631.);
assert_eq!( assert_eq!(
@@ -1064,6 +1077,23 @@ fn post_fragment_death_cannot_disappear_and_feasible_operand_spacing_retains_its
); );
let view = saved(&mut p, owner, Some(positions(&[(second, 520.)], &[]))); let view = saved(&mut p, owner, Some(positions(&[(second, 520.)], &[])));
let resolved = result(&p, view); let resolved = result(&p, view);
// The message still lies above the old frame bottom, but its padded
// operand would end at 570. Retain the automatic 92px frame padding.
assert_eq!(resolved.scene.rows[&second].1, 520.);
assert_eq!(resolved.plan.scopes[&operand], (433., 570.));
let frame = resolved.plan.frames[&fragment];
assert_eq!((frame.y, frame.y + frame.height), (148., 612.));
assert_eq!(resolved.scene.sequence_bounds[&operand], (433., 570.));
assert_eq!(
resolved
.scene
.boxes
.iter()
.find(|item| item.id == fragment)
.unwrap()
.rect,
frame
);
assert!(resolved.scene.lifecycle.missing_geometry().is_empty()); assert!(resolved.scene.lifecycle.missing_geometry().is_empty());
assert_eq!( assert_eq!(
resolved.scene.lifecycle.marker_at(Point::new(x, 631.)), resolved.scene.lifecycle.marker_at(Point::new(x, 631.)),