• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Expand/Contract Layer Groups

Enthusiast ,
Oct 15, 2013 Oct 15, 2013

Copy link to clipboard

Copied

So I spent the evening researching a way to expand/contract a layer group.. normally we have to click on the small triangle icon that appears before the layer name in the layers panel to expand the group, and click it again to fold it all up. So far, I've found information stating that it can't be done via scripting...

I thought up one way to do it, and that would be to search a layer by name (using a different script), and make sure that the layer name being searched for is inside of a contracted group.. and when that layer name is found and selected, it will unfold the layer group and show select the layer. It's quite a runaround though. Is there a more efficient way to do it with a script?

TOPICS
Actions and scripting

Views

5.9K

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
community guidelines
Adobe
Community Expert ,
Oct 22, 2013 Oct 22, 2013

Copy link to clipboard

Copied

Using script code found here I put some together that give me the functions needed.  I tested creating actions and assigned F keys during testing for fast access.

Open Target

// The main function

//@include "LayerSetSupport.jsx"

if (activeDocument.activeLayer.typename == 'LayerSet') {app.activeDocument.suspendHistory('openGroup','openGroup(activeDocument.activeLayer)');}

Close Target

// The main function

//@include "LayerSetSupport.jsx"

if (activeDocument.activeLayer.typename == 'LayerSet') {app.activeDocument.suspendHistory('closeGroup','closeGroup(activeDocument.activeLayer)');}

Open All Layer Groups

// The main function

//@include "LayerSetSupport.jsx"

openAllLayerSets( app.activeDocument );

Close All Layer Groups

// The main function

//@include "LayerSetSupport.jsx"

app.activeDocument.suspendHistory('closeAllGroup','closeAllLayerSets( app.activeDocument )');

LaySetSupport

//For code readability

function cTID(s){return charIDToTypeID(s)}

function sTID(s){return stringIDToTypeID(s)}

// =============================

function openAllLayerSets( parent ){

    for(var setIndex=0;setIndex<parent.layerSets.length;setIndex++){

        app.activeDocument.activeLayer = parent.layerSets[setIndex].layers[0];

        openAllLayerSets( parent.layerSets[setIndex]);

    }

};

function closeAllLayerSets(ref) {

          var layers = ref.layers;

          var len = layers.length;

          for ( var i = 0; i < len; i ++) {

                    var layer = layers;

                    if (layer.typename == 'LayerSet') {closeGroup(layer); var layer = layers; closeAllLayerSets(layer);};

          }

}

function openGroup(layerSet) {

   var m_activeLayer = activeDocument.activeLayer;

   var m_Layer_Dummy01 = layerSet.artLayers.add();

   var m_Layer_Dummy02 = layerSet.artLayers.add();

   layerSet.layers[1].name = layerSet.layers[1].name;

   m_Layer_Dummy01.remove();

   m_Layer_Dummy02.remove();

   activeDocument.activeLayer = m_activeLayer;

}

function closeGroup(layerSet) {

   var m_Name = layerSet.name;

   var m_Opacity = layerSet.opacity;

   var m_BlendMode = layerSet.blendMode;

   var m_LinkedLayers = layerSet.linkedLayers;

   var m_bHasMask = hasLayerMask();

   if(m_bHasMask) loadSelectionOfMask();

   if(layerSet.layers.length <= 1) {

      addLayer();

      var m_Tmp = activeDocument.activeLayer;

      m_Tmp.name = "dummy - feel free to remove me";

      activeDocument.activeLayer = layerSet;

      ungroup();

      addToSelection("dummy - feel free to remove me");

      groupSelected(m_Name);

   } else {

      activeDocument.activeLayer = layerSet;

      ungroup();

      groupSelected(m_Name);

   }

   var m_Closed = activeDocument.activeLayer;

   m_Closed.opacity = m_Opacity;

   m_Closed.blendMode = m_BlendMode;

   for(x in m_LinkedLayers) {

      if(m_LinkedLayers.typename == "LayerSet")

         activeDocument.activeLayer.link(m_LinkedLayers);

   }

   if(m_bHasMask) maskFromSelection();

   return m_Closed;

}

function ungroup() {

   var m_Dsc01 = new ActionDescriptor();

   var m_Ref01 = new ActionReference();

   m_Ref01.putEnumerated( cTID( "Lyr " ), cTID( "Ordn" ), cTID( "Trgt" ) );

   m_Dsc01.putReference( cTID( "null" ), m_Ref01 );

   try {

      executeAction( sTID( "ungroupLayersEvent" ), m_Dsc01, DialogModes.NO );

   } catch(e) {}

}

function addLayer() {

   var m_ActiveLayer          =    activeDocument.activeLayer;

   var m_NewLayer             =    activeDocument.artLayers.add();

   m_NewLayer.move(m_ActiveLayer, ElementPlacement.PLACEBEFORE);

   return m_NewLayer;

}

function hasLayerMask() {

   var m_Ref01 = new ActionReference();

   m_Ref01.putEnumerated( sTID( "layer" ), cTID( "Ordn" ), cTID( "Trgt" ));

   var m_Dsc01= executeActionGet( m_Ref01 );

   return m_Dsc01.hasKey(cTID('Usrs'));

}

function activateLayerMask() {

   var m_Dsc01 = new ActionDescriptor();

   var m_Ref01 = new ActionReference();

   m_Ref01.putEnumerated( cTID( "Chnl" ), cTID( "Chnl" ), cTID( "Msk " ) );

   m_Dsc01.putReference( cTID( "null" ), m_Ref01 );

   try {

      executeAction( cTID( "slct" ), m_Dsc01, DialogModes.NO );

   } catch(e) {

      var m_TmpAlpha = new TemporaryAlpha();

      maskFromSelection();

      activateLayerMask();

      m_TmpAlpha.consume();

   }

}

function deleteMask(makeSelection) {

   if(makeSelection) {

      loadSelectionOfMask();

   }

   var m_Dsc01 = new ActionDescriptor();

   var m_Ref01 = new ActionReference();

   m_Ref01.putEnumerated( cTID( "Chnl" ), cTID( "Ordn" ), cTID( "Trgt" ) );

   m_Dsc01.putReference( cTID( "null" ), m_Ref01 );

   try {

      executeAction( cTID( "Dlt " ), m_Dsc01, DialogModes.NO );

   } catch(e) {}

}

function selectLayerMask() {

   var m_Dsc01 = new ActionDescriptor();

   var m_Ref01 = new ActionReference();

   m_Ref01.putEnumerated(cTID("Chnl"), cTID("Chnl"), cTID("Msk "));

   m_Dsc01.putReference(cTID("null"), m_Ref01);

   m_Dsc01.putBoolean(cTID("MkVs"), false );

   try {

      executeAction(cTID("slct"), m_Dsc01, DialogModes.NO );

   } catch(e) {}

}

function loadSelectionOfMask() {

   selectLayerMask();

   var m_Dsc01 = new ActionDescriptor();

   var m_Ref01 = new ActionReference();

   m_Ref01.putProperty( cTID( "Chnl" ), cTID( "fsel" ) );

   m_Dsc01.putReference( cTID( "null" ), m_Ref01 );

   var m_Ref02 = new ActionReference();

   m_Ref02.putEnumerated( cTID( "Chnl" ), cTID( "Ordn" ), cTID( "Trgt" ) );

   m_Dsc01.putReference( cTID( "T   " ), m_Ref02 );

   try {

      executeAction( cTID( "setd" ), m_Dsc01, DialogModes.NO );

   } catch(e) {}

}

function maskFromSelection() {

   if(!hasLayerMask()) {

      var m_Dsc01 = new ActionDescriptor();

      m_Dsc01.putClass( cTID( "Nw  " ), cTID( "Chnl" ) );

      var m_Ref01 = new ActionReference();

      m_Ref01.putEnumerated( cTID( "Chnl" ), cTID( "Chnl" ), cTID( "Msk " ) );

      m_Dsc01.putReference( cTID( "At  " ), m_Ref01 );

      m_Dsc01.putEnumerated( cTID( "Usng" ), cTID( "UsrM" ), cTID( "RvlS" ) );

      try {

         executeAction( cTID( "Mk  " ), m_Dsc01, DialogModes.NO );

      } catch(e) {

         activeDocument.selection.selectAll();

         maskFromSelection();

      }

   } else {

      if(confirm("Delete existing mask?", true, "Warning")) {

         activateLayerMask();

         deleteMask();

      }

   }

}

function groupSelected(name) {

   var m_Dsc01 = new ActionDescriptor();

   var m_Ref01 = new ActionReference();

   m_Ref01.putClass( sTID( "layerSection" ) );

   m_Dsc01.putReference(  cTID( "null" ), m_Ref01 );

   var m_Ref02 = new ActionReference();

   m_Ref02.putEnumerated( cTID( "Lyr " ), cTID( "Ordn" ), cTID( "Trgt" ) );

   m_Dsc01.putReference( cTID( "From" ), m_Ref02 );

   var m_Dsc02 = new ActionDescriptor();

   m_Dsc02.putString( cTID( "Nm  " ), name);

   m_Dsc01.putObject( cTID( "Usng" ), sTID( "layerSection" ), m_Dsc02 );

   executeAction( cTID( "Mk  " ), m_Dsc01, DialogModes.NO );

   return activeDocument.activeLayer;

}

function addToSelection(layerName) {

   var m_Dsc01 = new ActionDescriptor();

   var m_Ref01 = new ActionReference();

   m_Ref01.putName( cTID( "Lyr " ), layerName );

   m_Dsc01.putReference( cTID( "null" ), m_Ref01 );

   m_Dsc01.putEnumerated( sTID( "selectionModifier" ), sTID( "selectionModifierType" ), sTID( "addToSelection" ) );

   m_Dsc01.putBoolean( cTID( "MkVs" ), false );

   try {

      executeAction( cTID( "slct" ), m_Dsc01, DialogModes.NO );

   } catch(e) {}

}

function TemporaryAlpha() {

   activeDocument.selection.store((this.alpha = activeDocument.channels.add()));

   activeDocument.selection.deselect();

   this.consume = function() {

      activeDocument.selection.load(this.alpha);

      this.alpha.remove();

   }

}

// The main function

//openGroup(activeDocument.activeLayer);

//openAllLayerSets( app.activeDocument );

//closeGroup(activeDocument.activeLayer);

//closeAllLayerSets( app.activeDocument );

Message was edited by: JJMack

JJMack

Votes

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
community guidelines
Enthusiast ,
Oct 23, 2013 Oct 23, 2013

Copy link to clipboard

Copied

cbuliarca - works great now!! definitely a script that will stay in my collection and I'll be using it every day - the nice thing is that it has a 'search layer' function just like CS6.. (it's actually a little better than CS6 because it auto-completes your layer name for you when you start typing - very nice)

JJmack - these are perfect - the only thing with 'close target' and 'close all layer groups' is that when it closes the layer group(s), it also deletes the color coding of the layer (for example if the layer was set to blue, it resets it back to nothing when closing the group) - I always need to color code my layers or else I'd lose my mind (if I haven't already lol)

Votes

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
community guidelines
Guru ,
Oct 23, 2013 Oct 23, 2013

Copy link to clipboard

Copied

That is one reason I don't think there is a good way to close a layerSet. To be clear the code posted does not close the set. It mimics closing by making a new layerSet and moving layers.

It should be possible for the script to maintain the set's layer color by getting the current set's color so it can set the color of the new set.. But there are some settings like blend-if settings that  can't be accessed by a script so it can't copy to the new set.

Votes

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
community guidelines
Community Expert ,
Oct 23, 2013 Oct 23, 2013

Copy link to clipboard

Copied

I agree the script uses a sledge hammer and flying chips  may loose some things. Script is better then actions for actions can not open or close layer sets themselves.  You can use a script an action to open layer sets,  but Closeing a layer set is an other story.  In an action when you create a group from selected layer the layer set is created closed.  That is more or less what these script do. They save  some information about a layer set ungroup the layer set  then select all that was in the group and recreates the best it can the group.  I see problem with layer set with layer mask for example  hide all layer mask  get changed to reveal all mask and vector mask are lost.... My testing was poor in fact the close all layerset routine messes up all layerset with layer mask Layers mask are changed and if you run open all layerset and close all layersets a couple of time all layer set layer mask will be lost.

I have address thelayerset  layer mask problem some, Vector mask on layer sets are not supported and will be lost. Hide all layer mask still get invetted.  However nornal raster layter mask  on layer groups are retained.

LayerSetSupport.jsx

//For code readability

function cTID(s){return charIDToTypeID(s)}

function sTID(s){return stringIDToTypeID(s)}

// =============================

function openAllLayerSets( parent ){

    var saveActivelayer = app.activeDocument.activeLayer;

    for(var setIndex=0;setIndex<parent.layerSets.length;setIndex++){

        app.activeDocument.activeLayer = parent.layerSets[setIndex].layers[0];

        openAllLayerSets( parent.layerSets[setIndex]);

    }

    app.activeDocument.activeLayer = saveActivelayer;

};

function closeAllLayerSets(ref) {

          var layers = ref.layers;

          var len = layers.length;

          for ( var i = 0; i < len; i ++) {

                    var layer = layers;

                    if (layer.typename == 'LayerSet') {app.activeDocument.activeLayer = layer; closeGroup(layer); var layer = layers; closeAllLayerSets(layer);};

          }

}

function openGroup(layerSet) {

   var m_activeLayer = activeDocument.activeLayer;

  

   var m_Layer_Dummy01 = layerSet.artLayers.add();

   var m_Layer_Dummy02 = layerSet.artLayers.add();

   layerSet.layers[1].name = layerSet.layers[1].name;

   m_Layer_Dummy01.remove();

   m_Layer_Dummy02.remove();

  

   activeDocument.activeLayer = m_activeLayer;

}

function closeGroup(layerSet) {

   var m_Name = layerSet.name;

   var m_Opacity = layerSet.opacity;

   var m_BlendMode = layerSet.blendMode;

   var m_LinkedLayers = layerSet.linkedLayers;

  

   var m_bHasMask = hasLayerMask();

   if(m_bHasMask) loadSelectionOfMask();

   if(layerSet.layers.length <= 1) {

      addLayer();

      var m_Tmp = activeDocument.activeLayer;

      m_Tmp.name = "dummy - feel free to remove me";

      activeDocument.activeLayer = layerSet;

      ungroup();

      addToSelection("dummy - feel free to remove me");

      groupSelected(m_Name);

     

   } else {

      activeDocument.activeLayer = layerSet;

      ungroup();

      groupSelected(m_Name);

   }

   var m_Closed = activeDocument.activeLayer;

   m_Closed.opacity = m_Opacity;

   m_Closed.blendMode = m_BlendMode;

  

   for(x in m_LinkedLayers) {

      if(m_LinkedLayers.typename == "LayerSet")

         activeDocument.activeLayer.link(m_LinkedLayers);

   }

  

   if(m_bHasMask) maskFromSelection();

  

   return m_Closed;

}

function ungroup() {

   var m_Dsc01 = new ActionDescriptor();

   var m_Ref01 = new ActionReference();

   m_Ref01.putEnumerated( cTID( "Lyr " ), cTID( "Ordn" ), cTID( "Trgt" ) );

   m_Dsc01.putReference( cTID( "null" ), m_Ref01 );

  

   try {

      executeAction( sTID( "ungroupLayersEvent" ), m_Dsc01, DialogModes.NO );

   } catch(e) {}

}

function addLayer() {

   var m_ActiveLayer          =    activeDocument.activeLayer;

   var m_NewLayer             =    activeDocument.artLayers.add();

   m_NewLayer.move(m_ActiveLayer, ElementPlacement.PLACEBEFORE);

  

   return m_NewLayer;

}

function hasLayerMask() {

   var m_Ref01 = new ActionReference();

   m_Ref01.putEnumerated( sTID( "layer" ), cTID( "Ordn" ), cTID( "Trgt" ));

   var m_Dsc01= executeActionGet( m_Ref01 );

   return m_Dsc01.hasKey(cTID('Usrs'));

}

function activateLayerMask() {

   var m_Dsc01 = new ActionDescriptor();

   var m_Ref01 = new ActionReference();

   m_Ref01.putEnumerated( cTID( "Chnl" ), cTID( "Chnl" ), cTID( "Msk " ) );

   m_Dsc01.putReference( cTID( "null" ), m_Ref01 );

  

   try {

      executeAction( cTID( "slct" ), m_Dsc01, DialogModes.NO );

   } catch(e) {

      var m_TmpAlpha = new TemporaryAlpha();

     

      maskFromSelection();

      activateLayerMask();

     

      m_TmpAlpha.consume();

   }

}

function deleteMask(makeSelection) {

   if(makeSelection) {

      loadSelectionOfMask();

   }

  

   var m_Dsc01 = new ActionDescriptor();

   var m_Ref01 = new ActionReference();

   m_Ref01.putEnumerated( cTID( "Chnl" ), cTID( "Ordn" ), cTID( "Trgt" ) );

   m_Dsc01.putReference( cTID( "null" ), m_Ref01 );

  

   try {

      executeAction( cTID( "Dlt " ), m_Dsc01, DialogModes.NO );

   } catch(e) {}

}

function selectLayerMask() {

   var m_Dsc01 = new ActionDescriptor();

   var m_Ref01 = new ActionReference();

   m_Ref01.putEnumerated(cTID("Chnl"), cTID("Chnl"), cTID("Msk "));

   m_Dsc01.putReference(cTID("null"), m_Ref01);

   m_Dsc01.putBoolean(cTID("MkVs"), false );

   try {

      executeAction(cTID("slct"), m_Dsc01, DialogModes.NO );

   } catch(e) {}

}

function loadSelectionOfMask() {

   selectLayerMask();

  

   var m_Dsc01 = new ActionDescriptor();

   var m_Ref01 = new ActionReference();

   m_Ref01.putProperty( cTID( "Chnl" ), cTID( "fsel" ) );

   m_Dsc01.putReference( cTID( "null" ), m_Ref01 );

   var m_Ref02 = new ActionReference();

   m_Ref02.putEnumerated( cTID( "Chnl" ), cTID( "Ordn" ), cTID( "Trgt" ) );

   m_Dsc01.putReference( cTID( "T   " ), m_Ref02 );

  

   try {

      executeAction( cTID( "setd" ), m_Dsc01, DialogModes.NO );

   } catch(e) {}

}

function maskFromSelection() {

   if(!hasLayerMask()) {

      var m_Dsc01 = new ActionDescriptor();

      m_Dsc01.putClass( cTID( "Nw  " ), cTID( "Chnl" ) );

      var m_Ref01 = new ActionReference();

      m_Ref01.putEnumerated( cTID( "Chnl" ), cTID( "Chnl" ), cTID( "Msk " ) );

      m_Dsc01.putReference( cTID( "At  " ), m_Ref01 );

      m_Dsc01.putEnumerated( cTID( "Usng" ), cTID( "UsrM" ), cTID( "RvlS" ) );

     

      try {

         executeAction( cTID( "Mk  " ), m_Dsc01, DialogModes.NO );

      } catch(e) {

         activeDocument.selection.selectAll();

         maskFromSelection();

      }

   } else {

      if(confirm("Delete existing mask?", true, "Warning")) {

         activateLayerMask();

         deleteMask();

      }

   }

}

function groupSelected(name) {

   var m_Dsc01 = new ActionDescriptor();

   var m_Ref01 = new ActionReference();

   m_Ref01.putClass( sTID( "layerSection" ) );

   m_Dsc01.putReference(  cTID( "null" ), m_Ref01 );

   var m_Ref02 = new ActionReference();

   m_Ref02.putEnumerated( cTID( "Lyr " ), cTID( "Ordn" ), cTID( "Trgt" ) );

   m_Dsc01.putReference( cTID( "From" ), m_Ref02 );

   var m_Dsc02 = new ActionDescriptor();

   m_Dsc02.putString( cTID( "Nm  " ), name);

   m_Dsc01.putObject( cTID( "Usng" ), sTID( "layerSection" ), m_Dsc02 );

   executeAction( cTID( "Mk  " ), m_Dsc01, DialogModes.NO );

  

   return activeDocument.activeLayer;

}

function addToSelection(layerName) {

   var m_Dsc01 = new ActionDescriptor();

   var m_Ref01 = new ActionReference();

   m_Ref01.putName( cTID( "Lyr " ), layerName );

   m_Dsc01.putReference( cTID( "null" ), m_Ref01 );

   m_Dsc01.putEnumerated( sTID( "selectionModifier" ), sTID( "selectionModifierType" ), sTID( "addToSelection" ) );

   m_Dsc01.putBoolean( cTID( "MkVs" ), false );

  

   try {

      executeAction( cTID( "slct" ), m_Dsc01, DialogModes.NO );

   } catch(e) {}

}

function TemporaryAlpha() {

   activeDocument.selection.store((this.alpha = activeDocument.channels.add()));

   activeDocument.selection.deselect();

  

   this.consume = function() {

      activeDocument.selection.load(this.alpha);

      this.alpha.remove();

   }

}

// The main function

//openGroup(activeDocument.activeLayer);

//openAllLayerSets( app.activeDocument );

//closeGroup(activeDocument.activeLayer);

//closeAllLayerSets( app.activeDocument );

Message was edited by: JJMack

JJMack

Votes

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
community guidelines
Contributor ,
Oct 23, 2013 Oct 23, 2013

Copy link to clipboard

Copied

Yes that's right, the script on toggleOpen_CloseGroup is restrictive, I have this problem as well, for example the script can't see if a vector mask is enabled or linked, and as Michael said there are some functions that can't be accessed by script.

One other problem the script has is that if you have some colored layers inside your set and your set has another color when you will close the set with the script you will lose the color to your layers as well, they will change to the color of the set.

Votes

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
community guidelines
Community Expert ,
Oct 24, 2013 Oct 24, 2013

Copy link to clipboard

Copied

Yes you and I started with the script from posted on ps-scripts by TeddyBear.  He call it ridiculous but it works and is fast. It has its faults and I don't use vector mask or color coding so its OK for me.  You took it to up many notches to the height of ridiculousness.  To code that much to stimulate what can be done better by pointing the mouse cursor and clicking the left mouse button.  The good part is you learned a lot about scripting Photoshop in the process.  I learned that its not possible to write a perfect script for it, So I really don use it. Sill I learned quite a bit about the workings of Photoshop in the process.

JJMack

Votes

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
community guidelines
Contributor ,
Oct 25, 2013 Oct 25, 2013

Copy link to clipboard

Copied

Yes you are so right, I've learned a lot on doing this script, before it I didn't knew how to use AM, it's great, to bad that there is no documentation for it. All I've learned I've learned from here and ps-scripts.com. Once again thank you all for taking the time to answer the questions and more important thank you for sharing your knowledge. You are right about the script as well, so much time spent on something that can be solved by moving and clicking the mouse.... but you know at first I thought that it can be a good idea just to press a key and open the group and TeddyBear gave a great ridiculous script on doing that, now as I seen that it can't be perfect I'm not so exited anymore, but anyway I'm grateful for the fact that it opened my eyes on AM.

Votes

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
community guidelines
Community Expert ,
May 18, 2023 May 18, 2023

Copy link to clipboard

Copied

LATEST

Votes

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
community guidelines