mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-24 10:09:32 -06:00
#979: test that layer context menus offer Create Shapes from Vector Layer
Right-clicking vector footage in the Timeline or the Composition viewer offered no vector conversion. The test imports an SVG and checks the item is absent for a solid, present on the SVG layer in both menus, and converts it. Without the fix the menu item is missing.
This commit is contained in:
@@ -637,3 +637,66 @@ fn timeline_context_menu_creates_shapes_and_masks_from_text() {
|
||||
assert!(h.query_by_label("Create Shapes from Text").is_none(), "no text conversion for a solid");
|
||||
assert!(h.query_by_label("Create Masks from Text").is_none(), "no text conversion for a solid");
|
||||
}
|
||||
|
||||
// Regression test for #979 (#958): right-clicking a vector footage layer (SVG) in the Timeline
|
||||
// or the Composition viewer offered no Create Shapes from Vector Layer; raster layers must not.
|
||||
#[test]
|
||||
fn layer_context_menus_offer_create_shapes_from_vector_layer_for_vector_footage() {
|
||||
use effectcraft_engine::project::LayerSource;
|
||||
let dir = std::env::temp_dir().join(format!("ec-ui-vector-menu-{}", std::process::id()));
|
||||
std::fs::create_dir_all(&dir).unwrap();
|
||||
let svg = dir.join("logo.svg");
|
||||
std::fs::write(
|
||||
&svg,
|
||||
r##"<svg xmlns="http://www.w3.org/2000/svg" width="40" height="20" viewBox="0 0 40 20"><rect width="40" height="20" fill="#ff0000"/></svg>"##,
|
||||
)
|
||||
.unwrap();
|
||||
let mut s = effectcraft_host::session();
|
||||
let item = s.execute("file.import", json!({"paths": [svg.to_string_lossy()]})).unwrap()["items"][0].as_u64().unwrap();
|
||||
s.execute("comp.new", json!({"name":"Vec","width":320,"height":180,"duration":4})).unwrap();
|
||||
let logo = s.execute("layer.addItem", json!({"item": item})).unwrap()["layer"].as_u64().unwrap();
|
||||
let plate = s.execute("layer.newSolid", json!({"name":"Plate","width":40,"height":40,"color":"#406080"})).unwrap()["layer"].as_u64().unwrap();
|
||||
s.execute("edit.deselectAll", json!({})).unwrap();
|
||||
let mut h = Harness::builder().with_size(vec2(1600.0, 1000.0)).build_eframe(|_| EffectcraftApp::new(s));
|
||||
h.run_steps(3);
|
||||
let right_click = |h: &mut Harness<'_, EffectcraftApp>, p: Pos2| {
|
||||
for pressed in [true, false] {
|
||||
h.input_mut().events.push(Event::PointerMoved(p));
|
||||
h.input_mut().events.push(Event::PointerButton { pos: p, button: PointerButton::Secondary, pressed, modifiers: Modifiers::NONE });
|
||||
h.step();
|
||||
}
|
||||
h.run_steps(3);
|
||||
};
|
||||
let row = |h: &Harness<'_, EffectcraftApp>, id: u64| {
|
||||
let r = rect(h, &format!("timeline.layer.{id}.row"));
|
||||
pos2(r.min.x + 210.0, r.center().y)
|
||||
};
|
||||
let label = "Create Shapes from Vector Layer";
|
||||
let shapes =
|
||||
|h: &Harness<'_, EffectcraftApp>| h.state().session.active_comp().unwrap().layers.iter().filter(|l| matches!(l.source, LayerSource::Shape)).count();
|
||||
// A raster-less solid does not offer the conversion.
|
||||
h.state_mut().session.execute("layer.select", json!({"layers": [plate]})).unwrap();
|
||||
h.run_steps(3);
|
||||
let at = row(&h, plate);
|
||||
right_click(&mut h, at);
|
||||
assert!(h.query_by_label(label).is_none(), "no vector conversion for a solid");
|
||||
h.key_press(egui::Key::Escape);
|
||||
h.run_steps(3);
|
||||
// The Timeline row of the SVG layer offers it, and it converts the layer.
|
||||
h.state_mut().session.execute("layer.select", json!({"layers": [logo]})).unwrap();
|
||||
h.run_steps(3);
|
||||
let at = row(&h, logo);
|
||||
right_click(&mut h, at);
|
||||
h.get_by_label(label).click();
|
||||
h.run_steps(3);
|
||||
assert_eq!(shapes(&h), 1, "a shape layer was created from the SVG layer");
|
||||
// The Composition viewer's menu offers it for the SVG layer under the pointer too.
|
||||
h.state_mut().session.execute("edit.undo", json!({})).unwrap();
|
||||
h.state_mut().session.execute("prop.set", json!({"layer": plate, "path": "transform/position", "value": [40.0, 40.0]})).unwrap();
|
||||
h.state_mut().session.execute("layer.select", json!({"layers": [logo]})).unwrap();
|
||||
h.run_steps(3);
|
||||
let comp = rect(&h, "viewer.comp");
|
||||
right_click(&mut h, comp.center());
|
||||
assert!(h.query_by_label(label).is_some(), "the viewer's context menu offers the vector conversion");
|
||||
let _ = std::fs::remove_dir_all(&dir);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user