Check if selection is a project item or a layer

Find out why the . goes before the /

Moderator: Paul Tuersley

Post Reply
User avatar
axymark
Posts: 23
Joined: November 29th, 2013, 7:04 am

Hi. First post here. Novice afterfx scripter, so fair warning in advance.

I need to get a name of a composition whether it's selected in the Project window or as a precomp layer in timeline.

My pseudocode:

Code: Select all

var activeItem = app.project.activeItem;
if (activeItem is a compItem)
{
    get activeItem name;
}
    else if (activeItem is a layer and a compItem)
{
    get selected layer's source name;
}
I cant really figure out how to make this work, though. Any help would be very much appreciated.
Paul Tuersley
Posts: 704
Joined: June 5th, 2004, 7:59 am
Location: London, UK

This is a bit tricky because activeItem can either represent the comp that is currently active, or an item in the project panel if that is active and selected. In the second case, activeItem returns null if multiple items are selected in the project panel, so then you would have to loop through app.project.items looking for any that are .selected and seeing if they were instanceof CompItem.

Here is some example code but it really depends on what exactly you're trying to do. I guess you could assume that if a comp is active (either one comp only selected in the project panel, or an actually active comp) and that no layers are selected in that comp, then that's the name you're after, otherwise if a layer is selected and its source is a CompItem then that's the name you're after.

Code: Select all

var activeItem = app.project.activeItem;

if (activeItem != null && activeItem instanceof CompItem) {
	alert(activeItem.name + " is active comp");
	
	for (var x = 0; x < activeItem.selectedLayers.length; x++) {
		if (activeItem.selectedLayers[x].source instanceof CompItem) {
			alert("Precomp layer: " + activeItem.selectedLayers[x].source.name + " is selected");
		}
	}
}

User avatar
axymark
Posts: 23
Joined: November 29th, 2013, 7:04 am

Huh, that's interesting.

Your code works perfectly well for me until i have a case when i'm selecting a comp item in project panel that has a layer selected inside. I could have opened up this comp in the past, selected a precomp and than moved on to other things. Later on, when i select a composition in project panel, the name i'm getting would really depend on whether i have something selected inside or not.

I now seem to recall something from the Scripting Guide about a method to check if a composition is opened in viewport or not. I'll go and try read some more about it but if you have an advice, do tell.

Thank you.
Paul Tuersley
Posts: 704
Joined: June 5th, 2004, 7:59 am
Location: London, UK

I think you mean the activeViewer stuff. I did have a look at this when coming up with a response for you. You can check for app.activeViewer.active and find the activeViewer.type but this only covers Comp, Footage and Layer windows. activeViewer.active returns false if either the project or timeline panels are active which I think would be a problem.

One thought I had is that maybe you could use something like app.executeCommand(app.findMenuCommandId("Null Object")) as certain menu items will only work if a comp is active. For example, you'd do all the other code, storing what layers were selected etc, then try this command and see if a new layer was added to the comp. If it was, the comp was properly active. You can then delete the new layer and restore the previous selection. But this seems like massive overkill.
User avatar
axymark
Posts: 23
Joined: November 29th, 2013, 7:04 am

May be an overkill, but it gets me moving forward. How would you check if this particular null was created?

I threw something together utilizing markers.

Code: Select all

var activeItem = app.project.activeItem;
var selectedLayer = activeItem.selectedLayers[0];

try {
    app.executeCommand(2157); // app.findMenuCommandId("Add Marker")
    if (selectedLayer.property("ADBE Marker").numKeys == 0) {
        throw ("err1");
    } else {
        var x = "This is a layer.";
    }
}
catch (err) {
    var x = "This is a project item.";
}

alert(x);
It's flawed. If a layer inside the compItem is selected and already has a marker, it wont matter that i cant do app.executeCommand at that moment.

So is there a way to check if the command was run or not?
Paul Tuersley
Posts: 704
Joined: June 5th, 2004, 7:59 am
Location: London, UK

I haven't tested it but something like this:

var compActive = false;
var numlayers = activeItem.numlayers;
// try adding null here
if (activeItem.numLayers > numlayers) {
compActive = true;
activeItem.layer(1).remove();
}
User avatar
axymark
Posts: 23
Joined: November 29th, 2013, 7:04 am

Yup, that works. Just needed an uppercase "L" in numLayers but easy enough to spot.

For anyone who happens to stumble upon this thread in the future:

Code: Select all

var activeItem = app.project.activeItem;
var compActive = false;
var numLayers = activeItem.numLayers;
app.executeCommand(2767); // New Null Layer
if (activeItem.numLayers > numLayers) {
    compActive = true;
    activeItem.layer(1).remove();
}
alert (compActive);
Thank you for your help, Paul.
Alan Eddie
Posts: 30
Joined: January 12th, 2012, 1:36 am
Location: Ireland
Contact:

For anyone coming back to this, I found this thread really helpful. I added removing the source dummy null, so no accumulation in the project. Also - returning the original layer selection as making the null would disrupt the original selection.

Code: Select all

function ael_activeProjectOrComp() {
//messes up selection of layers... 

    var activeItem = app.project.activeItem;  //null if multiple are selected in the proj panel.
    if ( activeItem == null ) {
        //assume we are in project mode and nothing selected or multiple files in proj.
        return "project";
    }

    //now we could have a single obj selected in proj, or an active comp.
    var numLayers = activeItem.numLayers;
    var sel = ael_getSelectedLayers();

    app.executeCommand( 2767 ); // New Null Layer
    if ( activeItem.numLayers > numLayers ) {
        //delete null inproject.
        activeItem.selectedLayers[ 0 ].source.remove();
        //reselect the original selection.
        for ( var i = 0; i < sel.length; i++ ) { 
            sel[ i ].selected = true;
        }
        return "composition";
    }
    else { 
        // alert( "project" );
        return "project";

    }

}
Alan Eddie
_______________________
www.alaneddie.com
3d Animation and VFX
RTE
Dublin
Post Reply