mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-30 04:57:54 -06:00
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -3591,7 +3591,15 @@ fn group_row_click(app: &mut EffectcraftApp, ui: &mut egui::Ui, g: &mut Rw, rc:
|
||||
}
|
||||
app.auto.add(&format!("timeline.group.{uid}.name"), gr_rect, name);
|
||||
if gr.clicked() && uid & (WAVE_BIT | GEOM_BIT) == 0 {
|
||||
actions.push(("prop.select".into(), json!({"layer": layer.id.0, "prop": uid, "selectKeys": false})));
|
||||
// Shift or Cmd/Ctrl adds the group to the selection, or takes a selected one out, as
|
||||
// property rows and Effect Controls headers do (#2552: several effects and styles for
|
||||
// one animation preset).
|
||||
let add = ui.input(|i| i.modifiers.shift || i.modifiers.command);
|
||||
if add && app.session.state.selected_props.contains(&(layer.id, *uid)) {
|
||||
actions.push(("prop.deselect".into(), json!({"layer": layer.id.0, "prop": uid})));
|
||||
} else {
|
||||
actions.push(("prop.select".into(), json!({"layer": layer.id.0, "prop": uid, "selectKeys": false, "add": add})));
|
||||
}
|
||||
}
|
||||
if gr.double_clicked() {
|
||||
if fx.is_some() {
|
||||
|
||||
@@ -448,3 +448,42 @@ fn effects_drag_to_a_new_place_in_the_timeline() {
|
||||
h.state_mut().session.execute("edit.undo", json!({})).unwrap();
|
||||
assert_eq!(names(&h), ["Tint", "Gaussian Blur", "Invert"], "one undo step per drop");
|
||||
}
|
||||
|
||||
/// #2552: Shift-clicking effect rows in the Timeline adds them to the selection (and a second
|
||||
/// Shift-click takes one out), so one animation preset can hold several effects.
|
||||
#[test]
|
||||
fn shift_click_selects_several_effects_for_a_preset() {
|
||||
let mut s = session();
|
||||
let l = s.execute("layer.newSolid", json!({"name": "Plate", "color": "#406080"})).unwrap()["layer"].as_u64().unwrap();
|
||||
for fx in ["Gaussian Blur", "Invert"] {
|
||||
s.execute("effect.apply", json!({"layers": [l], "effect": fx})).unwrap();
|
||||
}
|
||||
let effects = s.active_comp().unwrap().layer(LayerId(l)).unwrap().props.sub("effects").unwrap().clone();
|
||||
let uids: Vec<u64> = effects.groups().map(|g| g.uid).collect();
|
||||
let mut h = harness(s);
|
||||
h.state_mut().ui.timeline.open_groups.insert(effects.uid);
|
||||
open_layer(&mut h, l);
|
||||
let shift_click = |h: &mut Harness<'_, EffectcraftApp>, uid: u64| {
|
||||
let p = center(h, &format!("timeline.group.{uid}.name"));
|
||||
h.input_mut().events.push(Event::ModifiersChanged(Modifiers::SHIFT));
|
||||
h.input_mut().events.push(Event::PointerMoved(p));
|
||||
h.step();
|
||||
for pressed in [true, false] {
|
||||
h.input_mut().events.push(Event::PointerButton { pos: p, button: PointerButton::Primary, pressed, modifiers: Modifiers::SHIFT });
|
||||
h.step();
|
||||
}
|
||||
h.input_mut().events.push(Event::ModifiersChanged(Modifiers::NONE));
|
||||
h.run_steps(2);
|
||||
};
|
||||
let selected = |h: &Harness<'_, EffectcraftApp>| h.state().session.state.selected_props.iter().map(|(_, u)| *u).collect::<Vec<_>>();
|
||||
click(&mut h, &format!("timeline.group.{}.name", uids[0]));
|
||||
assert_eq!(selected(&h), [uids[0]]);
|
||||
shift_click(&mut h, uids[1]);
|
||||
assert_eq!(selected(&h), [uids[0], uids[1]], "Shift adds the second effect");
|
||||
let path = std::env::temp_dir().join(format!("ec-2552-{}.ffx", std::process::id()));
|
||||
let r = h.state_mut().session.execute("anim.savePreset", json!({"path": path.to_string_lossy()})).unwrap();
|
||||
assert_eq!(r["effects"], 2, "{r}");
|
||||
let _ = std::fs::remove_file(&path);
|
||||
shift_click(&mut h, uids[1]);
|
||||
assert_eq!(selected(&h), [uids[0]], "a second Shift-click takes it out");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user