• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

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

545

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

Guide , 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

...

Votes

Translate

Translate
LEGEND , 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
...

Votes

Translate

Translate
Adobe
Guide ,
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);

 

 

 

Votes

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 🙂

Votes

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
Guide ,
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

Votes

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.

Votes

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
LEGEND ,
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!

Votes

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

 

Votes

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
LEGEND ,
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.

Votes

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.

Votes

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
LEGEND ,
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.

Votes

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.

Votes

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

Copy link to clipboard

Copied

activeDocument.info.instructions = activeDocument.activeLayer.id

Votes

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
LEGEND ,
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.

Votes

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