hello all... just started with soundflow a few weeks ago and LOVING it so far!
a bit of a newbie question here perhaps, but couldn't find an obvious solution:
what is the best way to script the PT toolbar display in the edit window?
i'm working on a macro that will import my layout preferences into sessions and i'd like to be able to turn off "Zoom Controls", "MIDI controls", "Synchronization", and "Output Meters". this is usually accomplished by right-clicking on the toolbar or clicking the little triangle drop-down menu in the upper righthand corner of the edit window, but i was wondering if there was a way to do it without needing to simulate mouse clicks... like perhaps a menu option i'm missing somewhere.
many thanks!
joseph
- Raphael Sepulveda @raphaelsepulveda2022-08-05 23:51:13.805Z
Hey @JOSEPH_BRANCIFORTE, so glad you've been enjoying SoundFlow! 😃
You're correct, as far as I'm aware, the only way to toggle the visibility of those modules is from the methods you mentioned.
With that said, I propose the following script which leverages UI automation via the triangle popup menu on the top right.
This script will enable or disable any menu item you specify from that popup menu.
If you take a peek at the bottom of the script, I've already set it to disable the menu items you specified 🤘🏼
/** @param {{ names: string[], targetValue: "Enable"|"Disable" }} args */ function setMainToolbarOptions({ names, targetValue }) { sf.ui.proTools.appActivateMainWindow(); const toolbarOptionsMenuItems = sf.ui.proTools.mainWindow.toolbarOptionsMenuButton.popupMenuFetchAllItems().menuItems; const targetToolBarMenuItems = names.map(name => toolbarOptionsMenuItems.find(menuItem => menuItem.names[0].endsWith(name))); targetToolBarMenuItems.forEach(menuItem => { const checkmark = "✓"; if (targetValue === "Enable" && menuItem.names[0].startsWith(checkmark)) return; if (targetValue === "Disable" && !menuItem.names[0].startsWith(checkmark)) return; menuItem.element.elementClick(); }); sf.ui.proTools.appActivateMainWindow(); } setMainToolbarOptions({ names: ["Zoom Controls", "MIDI Controls", "Synchronization", "Output Meters"], targetValue: "Disable" });
Hope that helps!
JOSEPH BRANCIFORTE @JOSEPH_BRANCIFORTE
hi @raphaelsepulveda... this is amazing... works perfectly... thanks so much for taking the time!
i'm still wrapping my head around the coding side of things at this point, any chance you might be able to explain a bit about how you've defined the function to get it recognize the triangle menu and enable/disable options? what does your workflow look like in soundflow to write a little script like this?
also, if i've got a mixture of items i want to enable and disable, do i have to call the function twice? i got what i needed to work with the following code, but trying to learn best practices.
thanks again!
/** @param {{ names: string[], targetValue: "Enable"|"Disable" }} args */ function setMainToolbarOptions({ names, targetValue }) { sf.ui.proTools.appActivateMainWindow(); const toolbarOptionsMenuItems = sf.ui.proTools.mainWindow.toolbarOptionsMenuButton.popupMenuFetchAllItems().menuItems; const targetToolBarMenuItems = names.map(name => toolbarOptionsMenuItems.find(menuItem => menuItem.names[0].endsWith(name))); targetToolBarMenuItems.forEach(menuItem => { const checkmark = "✓"; if (targetValue === "Enable" && menuItem.names[0].startsWith(checkmark)) return; if (targetValue === "Disable" && !menuItem.names[0].startsWith(checkmark)) return; menuItem.element.elementClick(); }); sf.ui.proTools.appActivateMainWindow(); } setMainToolbarOptions({ names: ["Zoom Controls", "MIDI Controls", "Synchronization", "Output Meters"], targetValue: "Disable" }) setMainToolbarOptions({ names: ["Transport", "Expanded Transport"], targetValue: "Enable" }) ;
Chris Shaw @Chris_Shaw2022-08-07 13:58:10.205Z
Yep, that's the right way.
The only thing I would change is move that last ";" next to "})" so it reads "});"If you have a large list of items to disable / enable you can define each list as its own array.
It makes the code easier to read.const disableItems = ["Zoom Controls", "MIDI Controls", "Synchronization", "Output Meters"]; const enableItems = ["Transport", "Expanded Transport"]; setMainToolbarOptions({ names: disableItems, targetValue: "Disable" }); setMainToolbarOptions({ names: enableItems, targetValue: "Enable" });
- In reply toJOSEPH_BRANCIFORTE⬆:
Raphael Sepulveda @raphaelsepulveda2022-08-08 02:30:16.313Z
@JOSEPH_BRANCIFORTE, glad that worked out!
The following video, that Christian did a few years back, is a great place to start understanding the workflow for writing a script like this:
https://youtu.be/20ECpTUy_jkOh, and yes, as @Chris_Shaw pointed out, calling the function twice is the easiest way to set different settings 👍🏼
Yujiro Yonetsu @Yujiro_Yonetsu
Hello
excuse me for stepping in.
I found this script in the forum and I wanted to do the same thing, so I tried it.
Then I get an error on line 6.Could not open popup menu from specified element (456: Line 6)
Popup menu was not found
Popup window was not found after waiting 2000 msPro Tools ver is the latest 2022.12.
Can you please let me know if you know the cause of the problem? Thank you in advance.Raphael Sepulveda @raphaelsepulveda2023-01-16 07:05:24.701Z
Hey @Yujiro_Yonetsu,
Something seems to have changed in the current version of Pro Tools.
Give this revised version of the script a try:
/** @param {{ names: string[], targetValue: "Enable"|"Disable" }} args */ function setMainToolbarOptions({ names, targetValue }) { const popupMenuWin = sf.ui.proTools.windows.whoseTitle.is("Menu 19 items, Zoom Controls").first; sf.ui.proTools.appActivateMainWindow(); sf.ui.proTools.mainWindow.toolbarOptionsMenuButton.elementClick(); popupMenuWin.elementWaitFor(); const toolbarOptionsMenuItems = popupMenuWin.menuItems.map(menuItem => menuItem); const targetToolBarMenuItems = names.map(name => toolbarOptionsMenuItems.find(menuItem => menuItem.title.value.endsWith(name) ) ); targetToolBarMenuItems.forEach(menuItem => { const checkmark = "✓"; if (targetValue === "Enable" && menuItem.title.value.startsWith(checkmark)) return; if (targetValue === "Disable" && !menuItem.title.value.startsWith(checkmark)) return; menuItem.elementClick(); }); sf.ui.proTools.appActivateMainWindow(); } setMainToolbarOptions({ names: ["Zoom Controls", "MIDI Controls", "Synchronization", "Output Meters"], targetValue: "Disable" });
Yujiro Yonetsu @Yujiro_Yonetsu
It worked perfectly!
Thank you!
- In reply toraphaelsepulveda⬆:TThomas Gloor @Thomas_Gloor
I'd like to write a script that "gets" the current toolbar settings, stores them into a JSON so another script can recall these settings.
The recall-settings part works fine if I have 2 arrays (enable, disable) in a JSON, but I don't find a way to "get" the items.
Do you have a solution?
Thank you lots, as always!
Raphael Sepulveda @raphaelsepulveda2024-03-20 16:32:08.197Z
@Thomas_Gloor, sure thing. I'd do it like this:
function getMainToolbarOptions() { const popupMenuWin = sf.ui.proTools.windows.whoseTitle.is("Menu 19 items, Zoom Controls").first; const checkmark = "✓"; sf.ui.proTools.appActivateMainWindow(); sf.ui.proTools.mainWindow.toolbarOptionsMenuButton.elementClick(); popupMenuWin.elementWaitFor(); const toolbarOptionsMenuItems = popupMenuWin.menuItems.map(menuItem => menuItem); const options = toolbarOptionsMenuItems.map(menuItem => ({ name: menuItem.title.value.replace(`${checkmark}, `, ""), isEnabled: menuItem.title.value.startsWith(checkmark) })); sf.ui.proTools.appActivateMainWindow(); return { options }; } sf.file.writeJson({ path: "~/Downloads/ToolbarOptions.json", json: getMainToolbarOptions().options });
- TThomas Gloor @Thomas_Gloor
Thank you so much!
I took the liberty of adding a bit of sorting at the end so it can be used with
setMainToolbarOptions
Here it is:
function getMainToolbarOptions() { const popupMenuWin = sf.ui.proTools.windows.whoseTitle.is("Menu 19 items, Zoom Controls").first; const checkmark = "✓"; let toolbarPreferencesEnable = [] let toolbarPreferencesDisable = [] sf.ui.proTools.appActivateMainWindow(); sf.ui.proTools.mainWindow.toolbarOptionsMenuButton.elementClick(); popupMenuWin.elementWaitFor(); const toolbarOptionsMenuItems = popupMenuWin.menuItems.map(menuItem => menuItem); const options = toolbarOptionsMenuItems.map(menuItem => ({ name: menuItem.title.value.replace(`${checkmark}, `, ""), isEnabled: menuItem.title.value.startsWith(checkmark) })); sf.ui.proTools.appActivateMainWindow(); options.forEach(entry => { if (entry.isEnabled) { toolbarPreferencesEnable.push(entry.name) } else { toolbarPreferencesDisable.push(entry.name) } }) return { toolbarPreferencesEnable, toolbarPreferencesDisable }; }
Raphael Sepulveda @raphaelsepulveda2024-03-21 20:05:01.525Z
Awesome!
- In reply toraphaelsepulveda⬆:TThomas Gloor @Thomas_Gloor
Hi @raphaelsepulveda
I hope you're well :)This doesn't seem to work anymore on PT 2024.10.1
I'm getting this error:
TypeError: Cannot read property 'title' of undefined (A02b - Recall Pro Tools Options 2.0 line 83)
Any idea?
Thank you lots!
Raphael Sepulveda @raphaelsepulveda2025-01-08 21:50:22.831Z
Hey @Thomas_Gloor! Hope you had a great holiday season 🎄
Ah, looks that the title of the popup menu has changed slightly from:
const popupMenuWin = sf.ui.proTools.windows.whoseTitle.is("Menu 19 items, Zoom Controls").first;
to:
// 2024.10.1 const popupMenuWin = sf.ui.proTools.windows.whoseTitle.is("Menu 16 items, Zoom Controls").first;
The only thing that changed was the number of items in the title, so, to future-proof against this, I recommend using this instead:
const popupMenuWin = sf.ui.proTools.windows.whoseTitle.endsWith(" items, Zoom Controls").first;
- TThomas Gloor @Thomas_Gloor
Thank you @raphaelsepulveda !
- In reply toJOSEPH_BRANCIFORTE⬆:JOSEPH BRANCIFORTE @JOSEPH_BRANCIFORTE
thanks @Chris_Shaw, super helpful info!
i feel like a more fleshed version of this could be a useful script to have as a default soundflow function.
personally, i'm always getting sessions from clients that have weird stuff enabled in the toolbar... it's been very satisfying to have the above script + my preferences script as a one button solution for session prep!
Chris Shaw @Chris_Shaw2022-08-07 23:55:51.431Z
You should also check out the Pro Tools Preferences Manager in the store - it's free.