UXP - Get user adjustments from displayed dialog?

In extendscript it is possible to return a descriptor and get values entered by the user. For this expendscript example, there is already a solid color layer in the document. This will open up the dialog for the user to change the colors and then return the RGB values the user selected in the dialog.

Is there a way to do this in UXP?

var redCurrent=128;
var greenCurrent=128;
var blueCurrent=128;

var desc  =  changeSolidColor(redCurrent,greenCurrent,blueCurrent);

var ToDesc = desc.getObjectValue(charIDToTypeID( "T   " ));
var list = ToDesc.getList(charIDToTypeID( "Clr " ));
var levelDesc = list.getObjectValue(0);
var redNew=Math.round(levelDesc.getDouble(charIDToTypeID( "Rd  " )));
var greenNew=Math.round(levelDesc.getDouble(charIDToTypeID( "Grn " )));
var blueNew=Math.round(levelDesc.getDouble(charIDToTypeID( "Bl  " )));

function changeSolidColor(red,green,blue){
var id30 = charIDToTypeID( "setd" );
    var desc7 = new ActionDescriptor();
    var id31 = charIDToTypeID( "null" );
        var ref2 = new ActionReference();
        var id32 = stringIDToTypeID( "contentLayer" );
        var id33 = charIDToTypeID( "Ordn" );
        var id34 = charIDToTypeID( "Trgt" );
        ref2.putEnumerated( id32, id33, id34 );
    desc7.putReference( id31, ref2 );
    var id35 = charIDToTypeID( "T   " );
        var desc8 = new ActionDescriptor();
        var id36 = charIDToTypeID( "Clr " );
            var desc9 = new ActionDescriptor();
            var id37 = charIDToTypeID( "Rd  " );
            desc9.putDouble( id37, red );
            var id38 = charIDToTypeID( "Grn " );
            desc9.putDouble( id38, green );
            var id39 = charIDToTypeID( "Bl  " );
            desc9.putDouble( id39, blue );
        var id40 = charIDToTypeID( "RGBC" );
        desc8.putObject( id36, id40, desc9 );
    var id41 = stringIDToTypeID( "solidColorLayer" );
    desc7.putObject( id35, id41, desc8 );
return userRGB = executeAction( id30, desc7, DialogModes.ALL );
}
1 Like

I’d assume that you could record the equivalent uxp code for the event and just add
_options": { "dialogOptions": "display" }
to the descriptor, but I haven’t tested it. (In the CEP code that’s the DialogModes.ALL part)

Apart from that, you can also just show a color picker at any time via:

const openPicker = {
    _target: { _ref: "application" },
    _obj: "showColorPicker",
    context,
    color,
  };
  const res = await photoshop.action.batchPlay([openPicker], {})
  const rgbFloat = res[0].RGBFloatColor

But that wouldn’t give you any live updates while changing the color, as the picker isn’t connected to the change solid color event. And be aware that the resulting color has decimals for r,g and b, so you might want to round each of the components.

1 Like

Here is one possible approach with UXP

Function callColors() will:
1- open PS ColorPicker with R=G=B=128
2- get the current selected layer colors (assuming it’s a Solid Color type)
3- store new rounded R; G; B values in a userColors array…

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

async function callColors() {

  await batchPlay(
    [{
      "_obj": "set",
      "_target": [{
        "_ref": "contentLayer",
        "_enum": "ordinal",
        "_value": "targetEnum"
      }],
      "to": {
        "_obj": "solidColorLayer",
        "color": {
          "_obj": "RGBColor",
          "red": 128,
          "grain": 128,
          "blue": 128
        }
      },
      "_isCommand": true,
      "_options": {
        "dialogOptions": "display"
      }
    }], {
      "synchronousExecution": false,
      "modalBehavior": "fail"
    });

  let userColors = await testColors();

  console.log(userColors)
}

async function testColors() {
  var currentDocument = app.activeDocument
  var layers = currentDocument.activeLayers;
  var currentLayer = layers[0];

  const result = await batchPlay(
    [{
      "_obj": "get",
      "_target": [{
        "_ref": "layer",
        "_id": currentLayer._id
      }],
      "_options": {
        "dialogOptions": "dontDisplay"
      }
    }], {
      "synchronousExecution": false,
      "modalBehavior": "fail"
    });

  var userRed = Math.round(result[0].adjustment[0].color.red);
  var userGreen = Math.round(result[0].adjustment[0].color.grain);
  var userBlue = Math.round(result[0].adjustment[0].color.blue);
  var userColors = [userRed, userGreen, userBlue];
  return userColors;
}

Hope this helps !

Merry Xmas :christmas_tree: :smiley:

2 Likes

Thank you Pierre and Simon!!! Merry Christmas and Happy New Year :slight_smile:

I just did a quick test and got both to work. I actually have uses for both examples because Simon’s uses the color picker without the solid color layer and Pierre’s uses the solid color layer. So depending on the situation, both have unique use cases.

For Simon’s examples, I have to remove context and color from the descriptor for it to pull up the color picker. This is the revised code.

const openPicker = {
    _target: { _ref: "application" },
    _obj: "showColorPicker"
  };
  const res = await require("photoshop").action.batchPlay([openPicker], {});
  const rgbFloat = res[0].RGBFloatColor;
  var userColors=[Math.round(rgbFloat.red),Math.round(rgbFloat.grain),Math.round(rgbFloat.blue)];
1 Like

Oh, maybe I should have explained those 2 keys…You can add a title for the color picker (context) and the color to start with:

const openPicker = {
  _target: { _ref: "application" },
  _obj: "showColorPicker",
  context: "Some title for the color picker...",
  color: {
    _obj: 'RGBColor',
    red: 0,
    green: 0,
    blue: 0,
  },
};
const res = await photoshop.action.batchPlay([openPicker], {})
const rgbFloat = res[0].RGBFloatColor
3 Likes

Thanks. I figured there were suppose to be values there but wasn’t sure what it needed. So deleting them just went with defaults for the color and nothing for the title. The color key will be helpful for forcing the color starting point for sure.

How did you find this descriptor?
All Alchemist gives me while opening a picker, is modalStateChanged :confused:

Sorry for reviving the topic

I don’t remember, either from a thread in the prerelease forum or from some AM code.

Good it works fine !
Any suggestion how to change the ‘Color Picker’ message within the Photoshop Color Picker dialog window in this case ?

I ‘am able to change it in a basic ‘Color Picker’ dialog window, ( see code and images below) but I’m not able to change it in this particular Solid color ’ Color Picker’ dialog window

BEFORE in the basic ‘Color Picker’ dialog window,

CHANGED WITH MY CODE in the basic ‘Color Picker’ dialog window,

THIS IS THE CODE that I successfully use to change the message in the basic* ‘Color Picker’ dialog window but I’m not able to successfully replicate it in the *Solid Color ** ‘Color Picker’ dialog window)

var colorPicked = await batchPlay(
       [{
         _obj: "showColorPicker",
         context: "CHOOSE THE COLOR OF THES HADOWS",
         application: {
           _class: "null"
         },
         value: true,
         color: {
           _obj: 'RGBColor',
           red: R,
           green: G,
           blue: B,
         },
         dontRecord: true,
         forceNotify: true,
       }], {}) 

I tried to insert in the same way the 'context item in the in the *Solid Color ** ‘Color Picker’ dialog window : the dialog window is displayed and properly applied to the solid color level but the Context message is not shown in the window

  var colorPicked = await batchPlay(
    [{
      _obj: "set",
      context: "CHOOSE THE COLOR OF THE SHADOWS",
      application: {
        _class: "null"
      },
      value: true,
      _target: [{
        _ref: "contentLayer",
        _enum: "ordinal",
        _value: "targetEnum"
      }],
      to: {
        _obj: 'solidColorLayer',
        color: {
          _obj: 'RGBColor',
          red: coloriAttuali[0],
          grain: coloriAttuali[1],
          blue: coloriAttuali[2]
        }
      },
      _options: {
        isCommand: true,
        dialogOptions: "display",
        dontRecord: true,
        forceNotify: true
      }
     
    }], {});

OTHER PROBLEM

in the basic ‘Color Picker’ dialog window I’m able to catch the case when the user cancel the window (Cancel or X) ,without selcting a color (see the following code) but I’m not able to do the same in the Solid Color dialog window

WORKS for **basic 'Color Picker batchpaly, not for Solid Color batchpaly

  if ((colorPicked[0].value === false ))
   { ...... }