Is there a way to find the location of the actively selected layer? I'd like to get it's index number if possible. This layer might also exist in a layerset.
If I run this applescript code I get the index I need, but I'd like to find a similar way in javascript:
Code: Select alltell application "Adobe Photoshop CS"
tell document 1
current layer's index
end tell
end tell
--> I have the 4th layer down selected so it returns 4
Thanks.
Jay
index of active layer
index of active layer
There are two kinds of layer indexes. The DOM index (which indexes you into a collection of layers) has no API support. You have to write your own function for that. Some have been posted. I don't have one.
The internal index, which can be used using the ActionManager APIs, can be found with this:
Code: Select allcTID = function(s) { return app.charIDToTypeID(s); };
Stdlib = function(){};
Stdlib.hasBackground = function(doc) {
return doc.layers[doc.layers.length-1].isBackgroundLayer;
}
Stdlib.getActiveLayerIndex = function(doc) {
var desc = Stdlib.getActiveLayerDescriptor(doc);
var idx = desc.getInteger(cTID('ItmI'));
return Stdlib.hasBackground(doc) ? idx-1 : idx;
};
Stdlib.getActiveLayerDescriptor = function(doc) {
var ref = new ActionReference();
ref.putEnumerated(cTID('Lyr '), cTID('Ordn'), cTID('Trgt'));
return executeActionGet(ref);
}
};
Using this index can be a great help with performance when you are dealing with documents with a large number of layers (e.g. 400).
-X
The internal index, which can be used using the ActionManager APIs, can be found with this:
Code: Select allcTID = function(s) { return app.charIDToTypeID(s); };
Stdlib = function(){};
Stdlib.hasBackground = function(doc) {
return doc.layers[doc.layers.length-1].isBackgroundLayer;
}
Stdlib.getActiveLayerIndex = function(doc) {
var desc = Stdlib.getActiveLayerDescriptor(doc);
var idx = desc.getInteger(cTID('ItmI'));
return Stdlib.hasBackground(doc) ? idx-1 : idx;
};
Stdlib.getActiveLayerDescriptor = function(doc) {
var ref = new ActionReference();
ref.putEnumerated(cTID('Lyr '), cTID('Ordn'), cTID('Trgt'));
return executeActionGet(ref);
}
};
Using this index can be a great help with performance when you are dealing with documents with a large number of layers (e.g. 400).
-X
index of active layer
Hi X,
Thanks again for taking the time to help. I'm running the code on a Mac (OS X 10.3) and can't figure out how to make your code work. If you have time can you expain a little of it?
I came up with this method that seems to do what I need, although I doubt it's very efficient:
Code: Select allvar theDoc = app.activeDocument;
var aLayer = theDoc.activeLayer;
var layerList = aLayer.parent.layers;
for (var x = 0; x < layerList.length; x++) {
if (layerList[x] == aLayer) { break; }
}
alert("Current layer index: " + x);
//If I selected the 3rd layer it returns "Current layer index: 2"
Thanks again for your help X!
Jay
Thanks again for taking the time to help. I'm running the code on a Mac (OS X 10.3) and can't figure out how to make your code work. If you have time can you expain a little of it?
I came up with this method that seems to do what I need, although I doubt it's very efficient:
Code: Select allvar theDoc = app.activeDocument;
var aLayer = theDoc.activeLayer;
var layerList = aLayer.parent.layers;
for (var x = 0; x < layerList.length; x++) {
if (layerList[x] == aLayer) { break; }
}
alert("Current layer index: " + x);
//If I selected the 3rd layer it returns "Current layer index: 2"
Thanks again for your help X!
Jay
index of active layer
xbytor wrote:The internal index, which can be used using the ActionManager APIs
Slightly off topic, but out of curiosity, is there any way to quickly and easily determine the maximum layer index (other than the obvious of catch'ing use of the index and having it fail?)
Slightly off topic, but out of curiosity, is there any way to quickly and easily determine the maximum layer index (other than the obvious of catch'ing use of the index and having it fail?)
index of active layer
This function will give the number of layer/layersets in a doc. But Photoshop assigns two index numbers to each layerset so it will be off if there are layersets in the doc.
Code: Select allfunction getNumberOfLayer(){
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var desc = executeActionGet(ref);
var numberOfLayer = desc.getInteger(charIDToTypeID("NmbL"));
return numberOfLayer;
} ;
Code: Select allfunction getNumberOfLayer(){
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var desc = executeActionGet(ref);
var numberOfLayer = desc.getInteger(charIDToTypeID("NmbL"));
return numberOfLayer;
} ;
index of active layer
Mike Hale wrote:This function will give the number of layer/layersets in a doc. But Photoshop assigns two index numbers to each layerset so it will be off if there are layersets in the doc.
Thanks for the quick reply Mike. I had looked at "NmbL" before (presumably for "Number of Layers"?) but it never was consistent, at least now I know why. Why does everything have to be so complicated? 2 index numbers per layerset? Why Adobe, why?!
Are the "duplicate" index numbers always sequential, such that you could "skip" the next one in some sort of loop?
Thanks for the quick reply Mike. I had looked at "NmbL" before (presumably for "Number of Layers"?) but it never was consistent, at least now I know why. Why does everything have to be so complicated? 2 index numbers per layerset? Why Adobe, why?!
Are the "duplicate" index numbers always sequential, such that you could "skip" the next one in some sort of loop?
index of active layer
I think the layersets have one index for the start of the set. That is the one you can use with action manager code. It has another for the end of the set. Using that index wth action manager code throws an error in most cases.
The end index will be offset from the start by the number of nested layers/layersets
The end index will be offset from the start by the number of nested layers/layersets
index of active layer
You can skip them by checking the layer's name for that index number. The end of layerset index will have the name '</Layer group>'
Code: Select allfunction getLayerDescriptor(idx) {
var ref = new ActionReference();
ref.putIndex(charIDToTypeID( "Lyr " ), idx);
return executeActionGet(ref);
}
function getLayerName(idx) {
var desc = getLayerDescriptor(idx);
return desc.getString(charIDToTypeID( "Nm " ));
}
var cnt = getNumberOfLayer()
for(i=0;i<cnt;i++){
if(getLayerName(i)!= '</Layer group>'){
$.writeln(getLayerName(i));
}
}
Code: Select allfunction getLayerDescriptor(idx) {
var ref = new ActionReference();
ref.putIndex(charIDToTypeID( "Lyr " ), idx);
return executeActionGet(ref);
}
function getLayerName(idx) {
var desc = getLayerDescriptor(idx);
return desc.getString(charIDToTypeID( "Nm " ));
}
var cnt = getNumberOfLayer()
for(i=0;i<cnt;i++){
if(getLayerName(i)!= '</Layer group>'){
$.writeln(getLayerName(i));
}
}
index of active layer
Thanks again Mike. The two index thing makes sense if PS has an end of layer set layer internally.
It seems getNumberOfLayer() is quite slow when you have even a moderately complex document (another thing I just don't get).
It seems getNumberOfLayer() is quite slow when you have even a moderately complex document (another thing I just don't get).
index of active layer
It seems getNumberOfLayer() is quite slow when you have even a moderately complex document (another thing I just don't get).
It's that bad, actually. Doing it via Layers/LayerSets would be painfully slow in a doc with a large number of layers.
Also, instead of checking the layer name for the the end-of-layerset, I am now using the layer type:
Code: Select all//
// returns one of:
// sTID('layerSectionStart') Start of a layer set
// sTID('layerSectionEnd') End of a layer set
// sTID('layerSectionConent') A content layer
//
function getLayerType(doc, idx) {
var desc = getLayerDescriptorByIndex(doc, idx);
return desc.getEnumerationValue(sTID('layerSection'));
};
It's that bad, actually. Doing it via Layers/LayerSets would be painfully slow in a doc with a large number of layers.
Also, instead of checking the layer name for the the end-of-layerset, I am now using the layer type:
Code: Select all//
// returns one of:
// sTID('layerSectionStart') Start of a layer set
// sTID('layerSectionEnd') End of a layer set
// sTID('layerSectionConent') A content layer
//
function getLayerType(doc, idx) {
var desc = getLayerDescriptorByIndex(doc, idx);
return desc.getEnumerationValue(sTID('layerSection'));
};