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

Here is a script that switches (toggles) Sample Mode option for tools that support it

Explorer ,
Sep 23, 2021 Sep 23, 2021

Copy link to clipboard

Copied

Finally i found out how to set tool options, so here is a script that switches tools Sample Mode.
And finally we can assign a shortcut to that.
For some tools it toggles "Sample All Layers" on/off,
for others it switches Sample Mode between Current / Current & Below / All Layers / etc.
In the start of the script there is a variable called 'includeAllOptions' that controls whether to cycle all options (set to true) or only Current / Current & Below (set to false).
The script will appear in the top of the File / Scripts menu.
It was kinda hard to figure some stuff out, so i decided not to encrypt it's contents, so that anyone could investigate it.
Happy switching ☺ And if you have any comments, questions or suggestions, i'll be happy to hear them.
The script:

/*
<javascriptresource>
<name>Switch Sample Mode</name>
<enableinfo>true</enableinfo>
<category>Hirlin Scripts</category>
</javascriptresource>
// Oleksii Hirlin 2021
*/
var includeAllOptions = true; // should be either true or false
// if set to false will switch between 'Current' and 'Current &below' or just switch on / off
// if seet to true will switch between all avaliable variants as well as on / off
// getting currentToolOptions property
function checkCTOoption(charString, isIdTypeString){
    var ref = new ActionReference();
        ref.putProperty(stringIDToTypeID("property"), stringIDToTypeID("currentToolOptions"));
        ref.putEnumerated(stringIDToTypeID("application"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
    if (charString=="eyeDropperSampleSheet"){
        return executeActionGet(ref).getObjectValue(stringIDToTypeID("currentToolOptions")).getInteger(stringIDToTypeID(charString));
    }
    if (isIdTypeString==true){
        return executeActionGet(ref).getObjectValue(stringIDToTypeID("currentToolOptions")).getBoolean(stringIDToTypeID(charString));
    } else {
        return executeActionGet(ref).getObjectValue(stringIDToTypeID("currentToolOptions")).getBoolean(charIDToTypeID(charString));
    }
}
// get current tool options object
function getCTO(){
    var ref = new ActionReference();
        ref.putProperty(stringIDToTypeID("property"), stringIDToTypeID("currentToolOptions"));
        ref.putEnumerated(stringIDToTypeID("application"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
        return executeActionGet(ref).getObjectValue(stringIDToTypeID("currentToolOptions"));
}
// setting currentToolOptions with options array
function setCTO( options, isIdTypeString ){
    var desc = new ActionDescriptor();
        var ref = new ActionReference();
            ref.putClass( stringIDToTypeID( app.currentTool ) );
        desc.putReference( stringIDToTypeID( "target" ), ref );
        // getting current tool options so that they do not get reset
        var ctoObj = getCTO();
            // check if we are setting the eyedropper tool
            if ( app.currentTool=="eyedropperTool" ){
                ctoObj.putInteger( stringIDToTypeID( options[0][0] ), options[0][1] );
            } else {
                // iteration through options array and putting booleans into cto descriptor
                for (var i=0; i < options.length; i++){
                    if (isIdTypeString==true){
                        ctoObj.putBoolean( stringIDToTypeID( options[i][0] ), options[i][1] );
                    } else {
                        ctoObj.putBoolean( charIDToTypeID( options[i][0] ), options[i][1] );
                    }
                }
            }
        desc.putObject( stringIDToTypeID( "to" ), stringIDToTypeID( "currentToolOptions" ), ctoObj );
    executeAction( stringIDToTypeID( "set" ), desc, DialogModes.NO );
}
// switching currentToolOptions if it's one of the tools, ignoring otherwise
function switchCTO (){
    if ( app.currentTool=="magicStampTool" || app.currentTool=="cloneStampTool" ){
        if ( checkCTOoption("StmA")==true && checkCTOoption("StmB")==false && checkCTOoption("StmS")==false ){
            // if 'Current' set to 'Current and below'
            setCTO( [ ["StmA",true], ["StmB",true], ["StmS",true] ] );
        }
        else if ( checkCTOoption("StmA")==true && checkCTOoption("StmB")==true && checkCTOoption("StmS")==true && includeAllOptions==true ){
            // if 'current & below' set to 'all layers'
            setCTO( [ ["StmA",true], ["StmB",false], ["StmS",true] ] );
        }
        else {
            // otherwise set it to 'Current'
            setCTO( [ ["StmA",true], ["StmB",false], ["StmS",false] ] );
        }
    }
    else if ( app.currentTool=="magicLassoTool" || app.currentTool=="wetBrushTool" || app.currentTool=="recomposeSelection" ){
        if ( checkCTOoption("sampleAllLayers", true)==false ){
            setCTO( [ ["sampleAllLayers", true] ], true );
        } else {
            setCTO( [ ["sampleAllLayers", false] ], true );
        }
    }
    else if ( app.currentTool=="quickSelectTool" ){
        if ( checkCTOoption("quickSelectSampleAllLayers", true)==false ){
            setCTO( [ ["quickSelectSampleAllLayers", true] ], true );
        } else {
            setCTO( [ ["quickSelectSampleAllLayers", false] ], true );
        }
    }
    else if ( app.currentTool=="magicWandTool" ){
        if ( checkCTOoption("windowsSystem", true)==false ){
            setCTO( [ ["windowsSystem", true] ], true );
        } else {
            setCTO( [ ["windowsSystem", false] ], true );
        }
    }
    else if ( app.currentTool=="spotHealingBrushTool" ){
        if (checkCTOoption("StmS")==true){
            setCTO( [ ["StmS",false] ] );
        } else {
            setCTO( [ ["StmS",true] ] );
        }
    }
    else if ( app.currentTool=="patchSelection" && checkCTOoption("contentAware", true)==true ){
        if ( checkCTOoption("sampleAllLayers", true)==false ){
            setCTO( [ ["sampleAllLayers", true] ], true );
        } else {
            setCTO( [ ["sampleAllLayers", false] ], true );
        }
    }
    else if ( app.currentTool=="eyedropperTool" ){
        /* 
        current layer = 1
        cur & below = 3
        all layers = 0
        all layers no adj = 6
        cur & below no adj = 8
        */
        if ( checkCTOoption("eyeDropperSampleSheet")==1 ) {
            setCTO( [ ["eyeDropperSampleSheet", 3] ] );
        } else if ( checkCTOoption("eyeDropperSampleSheet")==3 ) {
            if ( includeAllOptions==true ){
                setCTO( [ ["eyeDropperSampleSheet", 0] ] );
            } else {
                setCTO( [ ["eyeDropperSampleSheet", 1] ] );
            }
        } else if ( checkCTOoption("eyeDropperSampleSheet")==0 ) {
            if ( includeAllOptions==true ){
                setCTO( [ ["eyeDropperSampleSheet", 6] ] );
            } else {
                setCTO( [ ["eyeDropperSampleSheet", 1] ] );
            }
        } else if ( checkCTOoption("eyeDropperSampleSheet")==6 ) {
            if ( includeAllOptions==true ){
                setCTO( [ ["eyeDropperSampleSheet", 8] ] );
            } else {
                setCTO( [ ["eyeDropperSampleSheet", 1] ] );
            }
        } else if ( checkCTOoption("eyeDropperSampleSheet")==8 ) {
                setCTO( [ ["eyeDropperSampleSheet", 1] ] );
        } else {
                setCTO( [ ["eyeDropperSampleSheet", 1] ] );
        }
    }
    else if ( app.currentTool=="bucketTool" || app.currentTool=="magicEraserTool"){
        if (checkCTOoption("BckS")==true){
            setCTO( [ ["BckS",false] ] );
        } else {
            setCTO( [ ["BckS",true] ] );
        }
    }
    else if ( app.currentTool=="blurTool" || app.currentTool=="sharpenTool" ){
        if (checkCTOoption("BlrS")==true){
            setCTO( [ ["BlrS",false] ] );
        } else {
            setCTO( [ ["BlrS",true] ] );
        }
    }
    else if ( app.currentTool=="smudgeTool" ){
        if ( checkCTOoption("smudgeStick", true)==false ){
            setCTO( [ ["smudgeStick", true] ], true );
        } else {
            setCTO( [ ["smudgeStick", false] ], true );
        }
    }
    else {
        // if other tools, do nothing
    }
}
switchCTO();

 

TOPICS
Actions and scripting

Views

1.5K

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

People's Champ , Sep 27, 2021 Sep 27, 2021
quote

Well, i guess, unless i get my hands on older PS version, this script is for 2021 only.
Cause that error is probably due to an inappropriate reference in the getter for that PS version.
But if anyone has the knowledge and will, they will fix it for older versions.


By @Oleqsa

 

Did you write this code yourself? Where did you get this way of getting currentToolOptions?

 

You can read here

ActionDescriptor getter: can't use Property for nested Descriptors?

 

Votes

Translate

Translate
People's Champ , Sep 27, 2021 Sep 27, 2021

Yes. In two places you need to replace

 

ref.putProperty(stringIDToTypeID("property"), stringIDToTypeID("currentToolOptions"));

 

with

 

ref.putProperty(stringIDToTypeID("property"), stringIDToTypeID("tool"));

Votes

Translate

Translate
Adobe
LEGEND ,
Sep 23, 2021 Sep 23, 2021

Copy link to clipboard

Copied

May you link us to the site where script was found at?

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 ,
Sep 23, 2021 Sep 23, 2021

Copy link to clipboard

Copied

I made the script, but i had to find some puzzles like having to reference the tool when setting the options. I would not figure that out myself for probably a decade.
But that particular thing i found on PS-SCRIPTS.COM in some discussion, probably including you 🙂
Found it - it says it was originally Tom Ruark script. The thread Set Brush Options problem
I kinda had all the pieces for some time, but didn't know how to set the tool options.
Also Yaroslav Bereza's "Alchemist" plugin helped a lot to see the differences in settings and names for the variables.
I've build my own script that logs any descriptor i reference into a txt file, but looking at it all as a tree is much more pleasing.
Here is the investigator logging script if you're interested.
I comment and uncomment parts that i need to log, and i don't feel it is complete, cause there are more stuff i can get to log, but it's a start.

 

/*
<javascriptresource>
<name>Get Descriptor</name>
<enableinfo>true</enableinfo>
<category>Hirlin Scripts</category>
</javascriptresource>
// Oleksii Hirlin 2021
*/
function getCTO(){
    var ref = new ActionReference();
        ref.putProperty(stringIDToTypeID("property"), stringIDToTypeID("currentToolOptions"));
        ref.putEnumerated(stringIDToTypeID("application"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
    return executeActionGet(ref).getObjectValue(stringIDToTypeID("currentToolOptions"));
}
function getApp(){
    var ref = new ActionReference();
        ref.putEnumerated(stringIDToTypeID("application"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
    return executeActionGet(ref);
}
function getLyr(){
    var ref = new ActionReference();
        ref.putEnumerated(stringIDToTypeID("layer"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
    return executeActionGet(ref);
}
var logg = new File("c:\\Program Files\\Adobe\\Adobe Photoshop 2021\\Presets\\Scripts\\loggCTO.txt");
// var logg = new File("c:\\Program Files\\Adobe\\Adobe Photoshop 2021\\Presets\\Scripts\\loggApp.txt");
// var logg = new File("c:\\Program Files\\Adobe\\Adobe Photoshop 2021\\Presets\\Scripts\\loggLyr.txt");
    logg.open("w");
var desc = getCTO();
// var desc = getApp();
// var desc = getLyr();
logg.write(desc.typename+"\t"+desc.count+"\n");
for (var i=0; i<desc.count; i++) {
    logg.write("• "+ i +"\t");
    //id number
    var keyIdNumber = desc.getKey(i).toString();
    while ( keyIdNumber.length<10 ) {keyIdNumber+=" ";};
    logg.write( keyIdNumber +"\t" );
    // type
    var typeOfKey = desc.getType( desc.getKey(i) ).toString().replace("DescValueType.", "").replace("TYPE","");
    var typeOfKey12 = typeOfKey;
    while ( typeOfKey12.length<12 ) {typeOfKey12+=" ";};
    logg.write( typeOfKey12 +"\t" );
    // char
    if (typeIDToCharID ( desc.getKey(i) )){
        logg.write("\""+ typeIDToCharID ( desc.getKey(i) )+"\"\t");
    } else {
        logg.write("\"\"\t\t");
    }
    // string
    logg.write("\""+ typeIDToStringID ( desc.getKey(i) ) +"\"\t");
    // data
    if ( typeOfKey == "BOOLEAN" ) { logg.write( desc.getBoolean( desc.getKey(i) )+"\t"); }
    if ( typeOfKey == "CLASS" ) { logg.write( desc.getClass( desc.getKey(i) )+"\t"); }
    if ( typeOfKey == "DOUBLE" ) { logg.write( desc.getDouble( desc.getKey(i) )+"\t"); }
    if ( typeOfKey == "INTEGER" ) { logg.write( desc.getInteger( desc.getKey(i) )+"\t"); }
    if ( typeOfKey == "LIST" ) { logg.write( desc.getList( desc.getKey(i) )+"\t"); }
    if ( typeOfKey == "REFERENCE" ) { logg.write( desc.getReference( desc.getKey(i) )+"\t"); }
    if ( typeOfKey == "STRING" ) { logg.write( desc.getString( desc.getKey(i) )+"\t"); }
    if ( typeOfKey == "LARGEINTEGER" ) { logg.write( typeIDToCharID( desc.getLargeInteger( desc.getKey(i) ) )+"\t"+ typeIDToStringID( desc.getLargeInteger( desc.getKey(i) ) )+"\t"); }
    if ( typeOfKey == "ENUMERATED" ) { logg.write( typeIDToCharID( desc.getEnumerationType( desc.getKey(i) ) )+"\t"+ typeIDToStringID( desc.getEnumerationType( desc.getKey(i) ) )+"\t"); }
    if ( typeOfKey == "ENUMERATED" ) { logg.write( typeIDToCharID( desc.getEnumerationValue( desc.getKey(i) ) )+"\t"+ typeIDToStringID( desc.getEnumerationValue( desc.getKey(i) ) )+"\t"); }
    if ( typeOfKey == "OBJECT" ) { logg.write( typeIDToCharID( desc.getObjectType( desc.getKey(i) ) )+"\t"+ typeIDToStringID( desc.getObjectType( desc.getKey(i) ) )+"\t"); }
    if ( typeOfKey == "OBJECT" ) { logg.write( desc.getObjectValue( desc.getKey(i) )+"\t"); }
    if ( typeOfKey == "UNITDOUBLE" ) { logg.write( typeIDToCharID( desc.getUnitDoubleType( desc.getKey(i) ) )+"\t"+ typeIDToStringID( desc.getUnitDoubleType( desc.getKey(i) ) )+"\t"); }
    if ( typeOfKey == "UNITDOUBLE" ) { logg.write( desc.getUnitDoubleValue( desc.getKey(i) )+"\t"); }
    // new line
    logg.write("\n");
}
logg.close();
// 

 

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
Community Expert ,
Sep 26, 2021 Sep 26, 2021

Copy link to clipboard

Copied

Cool Script! 

Some user had practically just been asking for it over on 

Shortcut für Reperatur-Pinsel (Aktuelle Ebene / Akt. u. darunter / Alle Ebenen)

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 ,
Sep 26, 2021 Sep 26, 2021

Copy link to clipboard

Copied

thanks forsharingthere link to here.
it was in german, so i didn't find it.
i had the same problem / wish as that guy, and that's i decided to make the script.
Soon i'll post a similar one that toggles "Use pressure for size" feature, that is also by default can't have a shortcut.

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
People's Champ ,
Sep 26, 2021 Sep 26, 2021

Copy link to clipboard

Copied

var ref = new ActionReference();
ref.putProperty(stringIDToTypeID("property"), stringIDToTypeID("currentToolOptions"));
ref.putEnumerated(stringIDToTypeID("application"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));

/*...*/ executeActionGet(ref) /*...*/

This code from your script causes an error in Photoshop CS6-CC2020. Also you are not using try-catch, which can lead to problems in modern Photoshop (higher than CS6)

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 ,
Sep 27, 2021 Sep 27, 2021

Copy link to clipboard

Copied

What error does it cause?
I would not postit if it caused an error  for me, and people who tested it never said about any error.
The code is streight forward, so i didn't use try/catch.
Please elaborate on the error and why lack of try/catch would cause a problem here.
Also i have no other versions of PS 2021 to test the code on, cause i can't legally install them from Adobe, so no way to test it other then pirate, which i don't want to do.
If Adobe would make it possible for PS subscribers / developers to test scripts on older versions, for example in some online thingy, i would totally do that.

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 ,
Sep 27, 2021 Sep 27, 2021

Copy link to clipboard

Copied

Error: General Photoshop error occurred. This functionality may not be available in this version of Photoshop. - The command "Get" is not currently available.

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 ,
Sep 27, 2021 Sep 27, 2021

Copy link to clipboard

Copied

Well, i guess, unless i get my hands on older PS version, this script is for 2021 only.
Cause that error is probably due to an inappropriate reference in the getter for that PS version.
But if anyone has the knowledge and will, they will fix it for older versions.

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
People's Champ ,
Sep 27, 2021 Sep 27, 2021

Copy link to clipboard

Copied

quote

Well, i guess, unless i get my hands on older PS version, this script is for 2021 only.
Cause that error is probably due to an inappropriate reference in the getter for that PS version.
But if anyone has the knowledge and will, they will fix it for older versions.


By @Oleqsa

 

Did you write this code yourself? Where did you get this way of getting currentToolOptions?

 

You can read here

ActionDescriptor getter: can't use Property for nested Descriptors?

 

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 ,
Sep 27, 2021 Sep 27, 2021

Copy link to clipboard

Copied

yeah, i found it with "tool" instead of "currentToolOptions", but since i didn't see any difference for me between referencing one or the other, i used "currentToolOptions".
So in order to not get an error in older versions i should put "tool" there and that will fix it?

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
People's Champ ,
Sep 27, 2021 Sep 27, 2021

Copy link to clipboard

Copied

Yes. In two places you need to replace

 

ref.putProperty(stringIDToTypeID("property"), stringIDToTypeID("currentToolOptions"));

 

with

 

ref.putProperty(stringIDToTypeID("property"), stringIDToTypeID("tool"));

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 ,
Sep 27, 2021 Sep 27, 2021

Copy link to clipboard

Copied

LATEST

thank you

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