Window/Panel/Palette drawing confusion

Find out why the . goes before the /

Moderator: Paul Tuersley

Post Reply
tzchaiboy
Posts: 3
Joined: April 25th, 2013, 10:51 am

This is my first foray into using ScriptUI, so it's possible this is a really easy fix and I'm just missing it. I've adapted one of my own scripts into one that uses a GUI instead of dialog prompts to gather user input. Running the script from the Script Editor results in a single dialog window popping up with all my controls, which is exactly as expected and makes me so happy. However, when I run the script from After Effects, it creates two things: one is my happy dialog window, and the other is what looks like a broken panel that doesn't respond to anything. After I successfully run my script or cancel the dialog, that panel resolves into a more normal looking - albeit completely empty - dockable panel.

Just not sure what I would/should change to either: (1) have my controls show up in the panel instead of the dialog window, or (2) have the dialog window appear without the panel showing up next to it as it currently does.

I'm including two screenshots; the first shows what gets drawn on when I run the script initially, and the second shows what remains after running or canceling the actions in the dialog window. I'm also pasting the first section of my code (the part that deals with generating the GUI).

Thank you for taking the time! :D

Code: Select all

var scriptWindow = new Window ('dialog', 'Beam Connection Builder'),
//Create window groups and elements
topLevelGroup = scriptWindow.add ('group'),
    effectPanel = topLevelGroup.add('panel', undefined, 'Beam Connection Settings'),
        useSelectedLayers = effectPanel.add('checkbox', undefined, 'Use selected layers'),
        layerRangeOptions = effectPanel.add('group'),
            useLayerRange = layerRangeOptions.add('checkbox', undefined, 'Use layers in range:'),
            layerRangeMin = layerRangeOptions.add('dropdownlist'),
            layerRangeDivider = layerRangeOptions.add('statictext', undefined, ' to '),
            layerRangeMax = layerRangeOptions.add('dropdownlist'),
        parentLayers = effectPanel.add('checkbox', undefined, 'Parent beams to source layers'),
        distanceGroup = effectPanel.add('group'),
            distanceSliderLabels = distanceGroup.add('group'),
                minDistanceLabel = distanceSliderLabels.add('statictext', undefined, 'Min Distance:'),
                maxDistanceLabel = distanceSliderLabels.add('statictext', undefined, 'Max Distance:'),
            distanceSliderNums = distanceGroup.add('group'),
                minDistanceNum = distanceSliderNums.add('edittext', undefined, 'Default'),
                maxDistanceNum = distanceSliderNums.add('edittext', undefined, 'Default'),
            distanceSliders = distanceGroup.add('group'),
                minDistanceSlider = distanceSliders.add('slider', undefined, 0, 0, 2000),
                maxDistanceSlider = distanceSliders.add('slider', undefined, 0, 0, 2000),
    dialogButtons = topLevelGroup.add('group'),
        createConnections = dialogButtons.add('button', undefined, 'Create Connections'),
        cancelDialog = dialogButtons.add('button', undefined, 'Cancel');

activeComp = app.project.activeItem;
if (activeComp) { totalLayers = activeComp.layers.length; } else { totalLayers = 1; }

//align groups and elements, initialize default values
topLevelGroup.orientation = 'column';
layerRangeOptions.orientation = 'row';
effectPanel.orientation = 'column';
distanceGroup.orientation = 'row';
distanceSliderLabels.orientation = 'column';
distanceSliderNums.orientation = 'column';
distanceSliders.orientation = 'column';
effectPanel.alignChildren = 'left';

if (activeComp.selectedLayers.length > 0) {
        useSelectedLayers.value = true;
        useLayerRange.value = false;
    } else {
        useLayerRange.value = true;
        useSelectedLayers.value = false;
        }
    
parentLayers.value = true;
minDistanceNum.characters = 5;
maxDistanceNum.characters = 5;
evaluateDropDownLists();
... callback functions, utility functions, code for pushing the main button, etc...

Code: Select all

//draw the window
if (activeComp == undefined) {
    alert('You must have an active Comp open to run this tool!'); 
    } else {
        scriptWindow.show();
        }
Attachments
Screenshot 1 - What shows up when I run my script initially; I don't understand the black panel on the left
Screenshot 1 - What shows up when I run my script initially; I don't understand the black panel on the left
Screen Shot 2013-04-25 at 3.01.46 PM.png (122.95 KiB) Viewed 11722 times
Screenshot 2 - What shows up after running or dismissing the dialog box; I don't mind this panel, but I either want it not there or have it take the place of my floating box when it's there.
Screenshot 2 - What shows up after running or dismissing the dialog box; I don't mind this panel, but I either want it not there or have it take the place of my floating box when it's there.
Screen Shot 2013-04-25 at 3.01.57 PM.png (108.08 KiB) Viewed 11722 times
Paul Tuersley
Posts: 704
Joined: June 5th, 2004, 7:59 am
Location: London, UK

Are you trying to launch it as a dockable panel by installing it in the ScriptUI Panels folder and launching it from the Window menu? This will always create a panel, regardless of whether your script uses it. For scripts to work as dockable panels they need to be coded in a particular way to receive the panel object created by launching them and applying the UI to that, but this would be for non-modal type uses.

When I try running your script from the File > Scripts menu it seems to work ok. You can either install directly into the Scripts folder or launch using File > Scripts > Run Script File.

Paul
tzchaiboy
Posts: 3
Joined: April 25th, 2013, 10:51 am

Hmmm... now I can't decide what I'd prefer. The first couple times I tried launching it through File > Scripts, I couldn't get it to work. I just assumed scripts that used GUI coding had to be launched through the Window menu, but since you mentioned that I tried it again and had no problems.

Is there a way to code it so that it works both ways and could be left up to the user's preference? I think I'd like it if you could choose to either launch it from File > Scripts and have it pop up as a window, *or* copy it to the ScriptsUI folder and launch it through Window as a dockable panel.

Hopefully that makes sense. Now that I know it runs properly just as a script and doesn't *have* to sit in the Window panel, I'm not as worried. But I also wouldn't mind figuring out how to round it out to be as robust and versatile as possible.

Thanks!
Paul Tuersley
Posts: 704
Joined: June 5th, 2004, 7:59 am
Location: London, UK

Something like this:

Code: Select all

{
	function BeamBuilder(thisObj) {
			
		function BeamBuilder_buildUI(thisObj) {

			var scriptWindow = (thisObj instanceof Panel) ? thisObj : new Window("dialog", 'Beam Connection Builder', undefined, {resizeable:true});
			// you may want to change "dialog" to "palette" and make it work in a non modal way that doesn't require a comp to be active at launch.

			//Create window groups and elements
			topLevelGroup = scriptWindow.add ('group'),
				effectPanel = topLevelGroup.add('panel', undefined, 'Beam Connection Settings'),
					useSelectedLayers = effectPanel.add('checkbox', undefined, 'Use selected layers'),
					layerRangeOptions = effectPanel.add('group'),
						useLayerRange = layerRangeOptions.add('checkbox', undefined, 'Use layers in range:'),
						layerRangeMin = layerRangeOptions.add('dropdownlist'),
						layerRangeDivider = layerRangeOptions.add('statictext', undefined, ' to '),
						layerRangeMax = layerRangeOptions.add('dropdownlist'),
					parentLayers = effectPanel.add('checkbox', undefined, 'Parent beams to source layers'),
					distanceGroup = effectPanel.add('group'),
						distanceSliderLabels = distanceGroup.add('group'),
							minDistanceLabel = distanceSliderLabels.add('statictext', undefined, 'Min Distance:'),
							maxDistanceLabel = distanceSliderLabels.add('statictext', undefined, 'Max Distance:'),
						distanceSliderNums = distanceGroup.add('group'),
							minDistanceNum = distanceSliderNums.add('edittext', undefined, 'Default'),
							maxDistanceNum = distanceSliderNums.add('edittext', undefined, 'Default'),
						distanceSliders = distanceGroup.add('group'),
							minDistanceSlider = distanceSliders.add('slider', undefined, 0, 0, 2000),
							maxDistanceSlider = distanceSliders.add('slider', undefined, 0, 0, 2000),
				dialogButtons = topLevelGroup.add('group'),
					createConnections = dialogButtons.add('button', undefined, 'Create Connections'),
					cancelDialog = dialogButtons.add('button', undefined, 'Cancel');


			//align groups and elements, initialize default values
			topLevelGroup.orientation = 'column';
			layerRangeOptions.orientation = 'row';
			effectPanel.orientation = 'column';
			distanceGroup.orientation = 'row';
			distanceSliderLabels.orientation = 'column';
			distanceSliderNums.orientation = 'column';
			distanceSliders.orientation = 'column';
			effectPanel.alignChildren = 'left';
			
			scriptWindow.layout.layout(true);
			
			return scriptWindow;
		}
			


		if (parseFloat(app.version) < 8 ) {
			alert("This script requires After Effects CS3 or later");
		} else  {
			var myPal = BeamBuilder_buildUI(thisObj);
			if (myPal != null) {
				if (myPal instanceof Window) {
					myPal.center();
					myPal.show();
				}
			}
		}
	}
	BeamBuilder(this);
}
Post Reply