From 7e748d4af8540be268aa905926db0d55056ab075 Mon Sep 17 00:00:00 2001 From: Trevor Brown Date: Wed, 11 Nov 2026 22:47:01 -0500 Subject: [PATCH] Rotation field: a relative edit turns a selected parent before its child (#2200 review) Co-Authored-By: Claude Sonnet 5.5 Model-Effort: Opus 5.5 drove; Opus 5.5 briefed; Sonnet 5.5 wrote at medium --- crates/ui-egui/src/field_tests.rs | 18 ++++++++++++++++++ crates/ui-egui/src/panels/right.rs | 7 ++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/crates/ui-egui/src/field_tests.rs b/crates/ui-egui/src/field_tests.rs index 2f8182b03..ebadce835 100644 --- a/crates/ui-egui/src/field_tests.rs +++ b/crates/ui-egui/src/field_tests.rs @@ -485,6 +485,24 @@ fn the_rotation_field_shows_and_sets_the_rotation_on_the_page() { assert_eq!(undo_steps(&u), steps + 1); } +#[test] +fn a_relative_rotation_edit_turns_a_selected_parent_before_its_child_whatever_the_selection_order() { + let mut s = Session::new(); + let f = id(s.execute("frame.create", &json!({"x": 0, "y": 0, "width": 400, "height": 400})).unwrap()); + let c = id(s.execute("shape.rectangle", &json!({"x": 100, "y": 100, "width": 120, "height": 80, "parent": f})).unwrap()); + s.execute("node.set", &json!({"ids": [f], "props": {"rotation": 10}})).unwrap(); + s.execute("node.set", &json!({"ids": [c], "props": {"absoluteRotation": 30}})).unwrap(); + // The child first, then its parent. + s.execute("select.set", &json!({"ids": [c, f]})).unwrap(); + let mut u = Ui::new(s); + u.ctx.enable_accesskit(); + u.frame(vec![]); + let page = |u: &Ui, n: NodeId| figcraft_geom::rotation_degrees(u.app.session.doc().unwrap().world_transform(n)); + assert_eq!(field(&mut u, "Rotation").1, "Mixed"); + type_into(&mut u, "Rotation", "+10", Key::Enter); + assert!((page(&u, f) - 20.0).abs() < 1e-6 && (page(&u, c) - 40.0).abs() < 1e-6, "{} {}", page(&u, f), page(&u, c)); +} + #[test] fn arithmetic_commits_tab_moves_on_and_escape_restores() { let (mut u, a, _) = setup(); diff --git a/crates/ui-egui/src/panels/right.rs b/crates/ui-egui/src/panels/right.rs index ff3c11000..a059dbccd 100644 --- a/crates/ui-egui/src/panels/right.rs +++ b/crates/ui-egui/src/panels/right.rs @@ -75,7 +75,12 @@ impl FigApp { None => return, }; let Ok(doc) = self.session.doc() else { return }; - let values: Vec<(NodeId, f64)> = ids.iter().filter_map(|i| Some((*i, rel.apply(shown(doc.node(*i)?))?))).collect(); + let mut values: Vec<(NodeId, f64)> = ids.iter().filter_map(|i| Some((*i, rel.apply(shown(doc.node(*i)?))?))).collect(); + if key == "absoluteRotation" { + // A page angle depends on the parents': turn a selected parent before the layers in it + // (as `node.set` orders a multi-id call), whatever order the selection is in. + values.sort_by_key(|(i, _)| doc.ancestors(*i).len()); + } if values.is_empty() || self.session.begin_interaction("Edit").is_err() { return; }