Getting selected layer in CS4

Photoshop Script Snippets - Note: Full Scripts go in the Photoshop Scripts Forum

Moderators: Tom, Kukurykus

Mike Hale

Getting selected layer in CS4

Post by Mike Hale »

Photoshop has add a new key to the document descriptor in CS4. That key has a list of selected layer indexes.

Code: Select all   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;
   }
xbytor

Getting selected layer in CS4

Post by xbytor »

Nice find.

I've got (far less elegant) code that works for CS2 and CS3 when more than one layer is selected. For PS7 and CS, I just return the active layer, like you do for pre-CS4.

I'll update my code as soon as I can for CS4+. This is definitely going to be faster for docs with a large number of layers.

-X
Mike Hale

Getting selected layer in CS4

Post by Mike Hale »

This only works with CS4 so it's a good thing that you have a different way for us to use.

You may want to compare the code you have be testing with what is posted now. I have updated it twice as I found errors dealing with the way the AM index changes if there is a background or not.

Also here is a companion function to make layer(s) active by index.
Code: Select allfunction makeActiveByIndex( idx, visible ){
   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 );
   }   
}

Now you can do something like this to get the selected layers as layer objects.

Code: Select allvar sl = getSelectedLayersIdx();
var sLayers = new Array();
for( var i = 0; i < sl.length; i++ ){
   makeActiveByIndex( [ sl[ i ] ], false );
   sLayers.push( activeDocument.activeLayer );
}
makeActiveByIndex( sl, false );
alert( sLayers );
xbytor

Getting selected layer in CS4

Post by xbytor »

Mike Hale wrote:You may want to compare the code you have be testing with what is posted now. I have updated it twice as I found errors dealing with the way the AM index changes if there is a background or not.


I've already run across that problem:

Code: Select allStdlib.getLayerIndex = function(doc, layer) {
  var idx = Stdlib.getLayerProperty(layer, 'ItmI');
  return Stdlib.hasBackground(doc) ? idx-1 : idx;
};

It took me awhile to figure out as well. I don't know what Adobe was thinking. They treat background layers like they're magic, probably for historic reasons.

Also here is a companion function to make layer(s) active by index.


See also: Stdlib.selectLayerByIndex and Stdlib.selectLayersByIndex.

-X
Mike Hale

Getting selected layer in CS4

Post by Mike Hale »

xbytor wrote:I don't know what Adobe was thinking. They treat background layers like they're magic, probably for historic reasons.


In my test, I also found that with 'targetLayers' the indexes are correct if there is background and off by +1 if there was not. The opposite of the way the layer property works.

It is very strange not to have the property return the correct value(s). Even stranger for the indexes not be be the same as the layer property.