Copy link to clipboard
Copied
Figured this may be useful for people, I believe I first learned this code layout from Jeff Almasol awhile back. I use it myself as a general ref/starting point for most of my scripts.
{
function myScript(thisObj) {
function myScript_buildUI(thisObj) {
var myPanel = (thisObj instanceof Panel) ? thisObj : new Window("palette", "My Panel Name", [0, 0, 300, 300]);
res="group{orientation:'column', alignment:['fill', 'fill'], alignChildren:['fill', 'fill'],\
myStaticText: StaticText{text:'StaticText Text'},\
myEditText: EditText{text:'EditText text'},\
myButton: Button{text:'Button Name'},\
myCheckbox: Checkbox{text:'Checkbox Name'},\
myRadioButton: RadioButton{text:'RadioButton Name'},\
myDropDownList: DropDownList{properties:{items:['Item 1 Name', 'Item 2 Name', 'Item 3 Name', 'Item 4 Name']}},\
myListBox: ListBox{properties:{items:['Item 1 Name', 'Item 2 Name', 'Item 3 Name', 'Item 4 Name']}},\
myGroup: Group{orientation:'row', alignment:['fill', 'fill'], alignChildren:['fill', 'fill'],\
myGroupItem1: Button{text:'Hi'},\
myGroupItem2: Button{text:'Hello'},\
myGroupItem3: Button{text:'Goodbye'},\
},\
myPanel: Panel{text:'Panel Name', orientation:'column', alignChildren:['right', 'fill'],\
myPanelItem1: Button{text:'One'},\
myPanelItem2: Button{text:'Two'},\
myPanelItem3: Button{text:'Three'},\
},\
myTabbedPanel: Panel{type:'tabbedpanel', text:'Tabbed Panel Name', orientation:'column', alignChildren:['right', 'fill'],\
myTab1: Panel{type:'tab', text:'Tab 1', orientation:'column', alignChildren:['right', 'center'],\
aButton1: Button{text:'Button1'},\
},\
myTab2: Panel{type:'tab', text:'Tab 2', orientation:'column', alignChildren:['left', 'center'],\
aButton2: Button{text:'Button2'},\
},\
},\
myProgressBar: Progressbar{text:'Progressbar Name', minvalue:0, maxvalue:100, value:50},\
}"
//Add resource string to panel
myPanel.grp = myPanel.add(res);
// DropDownList default selection
myPanel.grp.myDropDownList.selection = 2;//Item index starts at 0
//Setup panel sizing and make panel resizable
myPanel.layout.layout(true);
myPanel.grp.minimumSize = myPanel.grp.size;
myPanel.layout.resize();
myPanel.onResizing = myPanel.onResize = function () {this.layout.resize();}
return myPanel;
}
var myScriptPal = myScript_buildUI(thisObj);
if ((myScriptPal != null) && (myScriptPal instanceof Window)) {
myScriptPal.center();
myScriptPal.show();
}
}
myScript(this);
}
Copy link to clipboard
Copied
If you copy and paste the above script into ExtendScript, it will not work.
In order for this script to work you will need to omit extra line spacing in the res= section. Once you have one contiguous block, it should work without issue.
Copy link to clipboard
Copied
Just tried it and it worked just fine in ESTK. Make sure that there is no stray formatting carried over from copying the text above. I've noticed that sometimes, quotes get turned to smart quotes, whitespace can accidentally get added, and carriage returns can randomly appear when copy and paste is used. Both can cause errors if they carry over into a script. Pasting into a simple text editor like TextEdit, or NotePad first can help, then copy that into your script.

Copy link to clipboard
Copied
David Thanks for sharing this. I am a bit confused on scripting floating UI windows, because I see this line in many of the scripts that are dockable:
• var myPanel = (thisObj instanceof Panel) ? thisObj : new Window("palette", "My Panel Name", [0, 0, 300, 300]);
Could I just use this in the beginning of my script instead of using the above function?
Copy link to clipboard
Copied
From the AE Scripting guide:
Running scripts from the Window menu
[...]
Instead of creating a Window object and adding controls to it, a ScriptUI Panels script uses the this object that
represents the panel.
Meaning when you launch something from the window menu inside of AE, a special variable called 'this' is used to represent the dockable UI window. Meaning, for a UI window you can do something like:
var myPanel = this;
myPanel.add("button", [10, 10, 100, 30], "To ol #1");
However, if you try to run the above from File > Scripts > Run Scripts file it will panic as the value of 'this' would be null (as there is no dockable panel).
So, most script writers use the boiler plate you posted above as a way to get your script to run whether called from File > Scripts or from Window. The ?: is called the ternary operator and it is just, in essence, an if-else statement. You could also re-write it like this:
var myPanel;
//check if this Obj is a panel (run from Window menu)
if(thisObj instance of Panel) {
//is a panel (called from Window menu)
myPanel = thisObj;
} else{
//not a panel (called from File > Scripts > Run)
myPanel = new Window();
}
Most scripts are wrapped in a master function to which 'this' is fed as 'thisObj', 'thisObj' then gets fed to the function you use to make your UI.
Hopefully that clears it up for you!
EDIT: Just as a note, when I was first attempting to write dockable UI scripts I was unable for the life of me to get them to work for a long time. Simply using the above method is not enough to get a dockable UI window. You also need this innocuous line at the bottom to actually make the ScriptUI layout manager layout your dockable window (which OP does have in his sample).
myPanel.layout.layout(true),
Copy link to clipboard
Copied
However, if you try to run the above from File > Scripts > Run Scripts file it will panic as the value of 'this' would be null (as there is no dockable panel).
Actually, this in javascript is the current object, and is never null.
At the entry point of a After Effects script, this is the global object, unless the script file is located in the ScriptUI Panels folder and launched from the Window menu, in which case it will be a special type of interface container (dockable panel).
In the latter case, if you want a graphic interface you don't need to create a window, just use that panel, and for all other scripts you'll need to create a window.
Xavier.
Copy link to clipboard
Copied
Thank you for the detailed examples. This has cleared up a lot about dockable panels.
Copy link to clipboard
Copied
For those who want, here is the code for a floating panel only: (note! The image-buttons needs an image or they will get an error)
var myWin = new Window("palette", "My Window", undefined);
myWin.orientation = "row";
var groupOne = myWin.add("group", undefined, "GroupOne");
groupOne.orientation = "column";
groupOne.add("button", undefined, "Button");
groupOne.add("checkbox", undefined, "CheckBox");
groupOne.add("radiobutton", undefined, "RadioButton");
var dd = groupOne.add("dropdownlist", undefined, ["Item 1", "Item 2", "Item 3"]);
dd.selection = 2;
var pb = groupOne.add("progressbar", undefined, "ProgressBar");
pb.value = 50;
var groupTwo = myWin.add("group", undefined, "GroupTwo");
groupTwo.orientation = "column";
groupTwo.add("iconbutton", undefined, "~/Desktop/Alert.png", "IconButton");
groupTwo.add("image", undefined, "~/Desktop/Alert.png");
groupTwo.add("statictext", undefined, "My custom text");
groupTwo.add("edittext", undefined, "My default text");
var s = groupTwo.add("slider", undefined, "Slider");
s.value = 60;
groupTwo.add("scrollbar", undefined, "Scrollbalr");
var panelOne = myWin.add("panel", undefined, "My panel");
panelOne.add("button", undefined, "Button 1");
panelOne.add("button", undefined, "Button 2");
panelOne.add("button", undefined, "Button 3");
panelOne.add("button", undefined, "Button 4");
var myTab = myWin.add("tabbedpanel", undefined, "");
var tabContent1 = myTab.add("tab", undefined, "Tab1");
tabContent1.add("button", undefined, "My button in the tab");
var tabContent2 = myTab.add("tab", undefined, "Tab2");
tabContent2.add("radiobutton", undefined, "My radio button");
var tabContent3 = myTab.add("tab", undefined, "Tab3");
var groupThree = myWin.add("group", undefined, "GroupThree");
groupThree.orientation = "column";
groupThree.add("listbox", undefined, ["Item 1", "Item 2", "Item 3"]);
var myMultiColumnList = groupThree.add("listbox", undefined, "My Listbox",{
numberOfColumns: 3,
showHeaders: true,
columnTitles: ["Column 1", "Column 2", "Column 3"]
});
var myItems = myMultiColumnList.add("item", "Item 1");
myItems.subItems[0].text = "Item 2";
myItems.subItems[1].text = "Item 3";
var groupFour = myWin.add("group", undefined, "GroupFour");
groupFour.orientation = "column";
var myTree = groupFour.add("treeview", undefined, ["Item 1", "Item 2", "Item 3"], "MyTreeView");
var myMultiTree = groupFour.add("treeview", [0, 0, 200, 75], "My Tree View");
var myTreeItems = myMultiTree.add("node", "Item 1");
var myNode = myTreeItems.add("node", "Item 2");
myNode.add("item", "Item 3");
myWin.center()
myWin.show();
Get ready! An upgraded Adobe Community experience is coming in January.
Learn more