mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-14 19:27:05 -04:00
#1063: find a Levels alpha control on the effect by its name
Pro Levels2 keeps its Alpha controls one group down, under Alpha, and a script's
effect.property("Alpha Input White") only searched the effect's direct children, so it returned null.
The lookup now searches the groups nested below the direct children, up to three levels, after the
direct match fails. Direct children keep their priority. A regression test checks the name on the
effect and the same control through the Alpha group.
Co-Authored-By: Claude Haiku 5.5 <[email protected]>
This commit is contained in:
1 parent
470ea7a3af
commit
5e97eaddba
2 files changed
+51
-16
No files matched your search
+33
-16
@@ -402,6 +402,38 @@ fn alias(k: &str) -> Option<&'static str> {
|
||||
})
|
||||
}
|
||||
|
||||
/// How many groups below a property group a string key may search (#1063: Pro Levels2's Alpha
|
||||
/// controls sit one group down, under Alpha).
|
||||
const NESTED_CHILD_DEPTH: u8 = 3;
|
||||
|
||||
/// The child of `g` that a string key names. The direct children are searched first, then the
|
||||
/// groups nested below them, up to `depth` levels.
|
||||
fn find_child<'a>(l: &'a Layer, g: &'a PropGroup, k: &str, depth: u8) -> Option<&'a Node> {
|
||||
let chain_of = |n: &Node| -> String {
|
||||
let mut ch = if g.uid == l.props.uid { vec![] } else { chain(l, g.uid).unwrap_or_default() };
|
||||
ch.push(n);
|
||||
matchnames::node(&ch)
|
||||
};
|
||||
let lk = loose(k);
|
||||
g.children
|
||||
.iter()
|
||||
.find(|n| chain_of(n) == k)
|
||||
.or_else(|| g.children.iter().find(|n| n.name() == k))
|
||||
.or_else(|| g.children.iter().find(|n| n.match_id() == k))
|
||||
.or_else(|| g.children.iter().find(|n| n.name().eq_ignore_ascii_case(k)))
|
||||
.or_else(|| g.children.iter().find(|n| loose(n.name()) == lk || loose(n.match_id()) == lk))
|
||||
.or_else(|| alias(&lk).and_then(|m| g.children.iter().find(|n| n.match_id() == m)))
|
||||
.or_else(|| {
|
||||
if depth == 0 {
|
||||
return None;
|
||||
}
|
||||
g.children.iter().find_map(|n| match n {
|
||||
Node::Group(sub) => find_child(l, sub, k, depth - 1),
|
||||
Node::Prop(_) => None,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
fn child(s: &Session, a: &J) -> R {
|
||||
let (_, c, l) = layer_of(s, a)?;
|
||||
let uid = u(a, "uid").unwrap_or(0);
|
||||
@@ -409,22 +441,7 @@ fn child(s: &Session, a: &J) -> R {
|
||||
let key = a.get("key").cloned().unwrap_or(J::Null);
|
||||
let found = match &key {
|
||||
J::Number(n) => n.as_u64().and_then(|i| g.children.get((i as usize).checked_sub(1)?)),
|
||||
J::String(k) => {
|
||||
let chain_of = |n: &Node| -> String {
|
||||
let mut ch = if uid == 0 || uid == l.props.uid { vec![] } else { chain(l, uid).unwrap_or_default() };
|
||||
ch.push(n);
|
||||
matchnames::node(&ch)
|
||||
};
|
||||
let lk = loose(k);
|
||||
g.children
|
||||
.iter()
|
||||
.find(|n| chain_of(n) == *k)
|
||||
.or_else(|| g.children.iter().find(|n| n.name() == k))
|
||||
.or_else(|| g.children.iter().find(|n| n.match_id() == k))
|
||||
.or_else(|| g.children.iter().find(|n| n.name().eq_ignore_ascii_case(k)))
|
||||
.or_else(|| g.children.iter().find(|n| loose(n.name()) == lk || loose(n.match_id()) == lk))
|
||||
.or_else(|| alias(&lk).and_then(|m| g.children.iter().find(|n| n.match_id() == m)))
|
||||
}
|
||||
J::String(k) => find_child(l, g, k, NESTED_CHILD_DEPTH),
|
||||
_ => None,
|
||||
};
|
||||
match found {
|
||||
|
||||
@@ -1010,3 +1010,21 @@ fn scripted_text_range_selector_resolves_and_is_the_only_selector() {
|
||||
);
|
||||
assert_eq!(o.result, json!([1, "ADBE Text Selector", 50, 100, "ADBE Text Percent Offset"]));
|
||||
}
|
||||
|
||||
/// Pro Levels2's Alpha controls sit one group down (under Alpha), so a script finds them by their
|
||||
/// name on the effect as well as through the group (#1063).
|
||||
#[test]
|
||||
fn scripted_levels_alpha_controls_resolve_from_the_effect() {
|
||||
let mut s = session();
|
||||
let o = ok(
|
||||
&mut s,
|
||||
r#"
|
||||
var c = app.project.items.addComp("Levels", 320, 180, 1, 3, 30);
|
||||
var l = c.layers.addSolid([1, 0, 0], "S", 320, 180, 1);
|
||||
var fx = l.property("ADBE Effect Parade").addProperty("ADBE Pro Levels2");
|
||||
fx.property("Alpha Input White").setValue(0.5);
|
||||
[fx.property("Alpha").property("Alpha Input White").value, fx.property("Alpha Input White").value]
|
||||
"#,
|
||||
);
|
||||
assert_eq!(o.result, json!([0.5, 0.5]));
|
||||
}
|
||||
Reference in new issue
Block a user