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

Help getting variable value from with action manager code

Engaged ,
Nov 10, 2022 Nov 10, 2022

As far as I can see these two lines of AM code sets idUsrM to true

var idUsrM = charIDToTypeID( "UsrM" );
desc43.putBoolean( idUsrM, true );

 

My question is how to I get the value of a variable in AM? 

 

In a better context this code will enable a layer mask.

 var idsetd = charIDToTypeID( "setd" );
 var desc42 = new ActionDescriptor();
 var idnull = charIDToTypeID( "null" );
 var ref12 = new ActionReference();
 var idLyr = charIDToTypeID( "Lyr " );
 var idOrdn = charIDToTypeID( "Ordn" );
 var idTrgt = charIDToTypeID( "Trgt" );
 ref12.putEnumerated( idLyr, idOrdn, idTrgt );
 desc42.putReference( idnull, ref12 );
 var idT = charIDToTypeID( "T   " );
 var desc43 = new ActionDescriptor();
 var idUsrM = charIDToTypeID( "UsrM" );
 desc43.putBoolean( idUsrM, true ); // set to true here
 var idLyr = charIDToTypeID( "Lyr " );
 desc42.putObject( idT, idLyr, desc43 );
 executeAction( idsetd, desc42, DialogModes.NO );

I want to set a variable to the opposite. ie switching it off when on and visa versa.

var layerMaskState = !layerMaskCurrentState;

 

Hopefully, that's reasonabaly clear. If not just say so. 

 

TOPICS
Actions and scripting
638
Translate
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 1 Correct answer

Guide , Nov 10, 2022 Nov 10, 2022

Let me help a little with the ActionManager code 🙂

 

In fact, in Photoshop, in order to explore the properties of ActionManager objects, it is not necessary to loop through all of their keys. There is a handy convertJSONdescriptor function. As the name suggests, it takes an ActionDescriptor and converts it to a JSON string representation. Previously, its description could be found in the ccx-start.jsx file in the Required\CEP\extensions directory:

 

// Automatically convert to Action JSON, the
...
Translate
Adobe
Guide ,
Nov 10, 2022 Nov 10, 2022

Of course, I can give you the code, but I advise you to read this topic and first try to do it yourself: Action Manager Scripting 

Translate
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
Engaged ,
Nov 10, 2022 Nov 10, 2022

I have read that post. - It stops just when it was getting good 😉

Also some of us need to learn with examples.

Translate
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
Engaged ,
Nov 10, 2022 Nov 10, 2022

One way of toggling the layer mask without Action Manager code is to write a state to a text file:

Not elegant, but it works. And you don't even need to know what state it was in!

// Switch off any dialog boxes
displayDialogs = DialogModes.ERROR; // OFF

var f = "C:\\temp\\layer_mask_state.txt"; // layer mask file

var layerMaskState = read_it(f);

// toggle it!
if (layerMaskState != undefined)
{
  layerMaskState = !layerMaskState;
}
else 
{
  layerMaskState = true;
}

layer_mask(layerMaskState);

// write_it
write_it(layerMaskState, f);

// Switch off any dialog boxes
displayDialogs = DialogModes.ALL; // OFF

function layer_mask(bool)
{
  var idsetd = charIDToTypeID( "setd" );
  var desc22 = new ActionDescriptor();
  var idnull = charIDToTypeID( "null" );
  var ref5 = new ActionReference();
  var idLyr = charIDToTypeID( "Lyr " );
  var idOrdn = charIDToTypeID( "Ordn" );
  var idTrgt = charIDToTypeID( "Trgt" );
  ref5.putEnumerated( idLyr, idOrdn, idTrgt );
  desc22.putReference( idnull, ref5 );
  var idT = charIDToTypeID( "T   " );
  var desc23 = new ActionDescriptor();
  var idUsrM = charIDToTypeID( "UsrM" );
  desc23.putBoolean( idUsrM, bool ); // set here
  var idLyr = charIDToTypeID( "Lyr " );
  desc22.putObject( idT, idLyr, desc23 );
  executeAction( idsetd, desc22, DialogModes.NO );
}

function write_it(astring, afilename)
{
  var exportFile = new File(afilename);
  exportFile.open("w"); // write destroys
  exportFile.writeln(astring);
  exportFile.close();
}


function read_it(afilepath)
{
  var theFile = new File(afilepath);

  // read in file 
  var words = []; // text array
  var textFile = new File(theFile);
  textFile.open('r');

  while(!textFile.eof)
  {
    var line = textFile.readln();
    if (line != null && line.length >0)
    {
      words.push(line); // array
    }
  }
  textFile.close();

  if (words[0] == "true") return true;
  if (words[0] == "false") return false;
  return undefined;
}

 

Translate
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 ,
Nov 10, 2022 Nov 10, 2022

Let me help a little with the ActionManager code 🙂

 

In fact, in Photoshop, in order to explore the properties of ActionManager objects, it is not necessary to loop through all of their keys. There is a handy convertJSONdescriptor function. As the name suggests, it takes an ActionDescriptor and converts it to a JSON string representation. Previously, its description could be found in the ccx-start.jsx file in the Required\CEP\extensions directory:

 

// Automatically convert to Action JSON, the JSON representation of
// an ActionDescriptor. It is easiest to do this here while we know
// that we still have an object (not a list, string, etc).
if (appDesc && appDesc.hasKey(propertyKey)) {
    var convertDesc = new ActionDescriptor();
    convertDesc.putObject(sTID('object'), sTID('object'), appDesc);
    var jsonDesc = executeAction(sTID('convertJSONdescriptor'), convertDesc, DialogModes.NO);
    return jsonDesc.getString(sTID('json'));
}

 

The most important thing to see here is to create a new ActionDescriptor, put the object to be converted into it (be sure to indicate that this is an "object" in the first argument of the .putObject() function, the class of the object (second argument) does not play a role - it can be any), execute the function, store the result in a variable and extract the "json" string key from it.

Ok, let's try.

To begin with, let's prepare a document with which we will work: create a new file, a new layer, create a mask on it and turn it off.

2022-11-10_22-43-18.pngexpand image

Our function, as usual, begins with an ActionReference (a description of the path to the object we want to get). Since we are talking about a layer mask, then, most likely, the property we need will be contained in its properties, so we will write the path to the active layer:

 

s2t = stringIDToTypeID;
var r = new ActionReference();
r.putEnumerated(s2t('layer'), s2t('ordinal'), s2t('targetEnum'));

 

As we know, executeActionGet(r) as a result should return the ActionDescriptor() object by the specified path.

Next, we build on the example from ccx-start.jsx and add a function to convert ActionDescriptor to json (for convenience, we output information to the console):

 

s2t = stringIDToTypeID;
var r = new ActionReference();
r.putEnumerated(s2t('layer'), s2t('ordinal'), s2t('targetEnum'));
var d = new ActionDescriptor();
d.putObject(s2t('object'), s2t('layerInfo'), executeActionGet(r));
$.writeln(executeAction(s2t('convertJSONdescriptor'), d).getString(s2t('json')));

 

Result:

2022-11-10_22-43-58.pngexpand image

It works, but the json output goes on one line without formatting. We copy it and go to any online json beautifier, format our code and start looking for everything related to masks:

 

 "hasFilterMask": false,
 "hasUserMask": true,
 "hasVectorMask": false,
 "userMaskDensity": 255,
 "userMaskEnabled": false,
 "userMaskFeather": 0,
 "userMaskLinked": true,
 "vectorMaskDensity": 255,
 "vectorMaskEmpty": true,
 "vectorMaskFeather": 0,

 

Obviously, we need the "userMaskEnabled" property. Let's do a simple test: turn on the layer mask, get the ActionDescriptor's content again, and make sure "userMaskEnabled" has changed to "true". Good. And what happens if the layer has no mask at all - delete the layer mask and get the ActionDescriptor again. We see that the "userMaskEnabled" property has disappeared from the layer altogether, that is, if we try to get it for a layer without a mask, we will get an error. On the one hand, there is a try...catch, on the other hand, we can notice that when the mask was removed, another "hasUserMask" property changed its value from "true" to "false", but we will do it a little differently: we use the .hasKey() ActionDescriptor method to check if the property exists.

So, we know which property we need to get, so we can specify our code. Instead of getting the full layer object, let's specify that we only need one property:

 

s2t = stringIDToTypeID;
var r = new ActionReference();
r.putProperty(s2t('property'), s2t('userMaskEnabled'));
r.putEnumerated(s2t('layer'), s2t('ordinal'), s2t('targetEnum'));

 

Make sure that the object that executeActionGet returns contains this key (which means the layer has a mask):

 

var d = executeActionGet(r);
if (d.hasKey(s2t('userMaskEnabled'))) { }

 

and now finsh our code:

 

s2t = stringIDToTypeID;
var r = new ActionReference();
r.putProperty(s2t('property'), s2t('userMaskEnabled'));
r.putEnumerated(s2t('layer'), s2t('ordinal'), s2t('targetEnum'));
var d = executeActionGet(r);
if (d.hasKey(s2t('userMaskEnabled'))) { $.writeln('User mask enabled: ' + d.getBoolean(s2t('userMaskEnabled'))) }
else { $.writeln('Layer has no mask') }

 

 

 

Translate
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
Engaged ,
Nov 11, 2022 Nov 11, 2022

Following your wonderful explanation, Sadly just 

var s2t = stringIDToTypeID;
var r = new ActionReference();
r.putEnumerated(s2t('layer'), s2t('ordinal'), s2t('targetEnum'));
var d = new ActionDescriptor();
var j = executeAction(s2t('convertJSONdescriptor'), d).getString(s2t('json'))
alert(j);

results in the existential error:

Error 8500: The requested property does not exist.

- Yes I realise teh code is not identical -I'm doing an alert,  not writing a line.

 

Translate
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 ,
Nov 11, 2022 Nov 11, 2022

You've created a new ActionDescriptor, but you haven't placed an object containing the result of executeActionGet() into it. Look at my example a little more closely.

Translate
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
Engaged ,
Nov 12, 2022 Nov 12, 2022
LATEST

I sees wheres I gone wrong! 😉 

All good now. Thank you.

 

 

Translate
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