Multi selection Layers

Upload Photoshop Scripts, download Photoshop Scripts, Discussion and Support of Photoshop Scripts

Moderators: Tom, Kukurykus

davi.elia

Multi selection Layers

Post by davi.elia »

Hello to all!
I am new to this forum and to scripting also....

I need some help to find a way to apply some propriety (like blending mode) or apply an action, to a selection of more than one layer at same time.
I have found in this forum this code (sorry, I am trying to find the original post to refer to the author, but i can´t find at moment...):
-----------------------------------------------------------------------
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;
}
--------------------------------------------------------------------------------------------

Anyone can help me to understand how it can be done? This script have some clue to do this?
Thanks all

(Sorry for poor english...)
txuku

Multi selection Layers

Post by txuku »

Hello davi.elia

I do not think this is feasible with this function.

you can do it with a DialogBox ?
Mike Hale

Multi selection Layers

Post by Mike Hale »

davi.elia wrote:I need some help to find a way to apply some propriety (like blending mode) or apply an action, to a selection of more than one layer at same time.
For the most part Photoshop wants to work with only one layer at a time. The best you can do is let the user select multi layers then get the selected layers and make then active one at a time. Set whatever property or do whatever else is needed to the layers then make the next layer that was selected active and repeat until you have processed all the layers.

The code you posted returns an array of selected layer's action manager index(es). So you are half way there. Now you need to either make each layer active by AM index and work with the layer in the DOM or depending on what you are doing you might be able to do it without making the layer active and use Action Manager to do the work.

Action Manager can be hard to work with so here is a function that makes the layer active by AM index. It accepts a single index or an array of indexes. You can use this same function after you have processed all the layers to select them all again so the script ends with the same layer selection it started with.

Code: Select all///////////////////////////////////////////////////////////////////////////////
// Function: makeActiveByIndex
// Description: Sets the activeLayer by AM itemIndex
// Usage: var idx = makeActiveByIndex( 7, false );
// Input: Array - AM itemIndexes, Boolean - force visible
// Return: -1 if failed
// Notes:  If forceVisible = true layer.visible is set to true
//               if false, layer.visible is left unchanged.
///////////////////////////////////////////////////////////////////////////////
function makeActiveByIndex( idx, visible ){
   if( idx.constructor != Array ) idx = [ idx ];
   for( var i = 0; i < idx.length; i++ ){
      var desc = new ActionDescriptor();
      var ref = new ActionReference();
      ref.putIndex(charIDToTypeID( "Lyr " ), idx)
      desc.putReference( charIDToTypeID( "null" ), ref );
      if( i > 0 ) {
         var idselectionModifier = stringIDToTypeID( "selectionModifier" );
         var idselectionModifierType = stringIDToTypeID( "selectionModifierType" );
         var idaddToSelection = stringIDToTypeID( "addToSelection" );
         desc.putEnumerated( idselectionModifier, idselectionModifierType, idaddToSelection );
      }
      desc.putBoolean( charIDToTypeID( "MkVs" ), visible );
      executeAction( charIDToTypeID( "slct" ), desc, DialogModes.NO );
   }   
}

makeActiveByIndex( [ 3, 4 ], true )
davi.elia

Multi selection Layers

Post by davi.elia »

Thanks Mike (you must be a Scripter Master Jedi... i see you name in all over the place... kkkkk)
Thanks you to txuku!
I had understood what my script should do, by sadly I cant get it working, I am to noob to make the right syntax...
First let me see if I really understood the script sequence:
1- Use the function "getSelectedLayersIdx" to make a index of selected layers (the result will be get in this varible: "var selectedLayers = new Array" ?)
2- I saw on script that i posted a line to select the background somewhere before starting the processes, but i believe this step is not required, and also, sometimes will be no background layer...
3- Make one by one layer active (no clue where to start that and how to refer to my selected layer index...)
4- Change some propriety to the active layer using another script command, or run a action (again no clue how to do that, but I believe are more easy here, cause you just need to refer to selected layer....i think so..)
5- Make the next layer of the index active (how to use the boolean command?)
6- Run step 4 again (Change propriety or run an action)
7- Get all layers selected again to finish the script in same way that the user started.

About the layer visibility i think would not be necessary to make they visible (if have some invisible layer on selection) cause i can run an action to a invisible layer...


Sorry if I am boring you all guys, I am a old and expert DTP user, but I never wrote even a single script line (or anything close to that) in my life... I just trying to save my job here, a lot of young people have impressive skills but few desire to share the knowledge...
I am reading a lot of adobe scripting guides, but I do not have any previous programming knowledge to understand easily java script language
About the bad english I am from Brazil
Mike Hale

Multi selection Layers

Post by Mike Hale »

Well I can understand being old and wanting to keep your job.

I can go into the details if you want but you do need to check for a background layer when using Action Manager layer indexes. Unlike DOM layer indexes, AM indexes change depending on if there is a background layer or not in the document.

Maybe what will help is a script that works with multi-selected layers. The one below changes the blend mode of the selected layers. You can see how it handles changes the layers then edit it to do whatever you need done.

Code: Select allif( app.documents.length > 0 && versionCheck()  ){
   app.activeDocument.suspendHistory("Set Layer's Blend Mode", 'setBlendMode()');
}
function versionCheck()  { return app.version.match(/1[1|2]./) >= 11; };
function setBlendMode(){
   try{
      var modes = [ 'Normal','Dissolve','Darken','Multiply','Color Burn','Linear Burn','Darker Color','Lighten','Screen','Color Dodge',
                  'Linear Dodge','Lighter Color','Overlay','Soft Light','Hard Light','Vivid Light','Linear Light','Pin Light','Hard Mix',
                  'Difference','Exclusion','Hue','Saturation','Color','Luminosity' ];
      var modeIDs = [ charIDToTypeID( "Nrml" ),
                     charIDToTypeID( "Dslv" ),
                     charIDToTypeID( "Drkn" ),
                     charIDToTypeID( "Mltp" ),
                     charIDToTypeID( "CBrn" ),
                     stringIDToTypeID( "linearBurn" ),
                     stringIDToTypeID( "darkerColor" ),
                     charIDToTypeID( "Lghn" ),
                     charIDToTypeID( "Scrn" ),
                     charIDToTypeID( "CDdg" ),
                     stringIDToTypeID( "linearDodge" ),
                     stringIDToTypeID( "lighterColor" ),
                     charIDToTypeID( "Ovrl" ),
                     charIDToTypeID( "SftL" ),
                     charIDToTypeID( "HrdL" ),
                     stringIDToTypeID( "vividLight" ),
                     stringIDToTypeID( "linearLight" ),
                     stringIDToTypeID( "pinLight" ),
                     stringIDToTypeID( "hardMix" ),
                     charIDToTypeID( "Dfrn" ),
                     charIDToTypeID( "Xclu" ),
                     charIDToTypeID( "H   " ),
                     charIDToTypeID( "Strt" ),
                     charIDToTypeID( "Clr " ),
                     charIDToTypeID( "Lmns" )];
      var dlg = new Window( 'dialog', 'Layer Blend Mode' );
      dlg.ddModes= dlg.add("dropdownlist", undefined,  modes);
      dlg.ddModes.preferredSize.width = 120;
      dlg.ddModes.items[0].selected = true;
      dlg.ok = dlg.add('button',undefined,'Ok');
      dlg.cancel = dlg.add('button',undefined,'Cancel');
      var results = dlg.show();
      if( results == 1 ){
         var selectedLayers =  getSelectedLayersIdx();
         for( var l=0;l<selectedLayers.length;l++ ){
            setBlendModeByIndex( selectedLayers[l], modeIDs[dlg.ddModes.selection.index] );
         }
      }
      function getLayerNameByIndex( idx ) {
         var ref = new ActionReference();
         ref.putProperty( charIDToTypeID("Prpr") , charIDToTypeID( "Nm  " ));
         ref.putIndex( charIDToTypeID( "Lyr " ), idx );
         return executeActionGet(ref).getString(charIDToTypeID( "Nm  " ));;
      }
      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;
      }
      function setBlendModeByIndex( idx, m ) {
         var desc = new ActionDescriptor();
            var ref = new ActionReference();
            ref.putIndex( charIDToTypeID("Lyr "), idx );
         desc.putReference( charIDToTypeID( "null" ), ref );
            var modeDesc = new ActionDescriptor();
            modeDesc.putEnumerated( charIDToTypeID( "Md  " ), charIDToTypeID( "BlnM" ), m );
         desc.putObject( charIDToTypeID( "T   " ), charIDToTypeID( "Lyr " ), modeDesc );
         executeAction( charIDToTypeID( "setd" ), desc, DialogModes.NO );
      }
   }catch(e){}
};

In the case of blend modes you can change the mode without making the layer active. Depending on what you want to do you still may be able to do it the same way. But for some things you will need to make the layer active(selected/highlighted) first.
davi.elia

Multi selection Layers

Post by davi.elia »

YEAHHH!

Is EXACTLY that man, and even better... really thanks Mike, i will need some time to understand all script parts, but is there all that I need, I think will be able to modify this script to all my immediate needs.
I will post my scripts here son I get able to make it!

Thanks man, this will help me to prove that a old dog can learn new tricks!
[]
d3mac123

Multi selection Layers

Post by d3mac123 »

This script is great. However, for my project I only DO NOT need to know the layer names inside a group. For example, assuming my PSD has the following layers:
1) One (being an artlayer)
2) Two (being a layerset)
2.1) two and a half (an artlayer inside layerset Two)
3) Three (being an artlayer)

If I select all "three layers" the script returns: "one, two, two and half, three".

Is there a way to the script to return only "one, two, three"?

Thanks a lot,
Alex