mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-30 04:57:54 -06:00
Scripts: subfolders of the Scripts and ScriptUI Panels folders become submenus
An extension that ships several panels no longer adds one Window menu entry per panel: `Scripts/ScriptUI Panels/Motion Kit/Animate.jsx` shows as Window > Motion Kit > Animate.jsx, and a subfolder of `Scripts/` is a submenu of File > Scripts. Top-level scripts are unchanged. - Script names may be `Folder/File.jsx`: exactly one folder, each part a bare name (no `..`, `\`, NUL or empty part), never `ScriptUI Panels/...` under `Scripts/`. - window.scriptPanel, file.runScript, file.uninstallScript, file.scripts.list and scriptui_panels.json take such names; a panel's tab is titled after its file. - ConfigStore::list_dirs (DirConfig, MemoryConfig) lists the subfolders. - menus::dynamic_nodes groups a folder's entries into a MenuNode::Submenu; the egui and native menus draw it with their submenu code. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
eb5108786b
commit
bdcd2dc051
@@ -86,3 +86,27 @@ fn open_panels_open_again_at_the_next_launch() {
|
||||
let mut s = session(&store);
|
||||
assert_eq!(s.execute("window.restoreScriptPanels", json!({})).unwrap(), json!({"opened": [], "failed": []}));
|
||||
}
|
||||
|
||||
/// A panel in a subfolder (Window ▸ Motion Kit ▸ Animate.jsx) is `Motion Kit/Animate.jsx`: it opens
|
||||
/// titled after its file and opens again at the next launch.
|
||||
#[test]
|
||||
fn a_panel_in_a_subfolder_opens_and_opens_again_at_the_next_launch() {
|
||||
let store = Arc::new(MemoryConfig::default());
|
||||
store.write(&format!("{PANELS_DIR}/Motion Kit/Animate.jsx"), PANEL).unwrap();
|
||||
let mut s = session(&store);
|
||||
let list = s.execute("file.scripts.list", json!({})).unwrap();
|
||||
assert!(list.as_array().unwrap().iter().any(|e| e["name"] == "Motion Kit/Animate.jsx" && e["panel"] == true), "{list}");
|
||||
let r = s.execute("window.scriptPanel", json!({"name": "Motion Kit/Animate.jsx"})).unwrap();
|
||||
let w = s.script_ui.window(r["window"].as_u64().unwrap() as u32).unwrap();
|
||||
assert_eq!((w.kind, w.title.as_str()), (WindowKind::Panel, "Animate"));
|
||||
assert_eq!(remembered(&store), json!({"open": ["Motion Kit/Animate.jsx"]}));
|
||||
// A saved name that leaves the folder, or goes two folders deep, fails and is forgotten.
|
||||
store.write(OPEN_PANELS_FILE, &json!({"open": ["../Top.jsx", "Motion Kit/Animate.jsx", "a/b/c.jsx"]}).to_string()).unwrap();
|
||||
drop(s);
|
||||
let mut s = session(&store);
|
||||
let r = s.execute("window.restoreScriptPanels", json!({})).unwrap();
|
||||
assert_eq!(r["opened"], json!(["Motion Kit/Animate.jsx"]));
|
||||
assert_eq!(r["failed"].as_array().unwrap().iter().map(|f| f["name"].as_str().unwrap()).collect::<Vec<_>>(), ["../Top.jsx", "a/b/c.jsx"]);
|
||||
assert!(panel_window(&s, "Motion Kit/Animate.jsx").is_some());
|
||||
assert_eq!(remembered(&store), json!({"open": ["Motion Kit/Animate.jsx"]}));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user