Copy link to clipboard
Copied
Hello beautiful people,
first time here, I'm working on a jsx script to duplicate layers inside an artboard, what I want to achieve now is just to duplicate a layerSet inside another layerSet, and both are in the same artboard.
I've tried the "move" method, not working, I've tried also the script from here, without artboards it's working fine, but if my layerSets are inside an artboard it doesn't move the duplicated layer, any help, please.
thanks.
Copy link to clipboard
Copied
Just to clarify, are you successfully duplicating the LayerSet using LayerSet.duplicate() method first? But then you are unable to move it into the desired LayerSet?
Do you have an example .psd file you can share?
Copy link to clipboard
Copied
Yes, the LayerSet.duplicate() is working, but neither LayerSet.duplicate(targetLayerSet, ElementPlacement.INSIDE) nor LayerSet.move() are working, here is a psd example, where you can find two artboards, the main idea is to duplicate one LayerSet from artboard1 to "TARGET" LayerSet.
thanks
Copy link to clipboard
Copied
This seems to be a case where Adobe's note about ElementPlacement values applies...
That being said, ElementPlacement.PLACEBEFORE is a valid value for moving a LayerSet, so there is a potential workaround by creating a temporary LayerSet within your TARGET LayerSet, and moving the duplicates in front of it. For example, using the naming from the .psd you provided:
var docRef = app.activeDocument;
var artboard1 = docRef.layerSets.getByName("Artboard 1");
var warningLayerSet = artboard1.layerSets.getByName("WARNING");
var targetLayerSet = docRef.layerSets.getByName("TARGET");
var tempLayerSet = targetLayerSet.layerSets.add();
tempLayerSet.name = "TEMP";
var warningLayerSetDuplicate = warningLayerSet.duplicate();
warningLayerSetDuplicate.move(tempLayerSet, ElementPlacement.PLACEBEFORE);
//tempLayerSet.remove();
This successfully duplicates the WARNING LayerSet and moves it to within the TARGET LayerSet. However, this is where things get odd...
When I delete the temporary LayerSet (via the commando on line 12 or the GUI), the "Rounded Rectangle" layer jumps out of the new WARNING LayerSet and back into Artboard 1. I haven't worked with ArtBoards before and am at a loss for why this would happen this way.
Thoughts?
Copy link to clipboard
Copied
Yes, I've tried the same approach, with a recursive function to copy the content of the layerSet even when it contains another layerSet (not the case in the example psd), but I had the same issue, a weird situation
Copy link to clipboard
Copied
It seems to be caused by the "Auto-nesting" of layers within Artboards.
By selecting the option shown in the screenshot ("Prevent auto-nesting into and out of Artboards"), I was then able to delete the TEMP LayerSet without the odd behavior described in my previous response. I was even able to duplicate the LayerSet into the desired location, eliminating a line:
var docRef = app.activeDocument;
var artboard1 = docRef.layerSets.getByName("Artboard 1");
var warningLayerSet = artboard1.layerSets.getByName("WARNING");
var targetLayerSet = docRef.layerSets.getByName("TARGET");
var tempLayerSet = targetLayerSet.layerSets.add();
tempLayerSet.name = "TEMP";
var warningLayerSetDuplicate = warningLayerSet.duplicate(tempLayerSet, ElementPlacement.PLACEBEFORE);
tempLayerSet.remove();
If toggling this feature doesn't mess up your workflow, perhaps that will do the trick!
Copy link to clipboard
Copied
Thanks mate, I'll try this approach, it will be great to toggle this feature programmatically.
Edit:
I just test it and as expected, it's perfectly working, I tried with a nested layerSet (inside Warning layerSet) and tried to apply the action on it and it did the same behavior, so I think that the idea is to disable the auth-nesting temporary for the parent when doing the duplication/moving, but I can't find how to do it 😕
Copy link to clipboard
Copied
protectArtboardAutonest(activeDocument.activeLayer.id,true);
//Layer ID, true/false
function protectArtboardAutonest(ID,Bool){
try{
var d=new ActionDescriptor();
var r=new ActionReference();
r.putIdentifier(stringIDToTypeID("layer"), ID );
d.putReference(stringIDToTypeID("null"), r);
var d1=new ActionDescriptor();
d1.putBoolean(stringIDToTypeID("protectArtboardAutonest"), Bool);
d.putObject(stringIDToTypeID("layerLocking"), stringIDToTypeID("layerLocking"), d1);
executeAction(stringIDToTypeID("applyLocking"), d, DialogModes.NO);
}catch(e){}
};
Is this what you need?
Copy link to clipboard
Copied
thanks, yes something like that, by the way, how you get this kind of code ? (talking about the actions part)
Copy link to clipboard
Copied
I can't speak for SuperMerlin​, but usually when you see code using ActionDescriptors being utilized with executeAction(), it is the result of using the ScriptingListener plugin (see here).
The plugin records actions taken within photoshop as ExtendScript code in a log file. This allows you to manually execute a particular sequence and then view the resulting code. While incredibly useful, the code it produces is not the cleanest and if the desired functionality is available via the ExtendScript API it is preferable to use those functions. The ScriptingListener code can then be used directly, used as an example but modified by hand to acheive the desired result, or processed programmatically to clean it up (using an approach such asClean SL).
Additional Adobe documentation on Action Manager can be found in the Photoshop CC Scripting Guide starting on page 73.
Hopefully this helps!
Copy link to clipboard
Copied
thanks all that I needed as information.