... I think this can be done using scripting. One day when I learn scripting life will be grand
By @Bruce!
If only things were that simple!
It's a pet hate of mine that one feature is offered, such as "Collapse all groups", however the opposite and complimentary commands are not offered! There should be "Expand all groups" and "Collapse selected group" and "Expand selected group" for use with Actions and scripting, which can't be recorded via the GUI.
https://gist.github.com/MarshySwamp/a39e3e1efee41174b3b92ee68c40fcd8
// Collapse ALL layer groups/sets
app.runMenuItem(stringIDToTypeID('collapseAllGroupsEvent'));
// Expand ALL layer groups/sets
openAllLayerSets(app.activeDocument);
function openAllLayerSets(parent) {
// https://forums.adobe.com/message/5764024#5764024
for (var setIndex = 0; setIndex < parent.layerSets.length; setIndex++) {
app.activeDocument.activeLayer = parent.layerSets[setIndex].layers[0];
openAllLayerSets(parent.layerSets[setIndex]);
}
}
// Expand active layer set
if (app.activeDocument.activeLayer.typename == 'LayerSet' && app.activeDocument.activeLayer.layers.length > 0) {
app.activeDocument.activeLayer = app.activeDocument.activeLayer.layers[0];
}
To collapse only the active layer group would seem easy, but it's not, back in 2022 this is the best that I came up with, however, it still wasn't perfect. It's a hack, and there were unexpected consequences which required further hacks etc:
/*
Collapse Active Group.jsx
Modified by Stephen Marsh, 17th August 2022
https://gist.github.com/MarshySwamp/a39e3e1efee41174b3b92ee68c40fcd8
https://community.adobe.com/t5/photoshop-ecosystem-discussions/collapse-single-group-of-layers/m-p/13132297
Based on:
https://community.adobe.com/t5/photoshop-ecosystem/expand-collapse-a-group-via-javascript/m-p/7286298
By Vova_p, 16th February 2016
*** KNOWN LIMITATIONS & GOTCHAS ***
This script is a hack to overcome a shortcoming of the original implementation of layer groups/sets:
+ Layers clipped to the group will lose their clipping group property
+ Default layer names such as "Layer 6" may be auto-renamed by Photoshop to "Layer 10" etc.
*/
#target photoshop
if (app.documents.length > 0) {
function main() {
if (activeDocument.activeLayer.typename === "LayerSet") {
// Set the original document
var origDoc = app.activeDocument;
// Doc name variable
var origDocName = activeDocument.name;
// Store the name of the group
var groupname = activeDocument.activeLayer.name;
// Copy the active layer properties to a layer style (opacity, fill, blend mode, blend-if etc)
var idcopyEffects = stringIDToTypeID("copyEffects");
executeAction(idcopyEffects, undefined, DialogModes.NO);
// Toggle the active layer visibility
toggleLayerVisibility(true);
// Create the temp doc from active layer group
newDocFromLayer("_tempDoc");
// Set the "destination" group variable
var destinationGroup = activeDocument.activeLayer.name;
// Dupe the set into a temp group
activeDocument.activeLayer.duplicate();
// Set the duped "source" group variable
var sourceGroup = activeDocument.layers[0].name;
// Ungroup the group to select all the child elements
unGroup();
// Group the selected layers to collapse the group
groupSelectedLayers();
// Recall the original group name
activeDocument.activeLayer.name = groupname;
// Copy the layer mask with all properties from the temp group
copyLayerMask();
// Restore the layer style to the new collapsed group
pasteEffects(true);
// Select and remove the temp group
activeDocument.activeLayer = activeDocument.layers[0];
activeDocument.activeLayer.remove();
// Dupe the group back to the original doc
dupeLayer();
// Close the temp doc
activeDocument.close(SaveOptions.DONOTSAVECHANGES);
// Return to the original document
app.activeDocument = origDoc;
// Select the visible backward layer
selectForwardORBackwardLayer(false, "backwardEnum");
// Delete the original expanded group
removeGroup();
// Select the visible forward layer
selectForwardORBackwardLayer(false, "forwardEnum");
// Toggle the original active layer visibility
toggleLayerVisibility(true);
} else {
alert("Only layer groups can be collapsed!");
}
/***** Functions *****/
function dupeLayer() {
function s2t(s) {
return app.stringIDToTypeID(s);
}
var descriptor = new ActionDescriptor();
var list = new ActionList();
var reference = new ActionReference();
var reference2 = new ActionReference();
reference.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
descriptor.putReference(s2t("null"), reference);
reference2.putName(s2t("document"), origDocName);
descriptor.putReference(s2t("to"), reference2);
descriptor.putInteger(s2t("version"), 5);
list.putInteger(0);
descriptor.putList(s2t("ID"), list);
executeAction(s2t("duplicate"), descriptor, DialogModes.NO);
}
function toggleLayerVisibility(toggleOptionsPalette) {
function s2t(s) {
return app.stringIDToTypeID(s);
}
var descriptor = new ActionDescriptor();
var list = new ActionList();
var reference = new ActionReference();
reference.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
list.putReference(reference);
descriptor.putList(s2t("null"), list);
descriptor.putBoolean(s2t("toggleOptionsPalette"), toggleOptionsPalette);
executeAction(s2t("show"), descriptor, DialogModes.NO);
}
function newDocFromLayer(docName) {
function s2t(s) {
return app.stringIDToTypeID(s);
}
var descriptor = new ActionDescriptor();
var reference = new ActionReference();
var reference2 = new ActionReference();
reference.putClass(s2t("document"));
descriptor.putReference(s2t("null"), reference);
descriptor.putString(s2t("name"), docName);
reference2.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
descriptor.putReference(s2t("using"), reference2);
descriptor.putInteger(s2t("version"), 0);
executeAction(s2t("make"), descriptor, DialogModes.NO);
}
function unGroup() {
function c2t(s) {
return app.charIDToTypeID(s);
}
var s2t = function (s) {
return app.stringIDToTypeID(s);
};
var descriptor = new ActionDescriptor();
var reference = new ActionReference();
reference.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
descriptor.putReference(c2t("null"), reference);
executeAction(s2t("ungroupLayersEvent"), descriptor, DialogModes.NO);
}
function groupSelectedLayers() {
function c2t(s) {
return app.charIDToTypeID(s);
}
var s2t = function (s) {
return app.stringIDToTypeID(s);
};
var descriptor = new ActionDescriptor();
var reference = new ActionReference();
var reference2 = new ActionReference();
reference.putClass(s2t("layerSection"));
descriptor.putReference(c2t("null"), reference);
reference2.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
descriptor.putReference(s2t("from"), reference2);
executeAction(s2t("make"), descriptor, DialogModes.NO);
}
function copyLayerMask() {
// Copy layer mask - preserving feather, density
function s2t(s) {
return app.stringIDToTypeID(s);
}
var descriptor = new ActionDescriptor();
var reference = new ActionReference();
var reference2 = new ActionReference();
descriptor.putClass(s2t("new"), s2t("channel"));
reference.putEnumerated(s2t("channel"), s2t("channel"), s2t("mask"));
reference.putName(s2t("layer"), destinationGroup); // Destination group name
descriptor.putReference(s2t("at"), reference);
reference2.putEnumerated(s2t("channel"), s2t("channel"), s2t("mask"));
reference2.putName(s2t("layer"), sourceGroup); // Source group name
descriptor.putReference(s2t("using"), reference2);
executeAction(s2t("make"), descriptor, DialogModes.NO);
}
function selectForwardORBackwardLayer(makeVisible, forwardORbackward) {
function s2t(s) {
return app.stringIDToTypeID(s);
}
var descriptor = new ActionDescriptor();
var list = new ActionList();
var reference = new ActionReference();
// "forwardEnum" or "backwardEnum"
reference.putEnumerated(s2t("layer"), s2t("ordinal"), s2t(forwardORbackward));
descriptor.putReference(s2t("null"), reference);
// true or false
descriptor.putBoolean(s2t("makeVisible"), makeVisible);
list.putInteger(15);
descriptor.putList(s2t("layerID"), list);
executeAction(s2t("select"), descriptor, DialogModes.NO);
}
function removeGroup() {
function s2t(s) {
return app.stringIDToTypeID(s);
}
var descriptor = new ActionDescriptor();
var reference = new ActionReference();
reference.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
descriptor.putReference(s2t("null"), reference);
executeAction(s2t("delete"), descriptor, DialogModes.NO);
}
function pasteEffects(allowPasteFXOnLayerSet) {
function s2t(s) {
return app.stringIDToTypeID(s);
}
var descriptor = new ActionDescriptor();
descriptor.putBoolean(s2t("allowPasteFXOnLayerSet"), allowPasteFXOnLayerSet);
executeAction(s2t("pasteEffects"), descriptor, DialogModes.NO);
}
}
app.activeDocument.suspendHistory("Collapse Active Group.jsx", "main()");
} else {
alert('You must have a document open!');
}
... View more