Setting minimum brush opacity

Hello.

Does anybody know the code to set the minimum brush opacity. I was able to get the “get” code from Alchemist, but can’t figure out how to convert it to a “set” code.

Here’s the “get” code …

const batchPlay = require("photoshop").action.batchPlay;
const result = await batchPlay(
[
   {
      "_obj": "get",
      "_target": [
         {
            "_property": "currentToolOptions"
         },
         {
            "_ref": "application",
            "_enum": "ordinal",
            "_value": "targetEnum"
         }
      ],
      "_options": {
         "dialogOptions": "dontDisplay"
      }
   }
],{
   "synchronousExecution": false,
   "modalBehavior": "fail"
});
const pinned = result[0].currentToolOptions.$opVr.minimum;

Anybody? Maybe @kerrishotts ?

I so feel you :slight_smile:
We really need the docs for all these _obj, _target._ref, _target._property and so on…
Currently BatchPlay is a guessing game a lot of the time

1 Like

I figured it out…

const toolOpt: PaintBrushToolOptionsDescriptor = getAppProperty('currentToolOptions') as PaintBrushToolOptionsDescriptor
  toolOpt.$opVr.minimum._value = 50
  const desc = {
    _obj: 'set',
    _target: {
      _ref: [{ _ref: 'paintbrushTool'}],
    },
    to: toolOpt
  }

  photoshop.action.batchPlay([desc], {})

3 Notes:

  • You can ignore the types if you’re not using typescript, although I highly recommend it to know what’s going on inside the descriptors.
  • For a different tool type, you might need to change the class reference (paintbrushTool). Might be possible to dynamically read that, too.
  • If no opacity control is selected, you’ll have to set one first, too:
    toolOpt.$opVr.$bVTy = 1 (0: off, 1: fade, 2: pen pressure, etc.)
2 Likes

I tried to set it up some time ago on PHP Storm, but didn’t succeed. Maybe I’ll try again one day :thinking:

Thanks for the tsuggestion. However I get an “Missing initializer in const declaration” error in the const definition line. And as I can’t find a place to look that up, could you please enlighten me a bit more. I can’t even find anything about “getAppProperty”.

Where did you get those information from? Even Google delivers no result when I search for “PaintBrushToolOptionsDescriptor”.

getAppProperty is your initial getter code without the last part of .$opVr.minimum

const pinned = result[0].currentToolOptions;

Then first line basically becomes this:

const toolOpt = pinned;

Everything else should be good I think.

1 Like

So “getAppProperty” is a function that I have to declare myself?

At least that’s what I did in my plugin following Simons advice in the other topic :slight_smile:

@Karmalakas is right :slight_smile: The code I post isn’t always for direct copy/paste. I try to show the relevant parts to understand the concept. So sometimes it might include some getters or helpers, which aren’t directly part of the solution or can be easily replicated. As @Karmalakas pointed out, you already had a function to get the app property, so I just left that in there. Just in case, I’ll post it here, too:

function getAppProperty<T extends keyof ApplicationDescriptor>(_property: T): ApplicationDescriptor[T] {
  return photoshop.action.batchPlay([
    {
      _obj: 'get',
      _target: [{ _property}, { _ref: 'application', _enum: 'ordinal', _value: 'targetEnum' }],
    },
  ], { synchronousExecution: true })[0][_property]
}

(the types can be removed again, I’m just too lazy when pasting it here :sweat_smile:)

PaintBrushToolOptionsDescriptor is just the name I gave to that type, but you could also just leave it out and write
const toolOpt = getAppProperty('currentToolOptions'). It’s just helping me to not make any mistakes while navigating through those nested objects. For example if you’d forget that minimum is not a number, but a percent value, you’d get the following error:
image

1 Like

Cheers. I’ll give it a try.

And I also didn’t have any place to look that up. As @Karmalakas said, batchPlay is a guessing game with a lot of trial and error.

The syntax for setting properties is always quite similar. Something like

{
    _obj: 'set',
    _target: ...,
    to: ...
}

The tricky part is that you don’t always know what to set it to. Some setters allow you to set just a subset (for example just setting the font size of a textLayer) of the property that you want to update. But to be on the safe side, you can also just get the full property, change a value and then set the whole property.

The target also has some varying syntax… I also didn’t fully understand the pattern yet, but there are essentially two ways of targeting things.

1 Like

Hi @all.

I have tried to use the code you have provided here, but I am not clever enough :wink:

If someone would provide a complete function to set the opacity I would be deeply grateful.

After a lot of trial and error and taking bits from Alchemist and Simon’s suggestions , I got it to work. This is tricky as hell. It’s obvious that this part needs documentation in some form.

Here’s the complete code …

const batchPlay = require("photoshop").action.batchPlay;

// GET TOOL OPTIONS
async function getCurrentToolOptions () {
  const result = await batchPlay(
  [
     {
        "_obj": "get",
        "_target": [
           {
              "_property": "currentToolOptions"
           },
           {
              "_ref": "application",
              "_enum": "ordinal",
              "_value": "targetEnum"
           }
        ],
        "_options": {
           "dialogOptions": "dontDisplay"
        }
     }
  ],{
     "synchronousExecution": false
  });
  return result[0].currentToolOptions;
}

// SET TOOL OPTIONS
async function setCurrentToolOptions(currenttooloptions) {
  const result = await batchPlay(
  [
     {
        "_obj": "set",
        "_target": [
           {
             "_ref": "paintbrushTool"
           }
        ],
        "to": currenttooloptions
     }
  ],{
     "synchronousExecution": false
  });
}

async function test1() {
  let cto = await getCurrentToolOptions();
  cto.$opVr.minimum._value = 20;
  await setCurrentToolOptions(cto);
}

document.getElementById("test1").addEventListener("click", test1);

Thanks for all the help, Simon. Much appreciated.

1 Like

The next step would be to listen to the event of changing brush settings (like brush size, opacity etc.) so I can synchronize my panel with the Photoshop settings. Otherwise this would be chaos.

I tried “eventNotifier” but most brush-related events are not showing up there. What would be the proper method to achieve that?

It is still not working. if I click the button. (brush is activated) nothing happens.

I have checked. both functions are called and able to make an alert-output.
But the opacity did not change.

Any idea?

1 Like

This one changes the “Minimum Opacity”. And here it works. The value was 0 before the click.

image

Not sure if this can be related, but I can’t change the minimum value in Ps itself, so maybe that’s the case for you too @assitburn :thinking: When I change the slider, as soon as I click outside, it jumps right back to zero. Didn’t bother to figure out why to be honest :slight_smile:

1 Like

That sounds weird and might be the cause of the issue. I guess this is a case for the general Photoshop support.