Effect reset: restore parameters inside twirl-down groups

effect.reset looked parameters up by their full spec id among the effect's direct
children, so every 'group/param' id (most of Fractal, Scribble, and other grouped
effects) was skipped and Reset did nothing for them. Fixes #526

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Fabio Lussi
2026-10-10 13:57:45 +02:00
co-authored by Claude Opus 5.5
parent 813c7c4650
commit 00156ce22e
2 changed files with 25 additions and 1 deletions
+2 -1
View File
@@ -387,7 +387,8 @@ fn reset(s: &mut Session, p: &Value) -> Result<Value> {
s.edit(&format!("Reset {name}"), None, |proj, _| {
let g = layer_mut(proj, cid, lid)?.props.find_group_mut(uid).ok_or_else(|| bad("effect.reset", "gone"))?;
for ps in &spec.params {
if let Some(pr) = g.get_mut(ps.id) {
// (`group/param` ids live in twirl-down groups.)
if let Some(pr) = g.prop_mut(ps.id) {
pr.set_value_at(lt, effectcraft_effects::default_value(ps, size));
}
}
+23
View File
@@ -110,6 +110,29 @@ fn reset_effect_restores_defaults_in_one_undo_step() {
assert_eq!(g.get("start").unwrap().value, KV::Vec2([10.0, 20.0]));
}
#[test]
fn reset_restores_parameters_inside_twirl_down_groups() {
let (mut s, a, _) = comp_with_two_solids();
// Fractal and Scribble keep most parameters in groups (`mandelbrot/…`, `edgeOptions/…`).
for (effect, changes) in [
("Fractal", [("setChoice", json!(1)), ("mandelbrot/mandelbrotX", json!(1.25)), ("fractalColor/hue", json!(90.0))]),
("Scribble", [("scribble", json!(2)), ("edgeOptions/edgeWidth", json!(33.0)), ("strokeOptions/spacing", json!(9.0))]),
] {
let fx = apply(&mut s, a, effect);
let group = |s: &Session| layer(s, a).effects().unwrap().groups().find(|g| g.uid == fx).unwrap().clone();
let defaults: Vec<_> = changes.iter().map(|(id, _)| group(&s).prop(id).unwrap().value.clone()).collect();
for (id, v) in &changes {
let uid = group(&s).prop(id).unwrap().uid;
s.execute("prop.set", json!({"layer": a, "prop": uid, "value": v})).unwrap();
assert_ne!(group(&s).prop(id).unwrap().value, defaults[changes.iter().position(|(i, _)| i == id).unwrap()], "{effect} {id} changed");
}
s.execute("effect.reset", json!({"layer": a, "effect": fx})).unwrap();
for ((id, _), d) in changes.iter().zip(&defaults) {
assert_eq!(&group(&s).prop(id).unwrap().value, d, "{effect} {id} back to its default");
}
}
}
#[test]
fn reset_keys_animated_params_at_the_cti() {
let (mut s, a, _) = comp_with_two_solids();