From 88e40f444a9c6c1283083b27038201ce08071073 Mon Sep 17 00:00:00 2001 From: Elias Date: Sat, 10 Oct 2026 23:44:44 +0100 Subject: [PATCH] UI: reproduce overlapping duplicated text editing with pointer and Type tool (cherry picked from commit 0acb03da5f0d09d726047013e931e5eeff5504ce) (cherry picked from commit 66427c0149c5f2fd46931945a4f11a9530c12269) (cherry picked from commit d5fadffc1ac9f072a985a918cd6a62e9763bc2bf) --- crates/ui-egui/tests/ui_text_edit.rs | 65 ++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/crates/ui-egui/tests/ui_text_edit.rs b/crates/ui-egui/tests/ui_text_edit.rs index 1c2c7355..ec46975f 100644 --- a/crates/ui-egui/tests/ui_text_edit.rs +++ b/crates/ui-egui/tests/ui_text_edit.rs @@ -277,3 +277,68 @@ fn type_tool_drag_makes_paragraph_text_with_box_handles() { assert!(doc2.box_size.unwrap()[0] > bs[0] + 20.0, "{:?}", doc2.box_size); assert!(h.state().session.state.text_edit.is_some(), "still editing after resizing"); } + +#[test] +fn duplicated_text_boxes_both_remain_editable() { + let mut a = app(); + let original = a + .session + .execute("layer.newText", json!({"text": "alpha beta", "size": 40, "position": [40, 100], "justify": "left", "box": [40, 60, 250, 100]})) + .unwrap()["layer"] + .as_u64() + .unwrap(); + let mut h = Harness::builder().with_size(egui::vec2(1600.0, 1000.0)).with_step_dt(1.0 / 60.0).build_eframe(move |_| a); + h.run_steps(3); + h.state_mut().ui.focused = PanelKind::Composition; + key(&mut h, Key::D, Modifiers::COMMAND); + let duplicate = h.state().session.state.selected_layers[0].0; + assert_ne!(original, duplicate); + h.state_mut().session.execute("prop.set", json!({"layer": duplicate, "path": "transform/position", "value": [465, 110]})).unwrap(); + h.run_steps(3); + for (layer, x, text) in [(original, 80.0, "original edited"), (duplicate, 380.0, "duplicate edited")] { + h.run_steps(40); + let comp = rect(&h, "viewer.comp"); + let k = comp.width() / 640.0; + let p = comp.min + egui::vec2(x * k, 85.0 * k); + click(&mut h, p, Modifiers::NONE); + click(&mut h, p, Modifiers::NONE); + assert_eq!(edited(&h).0, layer); + type_text(&mut h, text); + key(&mut h, Key::Escape, Modifiers::NONE); + assert_eq!(layer_doc(&h.state().session, LayerId(layer)).unwrap().text, text); + } +} + +#[test] +fn overlapping_duplicate_text_remains_editable_by_double_click_and_selected_type_tool() { + let mut a = app(); + let original = a.session.execute("layer.newText", json!({"text": "alpha beta", "size": 40, "box": [40, 60, 250, 100]})).unwrap()["layer"].as_u64().unwrap(); + let mut h = Harness::builder().with_size(egui::vec2(1600.0, 1000.0)).with_step_dt(1.0 / 60.0).build_eframe(move |_| a); + h.run_steps(3); + h.state_mut().ui.focused = PanelKind::Composition; + key(&mut h, Key::D, Modifiers::COMMAND); + let duplicate = h.state().session.state.selected_layers[0].0; + assert_ne!(original, duplicate); + let comp = rect(&h, "viewer.comp"); + let p = comp.min + egui::vec2(80.0, 85.0) * (comp.width() / 640.0); + click(&mut h, p, Modifiers::NONE); + click(&mut h, p, Modifiers::NONE); + assert_eq!(edited(&h).0, duplicate, "double-click edits the topmost overlapping copy"); + type_text(&mut h, "copy edited"); + assert_eq!(edited(&h).1, "copy edited"); + key(&mut h, Key::Z, Modifiers::COMMAND); + assert_eq!(edited(&h).1, "alpha beta", "undo restores the duplicate's text"); + key(&mut h, Key::Escape, Modifiers::NONE); + h.state_mut().session.execute("layer.select", json!({"layers": [original]})).unwrap(); + h.state_mut().ui.focused = PanelKind::Composition; + key(&mut h, Key::T, Modifiers::COMMAND); + h.run_steps(40); + click(&mut h, p, Modifiers::NONE); + assert_eq!(edited(&h).0, original, "the Type tool must honor the explicitly selected overlapping text layer"); + key(&mut h, Key::A, Modifiers::COMMAND); + type_text(&mut h, "original edited"); + assert_eq!(edited(&h).1, "original edited"); + assert_eq!(layer_doc(&h.state().session, LayerId(duplicate)).unwrap().text, "alpha beta", "editing the original leaves the duplicate unchanged"); + key(&mut h, Key::Z, Modifiers::COMMAND); + assert_eq!(edited(&h).1, "alpha beta"); +}