feat(plugin,node): bridge parametric params into the node/inspector path
- ValueType::Parametric; the node input carries the whole curve set as NodeValue::Text(JSON) so undo and project serialization come for free - translation pass builds the input with the default-curve JSON and the dimension/range/ui-colour properties - edits flow both ways: node input (UI) -> curves_from_json -> set_ofx(Parametric) on the instance; plugin-side Set/Add/Delete -> notify_instance_changed -> JSON written back to the input (undoable) - screenshot example: gate the macOS-only offscreen capture items so the workspace tests build on Linux/Windows
This commit is contained in:
@@ -206,7 +206,7 @@ pub fn value_to_string(declared: ValueType, value: &NodeValue, key_track: bool)
|
||||
}
|
||||
}
|
||||
ValueType::Float => format!("{}", value.to_double()),
|
||||
ValueType::Text | ValueType::StrCombo => match value {
|
||||
ValueType::Text | ValueType::StrCombo | ValueType::Parametric => match value {
|
||||
NodeValue::Text(s) => s.clone(),
|
||||
NodeValue::StrCombo(s) => s.clone(),
|
||||
_ => String::new(),
|
||||
@@ -249,6 +249,7 @@ pub fn string_to_value(declared: ValueType, text: &str) -> NodeValue {
|
||||
ValueType::Float => NodeValue::Float(text.trim().parse().unwrap_or(0.0)),
|
||||
ValueType::Text => NodeValue::Text(text.to_string()),
|
||||
ValueType::StrCombo => NodeValue::StrCombo(text.to_string()),
|
||||
ValueType::Parametric => NodeValue::Text(text.to_string()),
|
||||
_ => NodeValue::None,
|
||||
}
|
||||
}
|
||||
@@ -1082,3 +1083,42 @@ fn resolve_folder_children(
|
||||
fn lock<T>(m: &Mutex<T>) -> std::sync::MutexGuard<'_, T> {
|
||||
m.lock().unwrap_or_else(|e| e.into_inner())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
/// Value codec 对 Parametric 输入的往返(save_immediate /
|
||||
/// load_immediate 对 standard 值走的纯函数路径:split →
|
||||
/// value_to_string → string_to_value → combine;XML 桥由
|
||||
/// tests/serializer_test.rs 覆盖)。
|
||||
#[test]
|
||||
fn parametric_input_value_codec_roundtrip() {
|
||||
let declared = ValueType::Parametric;
|
||||
let json = r#"{"curves":[[{"key":0,"value":0,"slope":1},{"key":0.5,"value":0.6,"slope":1}]]}"#;
|
||||
let value = NodeValue::Text(json.to_string());
|
||||
|
||||
// save 侧:standard 值按声明类型拆轨(Text → 单轨整值)。
|
||||
let tracks = value.split_into_tracks(declared);
|
||||
assert_eq!(tracks.len(), 1);
|
||||
let text = value_to_string(declared, &tracks[0], true);
|
||||
assert_eq!(text, json);
|
||||
|
||||
// load 侧:track 文本还原 + 合并回整值。
|
||||
let restored = string_to_value(declared, &text);
|
||||
assert_eq!(restored, value);
|
||||
let combined = NodeValue::combine_tracks(&[restored], declared);
|
||||
assert_eq!(combined, value);
|
||||
|
||||
// key_track=false 形态(整值轨道)同样往返。
|
||||
assert_eq!(value_to_string(declared, &value, false), json);
|
||||
|
||||
// 载荷不是 Text(防御)→ 空串;声明类型 Parametric 无键帧
|
||||
// 插值、无 C++ 判别值。
|
||||
assert_eq!(value_to_string(declared, &NodeValue::None, true), "");
|
||||
assert!(!declared.can_interpolate());
|
||||
assert_eq!(declared.to_cpp_discriminant(), 0);
|
||||
assert!(declared.is_string());
|
||||
assert_eq!(declared.to_oak(), crate::value::oak::STRING);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,6 +103,11 @@ pub enum ValueType {
|
||||
NodeRef,
|
||||
/// Push button (no payload).
|
||||
PushButton,
|
||||
/// Parametric curve (OpenFX parametric param; the value payload is a
|
||||
/// [`NodeValue::Text`] JSON document, see
|
||||
/// `oakplugin::param_curve::curves_to_json` — string-carried like
|
||||
/// [`ValueType::Text`]).
|
||||
Parametric,
|
||||
}
|
||||
|
||||
/// A node value. `Texture` stores an oakrender handle; dropping the
|
||||
@@ -310,8 +315,9 @@ impl ValueType {
|
||||
ValueType::Vec3 => oak::VEC3,
|
||||
ValueType::Vec4 => oak::VEC4,
|
||||
ValueType::Combo => oak::COMBO,
|
||||
// String-carried types (k_file/k_text/k_font/k_str_combo).
|
||||
ValueType::Text | ValueType::StrCombo => oak::STRING,
|
||||
// String-carried types (k_file/k_text/k_font/k_str_combo;
|
||||
// parametric carries a JSON text).
|
||||
ValueType::Text | ValueType::StrCombo | ValueType::Parametric => oak::STRING,
|
||||
_ => oak::NONE,
|
||||
}
|
||||
}
|
||||
@@ -320,7 +326,10 @@ impl ValueType {
|
||||
/// the dedicated string getters/setters, `// CPP-PARITY: valueconvert.h`
|
||||
/// `value_type_is_string`).
|
||||
pub fn is_string(self) -> bool {
|
||||
matches!(self, ValueType::Text | ValueType::StrCombo)
|
||||
matches!(
|
||||
self,
|
||||
ValueType::Text | ValueType::StrCombo | ValueType::Parametric
|
||||
)
|
||||
}
|
||||
|
||||
/// Number of keyframe tracks the type splits into (C++
|
||||
@@ -363,8 +372,9 @@ impl ValueType {
|
||||
// k_subtitle_params = 20 has no Rust type counterpart.
|
||||
ValueType::Binary => 21,
|
||||
ValueType::PushButton => 22,
|
||||
// No C++ counterpart (k_none).
|
||||
ValueType::NodeRef => 0,
|
||||
// No C++ counterpart (k_none); the parametric curve payload
|
||||
// lives in the JSON text (k_bezier = 15 is a different model).
|
||||
ValueType::NodeRef | ValueType::Parametric => 0,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user