Copy link to clipboard
Copied
Hi all,
Is there a way to copy the list of layer comps and paste into a fresh list?
Next bigger question, can you access the Layer Comp list within a smart object, as seen in the properties panel, and copy that?
I have a script that that culls layers by name, and makes layer comps from that data. Unfortumanetly those layer comps need to be copied to the main worker, not just inside the smart object.
Thanks for any guidance.
1) What do you mean? Please post meaningful screenshots including all pertinent Panels to clarify.
2) One can assess the Layer Comps of a Smart Object, what do you mean by »copy«?
// 2023, use it at your own risk;
if (app.documents.length > 0) {
var theThings = collectSmartObjectsWithLayerComps();
alert (theThings.length+" smart object instances with layer comps\n\n"+theThings.join("\n\n"));
};
////////////////////////////////////
////// collect smart objects, probably based on code by paul
...
it's just the list. And as Steven pointed out below, they do match, under the old conditions. e.g. The smart object has 5 UI locales, EN, SP, IT, JP, FR. The layer comp reflects those. Clicking on the layer comp drives the visibility of the language. Outside the layer compes, exsists the same layer comp list, EN, SP, IT, JP, FR. clicking on the layer comp outside of the Smart Object, will also change the language. It's cool, I love it.
However the classic 5 locales are no
...
// create layer comps for layer comps in smart object;
// 2024, use it at your own risk;
if (app.documents.length > 0) {
var myDocument = activeDocument;
// remove existing layer comps;
myDocument.layerComps.removeAll();
var theSmartObject = collectSmartObjectsLayerComps ();
// process layer comps;
for (var y = 0; y < theSmartObject[2].length; y++) {
var thisOne = theSmartObject[2][y];
applyLayerCompToSmartObject (theSmartObject[1], thisOne[1]);
createLayerComp (thisOne[0]);
}
};
////////////
...
Copy link to clipboard
Copied
1) What do you mean? Please post meaningful screenshots including all pertinent Panels to clarify.
2) One can assess the Layer Comps of a Smart Object, what do you mean by »copy«?
// 2023, use it at your own risk;
if (app.documents.length > 0) {
var theThings = collectSmartObjectsWithLayerComps();
alert (theThings.length+" smart object instances with layer comps\n\n"+theThings.join("\n\n"));
};
////////////////////////////////////
////// collect smart objects, probably based on code by paul, mike or x //////
function collectSmartObjectsWithLayerComps () {
// the file;
var myDocument = app.activeDocument;
// get number of layers;
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var applicationDesc = executeActionGet(ref);
var theNumber = applicationDesc.getInteger(stringIDToTypeID("numberOfLayers"));
// process the layers;
var theLayers = new Array;
for (var m = 0; m <= theNumber; m++) {
try {
var ref = new ActionReference();
ref.putIndex( charIDToTypeID( "Lyr " ), m);
var layerDesc = executeActionGet(ref);
var layerSet = typeIDToStringID(layerDesc.getEnumerationValue(stringIDToTypeID("layerSection")));
var isBackground = layerDesc.getBoolean(stringIDToTypeID("background"));
// if not layer group collect values;
if (layerSet != "layerSectionEnd" && layerSet != "layerSectionStart" && isBackground != true) {
var theName = layerDesc.getString(stringIDToTypeID('name'));
var theID = layerDesc.getInteger(stringIDToTypeID('layerID'));
if(layerDesc.hasKey(stringIDToTypeID('smartObject'))) {
var soDesc = layerDesc.getObjectValue(stringIDToTypeID('smartObject'));
var theFileRef = soDesc.getString(stringIDToTypeID('fileReference'));
var theDocID = soDesc.getString(stringIDToTypeID('documentID'));
var x = soDesc.getList(stringIDToTypeID("compsList"));
var theCompsList = soDesc.getObjectValue(stringIDToTypeID("compsList"));
if (theCompsList.count > 2) {
var theCompsList = theCompsList.getList(stringIDToTypeID("compList"));
var theSOComps = new Array;
for (var n = 0; n < theCompsList.count; n++) {
var thisOne = theCompsList.getObjectValue(n);
var compName = thisOne.getString(stringIDToTypeID("name"));
var compID = thisOne.getInteger(stringIDToTypeID("ID"));
var theComment = thisOne.getString(stringIDToTypeID("comment"));
theSOComps.push([compName, compID, theComment]);
};
theLayers.push([theName, theID, theFileRef, theDocID, theSOComps])
};
}
};
}
catch (e) {};
};
return theLayers
};
Copy link to clipboard
Copied
»what do you mean by »copy«?« may seem like a strange question.
Let me elaborate:
What you described as »the Layer Comp list within a smart object, as seen in the properties panel, and copy that« is probably not the end-point of the intended automation process, because what good is the list in the clipboard?
How do you intend to use that list subsequently?
Copy link to clipboard
Copied
exactly correct Steven.
Just getting back to this thread. I have a functional modified script that exports layer comps to files. Great. The trick has been to drive a predefined layer comp list, inside a smart object with the same list outside of the smart object using the properties panel. Also good.
Copy link to clipboard
Copied
it's just the list. And as Steven pointed out below, they do match, under the old conditions. e.g. The smart object has 5 UI locales, EN, SP, IT, JP, FR. The layer comp reflects those. Clicking on the layer comp drives the visibility of the language. Outside the layer compes, exsists the same layer comp list, EN, SP, IT, JP, FR. clicking on the layer comp outside of the Smart Object, will also change the language. It's cool, I love it.
However the classic 5 locales are now going to be augmented. It could be 1 to 27 and in differing groupings, and different Locale Codes. I have a script that looks for specific parts of the name, and builds a layer comp for that name, i.e. 20240210_JP_tv_features.png equales a layer comp JP. Because of the random way the files will be used, I can't predetrmine a fixed layer comp list in and out of the smart object.
So copying the list. Either by selecting the smart object and go to the properties panel, you can see all the layer comps held inside. Can that list be copied, so that same list be rcreated outside in the worker. You use Parent and child, but I'm not sure that metaphor works in that the smart object is a unique file (Child?), and the worker housing it is also a unique file (Parent?.). That's one possible option. The other is to reopen the smart object and copy the layer comp names as a source and build out the same list for the target doc.
The rest is built and functional. And under the original set of locales was so fun to export.
I wish I could post screen caps, but NDA reqs don't allow. I did post something as I was fleshing this out a couple of years ago. In fact you help to crack the final nut in this worklow. c.pfaffenbichler
Copy link to clipboard
Copied
I am having problems with your description.
Please provide a mockup-file to demonstrate the current state and the intended result.
Can that list be copied, so that same list be rcreated outside in the worker.
What good would the list copied to the clipboard be?
Have you tested the code I posted?
It gives an alert of the Layer Comps of all Smart Objects (with Layer Comps) in a file, but that can naturally limited to the active Smart Object (for example) and the Array can then be processed.
Copy link to clipboard
Copied
@RoyBoySolorio Creating matching layer comps in the parent document would only seem to make sense if the child smart object contained the same named layers as the parent.
Can you post a screenshot of the parent doc's layers panel, and also a screenshot of the child smart object doc's layers panel.
Copy link to clipboard
Copied
// create layer comps for layer comps in smart object;
// 2024, use it at your own risk;
if (app.documents.length > 0) {
var myDocument = activeDocument;
// remove existing layer comps;
myDocument.layerComps.removeAll();
var theSmartObject = collectSmartObjectsLayerComps ();
// process layer comps;
for (var y = 0; y < theSmartObject[2].length; y++) {
var thisOne = theSmartObject[2][y];
applyLayerCompToSmartObject (theSmartObject[1], thisOne[1]);
createLayerComp (thisOne[0]);
}
};
////////////////////////////////////#
////// collect smart object’s layer comps, probably based on code by paul, mike or x //////
function collectSmartObjectsLayerComps () {
try {
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
//ref.putIndex( charIDToTypeID( "Lyr " ), m);
var layerDesc = executeActionGet(ref);
var layerSet = typeIDToStringID(layerDesc.getEnumerationValue(stringIDToTypeID("layerSection")));
var isBackground = layerDesc.getBoolean(stringIDToTypeID("background"));
// if not layer group collect values;
if (layerSet != "layerSectionEnd" && layerSet != "layerSectionStart" && isBackground != true) {
var theName = layerDesc.getString(stringIDToTypeID('name'));
var theID = layerDesc.getInteger(stringIDToTypeID('layerID'));
// is smart object;
if(layerDesc.hasKey(stringIDToTypeID('smartObject'))) {
// comps;
var theSO = layerDesc.getObjectValue(stringIDToTypeID("smartObject"));
var theCompsList = theSO.getObjectValue(stringIDToTypeID("compsList"));
if (theCompsList.count > 2) {
var theCompsList = theCompsList.getList(stringIDToTypeID("compList"));
var theSOComps = new Array;
for (var n = 0; n < theCompsList.count; n++) {
var thisOne = theCompsList.getObjectValue(n);
var theCompName = thisOne.getString(stringIDToTypeID("name"));
var theCompID = thisOne.getInteger(stringIDToTypeID("ID"));
var theComment = thisOne.getString(stringIDToTypeID("comment"));
theSOComps.push([theCompName, theCompID, theComment]);
};
// add to array;
return [theName, theID, theSOComps]
}
}
}
} catch (e) {};
};
////// apply layercomp to smart object //////
function applyLayerCompToSmartObject (theLayerID, theID) {
selectLayerByID(theLayerID, false);
var desc9 = new ActionDescriptor();
var ref3 = new ActionReference();
ref3.putEnumerated(charIDToTypeID( "Lyr " ), charIDToTypeID( "Ordn" ), charIDToTypeID( "Trgt" ));
desc9.putReference( charIDToTypeID( "null" ), ref3 );
desc9.putInteger( stringIDToTypeID( "compID" ), theID );
executeAction( stringIDToTypeID( "setPlacedLayerComp" ), desc9, DialogModes.NO );
};
////// based on code by mike hale and paul riggott //////
function selectLayerByID(index,add){
add = undefined ? add = false:add
var ref = new ActionReference();
ref.putIdentifier(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);
}
};
////// create layer comp //////
function createLayerComp (theName) {
// =======================================================
var desc4 = new ActionDescriptor();
var ref2 = new ActionReference();
ref2.putClass( stringIDToTypeID( "compsClass" ) );
desc4.putReference( stringIDToTypeID( "null" ), ref2 );
var desc5 = new ActionDescriptor();
desc5.putBoolean( stringIDToTypeID( "useVisibility" ), true );
desc5.putBoolean( stringIDToTypeID( "usePosition" ), true );
desc5.putBoolean( stringIDToTypeID( "useAppearance" ), true );
desc5.putBoolean( stringIDToTypeID( "useChildLayerCompState" ), true );
desc5.putString( stringIDToTypeID( "title" ), theName );
var idcompsClass = stringIDToTypeID( "compsClass" );
desc4.putObject( stringIDToTypeID( "using" ), idcompsClass, desc5 );
executeAction( stringIDToTypeID( "make" ), desc4, DialogModes.NO );
};
edited
Copy link to clipboard
Copied
Stunned and amazed c.pfaffenbichler.
That was exactly what I needed. Your screen grabs thru me off, but when I ran it, it made the list as needed, and did the syncing too. I'm updsting the actions and will beta test the new pipeline later today. Thanks again for your help on this. Maybe when complete I could send a training vid that shows the work inprogress. Of course with prereleased assets.