Copy link to clipboard
Copied
Hi all,
I need help with a script(s) I'm writing that tries to remember the layer I was just on, to later go back to it.
The idea is like this;
I run script A, it logs the layer I'm currently on; I then switch to a different layer
I run script B, it then goes to the layer script A logged.
I am thinking about using putCustomOptions, but I am a little unaware of how to retrieve the layer (and that's if I'm using it correctly at all).
Here is my scripts so far, I doubt it would be helpful but just so it gets the idea of what I'm trying to do across:
#target photoshop
s2t = stringIDToTypeID;
var doc = activeDocument;
// The layer I want to remember
var previousLayer = doc.activeLayer;
var ref = new ActionReference();
ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
var desc = executeActionGet(ref);
var settingsObj = new ActionDescriptor;
settingsObj.putObject(s2t('key1'), charIDToTypeID("Lyr "), desc);
var GUID = '2b7f8f4d-7eb9-4b03-a613-1457e5fea974';
app.putCustomOptions(GUID, settingsObj, false);
This is script A, and script B is below:
#target photoshop
s2t = stringIDToTypeID;
var doc = activeDocument;
var GUID = '2b7f8f4d-7eb9-4b03-a613-1457e5fea974'
try {settingsObj = app.getCustomOptions (GUID)} catch (e) {}
if (settingsObj != undefined) {
var myKey1 = settingsObj.getObjectValue(s2t('key1'));
}
// This supposedly should set the current layer to the layer that was "remembered"
doc.activeLayer = myKey1; // Throws an error though 😞
Also, this should be very fast, so if putCustomObject is too slow, then perhaps another idea can be suggested, but I guess I will get to that if it happens.
app.putCustomOptions is very fast since the settings file is cached and reading/writing options while running Photoshop is done from/to RAM.
DOM object and Action Manager descriptor are two different things. You cannot assign descriptor to the DOM activeDocument.activeLayer
Instead, save with putCustomOptions activeLayer.id (integer) then get it and make the layer active using 'select' action in another script (type in the search bar "select layer by id" and everything will become clear)
P.S. to
...You can store id's also in hidden BridgeTalk palette. It is how to activate one before last selected layer:
id = (aD = activeDocument).activeLayer.id; if (!(w = Window.find('palette', ' ')))
s = "(w = new Window('palette', ' ', void(0), {id: "+id+"})).show(), w.hide()",
(bt=new BridgeTalk()).target=BridgeTalk.appSpecifier, bt.body = s, bt.send() else{
wip = w.properties.id, w.properties.id = id; if (id != wip) {
sTT = stringIDToTypeID; (ref = new ActionReference())
.putIdentifier(sTT('l
...
Copy link to clipboard
Copied
app.putCustomOptions is very fast since the settings file is cached and reading/writing options while running Photoshop is done from/to RAM.
DOM object and Action Manager descriptor are two different things. You cannot assign descriptor to the DOM activeDocument.activeLayer
Instead, save with putCustomOptions activeLayer.id (integer) then get it and make the layer active using 'select' action in another script (type in the search bar "select layer by id" and everything will become clear)
P.S. to temporarily store simple values that can be converted to a string, it is easier to use $.setenv (name: string, value: string) and $.getenv (name: string)
that is, in the simplest case, your code can be reduced to this:
Script A:
$.setenv('activeLayer', activeDocument.activeLayer.id)
Script B:
( r = new ActionReference()).putIdentifier(stringIDToTypeID ("layer"), Number($.getenv('activeLayer')));
(d = new ActionDescriptor()).putReference(stringIDToTypeID("null"),r);
executeAction(stringIDToTypeID("select"), d, DialogModes.NO);
Copy link to clipboard
Copied
Thank you!- this is very helpful. (Also, this thread)
Is $.setenv and $.getenv simply faster, or is there some other reason? I tried using it below, perhaps you can critique me ^^
I also removed the "GUID" variable, instead inputting it directly, maybe it is better to keep it and instead use $.setenv?
Script A:
#target photoshop
s2t = stringIDToTypeID;
var doc = activeDocument;
var ref = new ActionReference();
$.setenv('lyrID', doc.activeLayer.id);
var settingsObj = new ActionDescriptor;
settingsObj.putInteger(s2t('key1'), $.getenv('lyrID'));
app.putCustomOptions('2b7f8f4d-7eb9-4b03-a613-1457e5fea974', settingsObj, false);
Script B:
#target photoshop
s2t = stringIDToTypeID;
var doc = activeDocument;
try {settingsObj = app.getCustomOptions ('2b7f8f4d-7eb9-4b03-a613-1457e5fea974')} catch (e) {}
if (settingsObj != undefined) {
$.setenv('lyrID', settingsObj.getInteger(s2t('key1')));
}
var ref = new ActionReference();
ref.putIdentifier(charIDToTypeID('Lyr '), $.getenv('lyrID'));
var desc = new ActionDescriptor();
desc.putReference(charIDToTypeID("null"), ref );
executeAction(charIDToTypeID("slct"), desc, DialogModes.NO );
Thank you once again, this works great 🙂
Copy link to clipboard
Copied
putCustomOptions and $.setenv are two different ways to store variables. Why are you using them at the same time? 🙂
you can use $.hiresTimer to estimate the running time of individual functions. $.setenv saves and gets single values faster, putCustomOptions works faster with complex objects with many variables of different types
Copy link to clipboard
Copied
I see, I thought the only way to save a variable across scripts was with putCustomOptions. And yes, I wasn't thinking when I had both $.setenv and putCustomOptions.
Thank you, I've learned a bit now.
Copy link to clipboard
Copied
Mixing these 2 methods into one is crazy 😄 But you did it perfectly loll
'I also removed the "GUID" variable, instead inputting it directly' - good move!
Copy link to clipboard
Copied
You can store id's also in hidden BridgeTalk palette. It is how to activate one before last selected layer:
id = (aD = activeDocument).activeLayer.id; if (!(w = Window.find('palette', ' ')))
s = "(w = new Window('palette', ' ', void(0), {id: "+id+"})).show(), w.hide()",
(bt=new BridgeTalk()).target=BridgeTalk.appSpecifier, bt.body = s, bt.send() else{
wip = w.properties.id, w.properties.id = id; if (id != wip) {
sTT = stringIDToTypeID; (ref = new ActionReference())
.putIdentifier(sTT('layer'), wip); (dsc = new ActionDescriptor())
.putReference(sTT('null'), ref), executeAction(sTT('select'), dsc)
}
}
Copy link to clipboard
Copied
Like I adviced in Wait for user actions before completing script. use one script.
Copy link to clipboard
Copied
I see; in my case, I would in my case be making a selection, perhaps it could check for that? And would I use putCustomOptions again to "remember" the layer I was just on?
It seems a bit complicated for me, but I may consider it if my current setup is too slow.
Copy link to clipboard
Copied
Generaly Custom Options are faster than Environment Variables, but not in this case. If you'd like to store many files paths to yield them back later, then you would notice the difference. Regarding doing it within one script you can try a code I shared in other post of this thread.
Copy link to clipboard
Copied
I see, that works also. I guess I will use that one since it only involves using one script. Now I have two scripts in case one fails for some reason 🙂 Thank you, I never heard of BridgeTalk.
Copy link to clipboard
Copied
activeDocument.info.instructions = activeDocument.activeLayer.id
Copy link to clipboard
Copied
In the past I used 'keywords' to store informations as this item is array-like.