Highlighted

Best clean way to get number of selected layers within script.

Participant ,
May 15, 2020

Copy link to clipboard

Copied

So,

I'm looking for the best way to count the number of selected layers in a PS document.

 

I've been looking around and stumbled on this piece of code : https://graphicdesign.stackexchange.com/questions/104786/is-it-possible-to-count-the-number-of-layer...

 

It does work, but it works by creating a new group before counting the layers, then undoing it all.  This fires a "Mk " event.  And since the script has an EventListenner looking out for "Mk " events, well... I get stuck in an endless loop...

 

Isn't there a simple and effective way to count the selected layers ?  Actually... I just need to know if there's more than one selected...

 

Many thanks.

 

J.

s2t = stringIDToTypeID;
(r = new ActionReference).putProperty(s2t('property'), p = s2t('targetLayers'));
r.putEnumerated (s2t ('document'), s2t ('ordinal'), s2t ('targetEnum'));
n =  executeActionGet (r).hasKey(p) ?  executeActionGet (r).getList(p).count : 0;
alert (n)
TOPICS
Actions and scripting, How to, Mac, SDK

Views

1.7K

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more

Best clean way to get number of selected layers within script.

Participant ,
May 15, 2020

Copy link to clipboard

Copied

So,

I'm looking for the best way to count the number of selected layers in a PS document.

 

I've been looking around and stumbled on this piece of code : https://graphicdesign.stackexchange.com/questions/104786/is-it-possible-to-count-the-number-of-layer...

 

It does work, but it works by creating a new group before counting the layers, then undoing it all.  This fires a "Mk " event.  And since the script has an EventListenner looking out for "Mk " events, well... I get stuck in an endless loop...

 

Isn't there a simple and effective way to count the selected layers ?  Actually... I just need to know if there's more than one selected...

 

Many thanks.

 

J.

s2t = stringIDToTypeID;
(r = new ActionReference).putProperty(s2t('property'), p = s2t('targetLayers'));
r.putEnumerated (s2t ('document'), s2t ('ordinal'), s2t ('targetEnum'));
n =  executeActionGet (r).hasKey(p) ?  executeActionGet (r).getList(p).count : 0;
alert (n)
TOPICS
Actions and scripting, How to, Mac, SDK

Views

1.7K

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
May 15, 2020 0
Enthusiast ,
May 15, 2020

Copy link to clipboard

Copied

s2t = stringIDToTypeID;
(r = new ActionReference).putProperty(s2t('property'), p = s2t('targetLayers'));
r.putEnumerated (s2t ('document'), s2t ('ordinal'), s2t ('targetEnum'));
n =  executeActionGet (r).hasKey(p) ?  executeActionGet (r).getList(p).count : 0;
alert (n)

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
May 15, 2020 1
Adobe Community Professional ,
May 15, 2020

Copy link to clipboard

Copied

Hi, This is a nice solution. Could you please explain me (just want to learn), how exactly it is working.

Highly appreciated!

 

Thanks

Best regards

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
May 15, 2020 0
Enthusiast ,
May 15, 2020

Copy link to clipboard

Copied

This is the code for the action manager, the Photoshop subsystem. Action manager objects are stored in ActionDescriptors. The names of properties and methods are encoded by numeric keys, which we can receive and convert using functions like stringIDToTypeID.
In that case, we get access to the ActionDescriptor of the current document using the ActionReference (this is something like a link to the desired object). Using the ActionReference, we describe the property that we need. We need to get a list of selected layers - it is stored as an ActionList named 'targetLayers'. To do that we create a new ActionReference, first put the name of the property we need into it (so as not to request the entire document object):
(r = new ActionReference) .putProperty (s2t ('property'), p = s2t ('targetLayers'));
then we indicate that this property should be taken from the active document:
r.putEnumerated (s2t ('document'), s2t ('ordinal'), s2t ('targetEnum'));
Since layers may or may not be selected, then using executeActionGet and the .hasKey () function, we check if we have the property we need, if so, we write the number of elements in the list of selected layers to a variable
executeActionGet (r) .getList (p) .count , if not, then write to the variable 0.

At the same time, it is not difficult to obtain the index of each layer from the resulting list and with its help obtain all the necessary properties of each selected layer.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
May 15, 2020 1
Participant ,
May 16, 2020

Copy link to clipboard

Copied

This works perfectly.  Many thanks.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
May 16, 2020 0
Adobe Community Professional ,
May 15, 2020

Copy link to clipboard

Copied

Hi,

This is another version of the script that you have shared above.

 

var doc = app.activeDocument;
var layers = doc.layers;

function getSelectedLayers() {
    var resultLayers = new Array();
    try {
        var idGrp = stringIDToTypeID("groupLayersEvent");
        var descGrp = new ActionDescriptor();
        var refGrp = new ActionReference();
        refGrp.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
        descGrp.putReference(charIDToTypeID("null"), refGrp);
        executeAction(idGrp, descGrp, DialogModes.NO);
        for (var i = 0; i < app.activeDocument.activeLayer.layers.length; i++) {
            resultLayers.push(app.activeDocument.activeLayer.layers[i])
        }
        var id8 = charIDToTypeID("slct");
        var desc5 = new ActionDescriptor();
        var id9 = charIDToTypeID("null");
        var ref2 = new ActionReference();
        var id10 = charIDToTypeID("HstS");
        var id11 = charIDToTypeID("Ordn");
        var id12 = charIDToTypeID("Prvs");
        ref2.putEnumerated(id10, id11, id12);
        desc5.putReference(id9, ref2);
        executeAction(id8, desc5, DialogModes.NO);
        return resultLayers;
    } catch (e) {
        alert("No Layer selected or locked layer selected");
        return resultLayers;
    }
}
var selectedLayers = getSelectedLayers();
$.writeln(selectedLayers.length);

 

This will give you an array of selected layers. I hope this helps

 

Thanks

Best regards

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
May 15, 2020 0
New Here ,
Nov 07, 2020

Copy link to clipboard

Copied

This helped me a lot, thanks

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Nov 07, 2020 0