Welcome Dialog

Welcome to the Community!

We have a brand new look! Take a tour with us and explore the latest updates on Adobe Support Community.


Saving the layer I'm on, then referencing it later

Explorer ,
Aug 07, 2021 Aug 07, 2021

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.

TOPICS
Actions and scripting, Windows

Views

128

Likes

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

correct answers 2 Correct answers

Adobe Community Professional , Aug 07, 2021 Aug 07, 2021
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...

Likes

Translate

Translate
Adobe Community Professional , Aug 07, 2021 Aug 07, 2021
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...

Likes

Translate

Translate
Adobe Community Professional ,
Aug 07, 2021 Aug 07, 2021

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);

 

 

 

Likes

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
Explorer ,
Aug 07, 2021 Aug 07, 2021

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 🙂

Likes

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 Professional ,
Aug 07, 2021 Aug 07, 2021

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

Likes

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
Explorer ,
Aug 07, 2021 Aug 07, 2021

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.

Likes

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 Professional ,
Aug 07, 2021 Aug 07, 2021

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!

Likes

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 Professional ,
Aug 07, 2021 Aug 07, 2021

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)
	}
}

 

Likes

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 Professional ,
Aug 07, 2021 Aug 07, 2021

Copy link to clipboard

Copied

Like I adviced in Wait for user actions before completing script. use one script.

Likes

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
Explorer ,
Aug 07, 2021 Aug 07, 2021

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.

Likes

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 Professional ,
Aug 07, 2021 Aug 07, 2021

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.

Likes

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
Explorer ,
Aug 07, 2021 Aug 07, 2021

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.

Likes

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 Professional ,
Aug 07, 2021 Aug 07, 2021

Copy link to clipboard

Copied

activeDocument.info.instructions = activeDocument.activeLayer.id

Likes

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 Professional ,
Aug 07, 2021 Aug 07, 2021

Copy link to clipboard

Copied

LATEST

In the past I used 'keywords' to store informations as this item is array-like.

Likes

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