Select layer above/below - even if hidden

Anyone, especially newbies, asking for help with Photoshop Scripting and Photoshop Automation - as opposed to those contributing to discussion about an aspect of Photoshop Scripting

Moderators: Kukurykus, Tom, xbytor

Nightshade

Select layer above/below - even if hidden

Post by Nightshade »

I'm using the XSHOCK scripts on keybinds to quickly select layers above or below my current layer selection (code below).
However, I do not like that these scripts skip through layers and groups that are hidden. How can I modify these scripts so that they do not ignore hidden layers and groups?

Select layer below:
Code: Select allif (app.documents.length > 0) {
   var method = charIDToTypeID("slct");
   var actDesc = new ActionDescriptor();
   var actRef = new ActionReference();   
   actRef.putEnumerated(charIDToTypeID("Lyr "),charIDToTypeID("Ordn"),charIDToTypeID("Bckw"));
   actDesc.putReference(charIDToTypeID("null"),actRef);
   actDesc.putBoolean(charIDToTypeID("MkVs"),false);
   executeAction(method,actDesc,DialogModes.NO);
}

Select layer above:
Code: Select allif (app.documents.length > 0) {
   var method = charIDToTypeID("slct");
   var actDesc = new ActionDescriptor();
   var actRef = new ActionReference();   
   actRef.putEnumerated(charIDToTypeID("Lyr "),charIDToTypeID("Ordn"),charIDToTypeID("Frwr"));
   actDesc.putReference(charIDToTypeID("null"),actRef);
   actDesc.putBoolean(charIDToTypeID("MkVs"),false);
   executeAction(method,actDesc,DialogModes.NO);
}

pfaffenbichler

Select layer above/below - even if hidden

Post by pfaffenbichler »

Does this work for you?
Code: Select all// select next layer below;
// thanks to mike hale and paul mr;
// 2014, use it at your own risk;
#target photoshop
if (app.documents.length > 0) {
var myDocument = app.activeDocument;
main ();
};
////////////////////////////////////
function main () {
var theLayers = getSelectedLayersIdx();
// get number of layers;
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var applicationDesc = executeActionGet(ref);
var theTop = applicationDesc.getInteger(stringIDToTypeID("numberOfLayers"));
// select lower layer;
var theNumber = theLayers[0]-1;
if (theNumber == 0) {theNumber = theTop};
try {selectLayerByIndex(theNumber, false)}
catch (e) {};
};
// function to get selected layers by paul mr;
function GetSelectedLayers() {
var A=[];
    var desc11 = new ActionDescriptor();
        var ref9 = new ActionReference();
        ref9.putClass( stringIDToTypeID('layerSection') );
    desc11.putReference( charIDToTypeID('null'), ref9 );
        var ref10 = new ActionReference();
        ref10.putEnumerated( charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') );
    desc11.putReference( charIDToTypeID('From'), ref10 );
    executeAction( charIDToTypeID('Mk  '), desc11, DialogModes.NO );
var gL = activeDocument.activeLayer.layers;
for(var i=0;i<gL.length;i++){
A.push(gL);
}
executeAction( charIDToTypeID('undo'), undefined, DialogModes.NO );
return A;
};
// by mike hale, via paul riggott;
// http://forums.adobe.com/message/1944754#1944754
function selectLayerByIndex(index,add){
add = undefined ? add = false:add
var ref = new ActionReference();
    ref.putIndex(charIDToTypeID("Lyr "), index);
    var desc = new ActionDescriptor();
    desc.putReference(charIDToTypeID("null"), ref );
       if(add) desc.putEnumerated( stringIDToTypeID( "selectionModifier" ), stringIDToTypeID( "selectionModifierType" ), stringIDToTypeID( "addToSelection" ) );
      desc.putBoolean( charIDToTypeID( "MkVs" ), false );
   try{
    executeAction(charIDToTypeID("slct"), desc, DialogModes.NO );
}catch(e){
alert(e.message);
}
};
////// by paul mr;
function getSelectedLayersIdx(){
      var selectedLayers = new Array;
      var ref = new ActionReference();
      ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
      var desc = executeActionGet(ref);
      if( desc.hasKey( stringIDToTypeID( 'targetLayers' ) ) ){
         desc = desc.getList( stringIDToTypeID( 'targetLayers' ));
          var c = desc.count
          var selectedLayers = new Array();
          for(var i=0;i<c;i++){
            try{
               activeDocument.backgroundLayer;
               selectedLayers.push(  desc.getReference( i ).getIndex() );
            }catch(e){
               selectedLayers.push(  desc.getReference( i ).getIndex()+1 );
            }
          }
       }else{
         var ref = new ActionReference();
         ref.putProperty( charIDToTypeID("Prpr") , charIDToTypeID( "ItmI" ));
         ref.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
         try{
            activeDocument.backgroundLayer;
            selectedLayers.push( executeActionGet(ref).getInteger(charIDToTypeID( "ItmI" ))-1);
         }catch(e){
            selectedLayers.push( executeActionGet(ref).getInteger(charIDToTypeID( "ItmI" )));
         }
      }
      return selectedLayers;
};

Nightshade

Select layer above/below - even if hidden

Post by Nightshade »

Sure it does!
It's an awful lot of code though - almost 5 times as much just to get hidden layers. There must be another way than that :/

Anyway, I'm new to scripting in Photoshop. So some things make sense to me, others are just plain weird. Below is the original script again with comments (me trying to dissect it and understand what is actually happening here):

Code: Select all// If we have a document open
if (app.documents.length > 0) {
   var method = charIDToTypeID("slct"); // Converts the 4-char ID for "select" to a runtime ID. Stored into the variable "method"
   var actDesc = new ActionDescriptor(); // New action descriptor, stored in the variable "actDesc"
   var actRef = new ActionReference();   // New action reference, stored in the variable "actRef"
   actRef.putEnumerated(charIDToTypeID("Lyr "),charIDToTypeID("Ordn"),charIDToTypeID("Bckw")); //  Puts the enumeration type (Ordinance) and ID (backwardsEnum) into a reference (actRef) along with
   // the desired class (Layer) for this reference. Basicly: Layer, Order, Backwards is added to the action reference. Can anyone explain this whole thing about references in better detail?   
   actDesc.putReference(charIDToTypeID("null"),actRef); // Sets the actRef value to null for the action descriptor. But why do we need a null-value reference for the action descriptor? Whats the reason?
   actDesc.putBoolean(charIDToTypeID("MkVs"),false); // Sets makeVisible to false for the action descriptor. Why is this even necessary? Setting it to true changes nothing, and if I comment
   // this line out the script still runs just fine. Whats the deal?
   executeAction(method,actDesc,DialogModes.NO); // Executes "Select", with the action descriptor and with no dialogs. The action descriptor is a pointer to what objects the command should target?
}

I've tossed in some questions there in the comments. Feel free to answer any of them.

c.buliarca

Select layer above/below - even if hidden

Post by c.buliarca »

Hello, I've tried to go further with selecting the next layer in this pack of scripts :
http://www.buliarca.net63.net/counter/c ... =BCM_Tools

I think I solved the problem when the next layer is a layer set, but the code got a lot more complicated, because I had to check if the layer set is closed or not....

pfaffenbichler

Select layer above/below - even if hidden

Post by pfaffenbichler »

I think I solved the problem when the next layer is a layer set
Ah, I hadn’t tested with LayerSet it seems, so I missed that issue.

skrippy
Posts: 14
Joined: Sun Nov 27, 2016 5:34 am
Location: EU

Re: Select layer above/below - even if hidden

Post by skrippy »

I was looking for this too and tested the code in the second post.

This seems not to be working anymore in PS CC 2018. it's not doing anything.