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

Defining the stroke size by slider

Engaged ,
Feb 11, 2017 Feb 11, 2017

Copy link to clipboard

Copied

How to make this slider work to control the stroke size in a small dialog box.

00000.png

I find here that script that controls the opacity of the layer. I made a basic modification, but I do not know how to make it work by controlling stylles. Thanks in advance!

var d= new Window('dialog','Stylle');

          d.grpOpacity = d.add('panel', undefined,'Stroke'); 

          d.grpOpacity.orientation = 'column'; 

          d.grpOpacity.alignChildren = ['fill','top']; 

          d.grpOpacity.grpSlider = d.grpOpacity.add('group'); 

          d.grpOpacity.grpSlider.spacing = 0; 

          d.grpOpacity.grpSlider.orientation = 'column'; 

          d.grpOpacity.grpSlider.st1 =  d.grpOpacity.grpSlider.add('statictext',undefined,'Structure-Size'); 

          d.grpOpacity.grpSlider.st1.alignment = 'left'; 

          d.grpOpacity.grpSlider.grpSlider = d.grpOpacity.grpSlider.add('group'); 

          d.grpOpacity.grpSlider.grpSlider.alignChildren = ['left','center']; 

          d.grpOpacity.grpSlider.grpSlider.spacing = 0; 

          d.slOpacity = d.grpOpacity.grpSlider.grpSlider.add('slider',undefined,0,0,255); 

          d.slOpacity.value = app.activeDocument.activeLayer.opacity; 

          d.slOpacity.preferredSize.width =100; 

          d.etOpacityValue = d.grpOpacity.grpSlider.grpSlider.add('edittext'); 

          d.etOpacityValue.text = Math.round(app.activeDocument.activeLayer.opacity); 

          d.etOpacityValue.addEventListener ('keydown', InitEditKeyboardHandler ); 

          d.etOpacityValue.preferredSize.width = 20; 

          d.grpOpacity.grpSlider.grpSlider.stUnit = d.grpOpacity.grpSlider.grpSlider.add('statictext',undefined,' px'); 

 

          d.grpOpacity.grpSlider.grpSt = d.grpOpacity.grpSlider.add('group'); 

          d.grpOpacity.grpSlider.grpSt.orientation = 'row'; 

          d.grpOpacity.grpSlider.grpSt.alignment = 'fill'; 

          d.grpOpacity.grpSlider.grpSt.spacing = 0; 

          d.grpOpacity.grpSlider.grpSt.margins = [5,0,0,0]; 

          d.grpOpacity.grpSlider.grpSt.grpLeft = d.grpOpacity.grpSlider.grpSt.add('group'); 

          d.grpOpacity.grpSlider.grpSt.grpLeft.st1 = d.grpOpacity.grpSlider.grpSt.grpLeft.add('statictext',undefined,'0'); 

          d.grpOpacity.grpSlider.grpSt.grpLeft.st1.alignment = ['left','center']; 

          d.grpOpacity.grpSlider.grpSt.grpLeft.st1.preferredSize.width = 70; 

          d.grpOpacity.grpSlider.grpSt.grpLeft.st3 = d.grpOpacity.grpSlider.grpSt.grpLeft.add('statictext',undefined,'255'); 

          d.grpOpacity.grpSlider.grpSt.grpLeft.st3.alignment = ['right','center']; 

          d.grpOpacity.grpSlider.grpSt.grpLeft.st3.preferredSize.width = 40; 

           

          d.grpButtons = d.add('group'); 

          d.grpButtons.alignment = "right"; 

          d.grpButtons.btnCanel = d.grpButtons.add( 'button', undefined, 'Cancel', { name:'cancel' }); 

          d.grpButtons.btnOK = d.grpButtons.add( 'button', undefined, 'Ok', { name:'ok' }); 

           

  d.etOpacityValue.onChanging = d.etOpacityValue.onChange = function(){ 

  var d = FindDialog(this); 

  d.slOpacity.value = Number(this.text); 

  d.slOpacity.onChange(); 

                                                                                                               

                                                                                                              } 

d.slOpacity.onChanging  = d.slOpacity.onChange = function(){ 

var d = FindDialog(this); 

d.etOpacityValue.text = Math.round(this.value); 

       d.slOpacity.onChange = function(){ 

var d = FindDialog(this); 

app.activeDocument.activeLayer.opacity = Math.round(this.value); 

app.refresh(); 

           

d.show(); 

 

function FindDialog( inItem ) { 

     var w = inItem; 

     while ( 'dialog' != w.type ) { 

          if ( undefined == w.parent ) { 

               w = null; 

               break; 

          } 

          w = w.parent; 

     } 

     return w; 

}; 

function InitEditKeyboardHandler (event) { 

    try { 

        var keyIsOK = KeyIsNumeric(event) || 

                                   KeyIsDelete(event) ||  

                                   KeyIsLRArrow(event) || 

                                   KeyIsTabEnterEscape(event);                  

        if (! keyIsOK) { 

            event.preventDefault(); 

            app.beep(); 

        } 

    } 

    catch (e) { 

    } 

}; 

TOPICS
Actions and scripting

Views

1.8K

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 1 Correct answer

Guide , Feb 13, 2017 Feb 13, 2017

Here is the fix for the cancel button also it starts with the correct stroke size.

#target photoshop;

app.bringToFront();

main();

function main(){

var strokeSize = getStrokeSize();

if(strokeSize == null) return;

var d= new Window('dialog','Style'); 

d.grpOpacity = d.add('panel', undefined,'Stroke');   

d.grpOpacity.orientation = 'column';   

d.grpOpacity.alignChildren = ['fill','top'];   

d.grpOpacity.grpSlider = d.grpOpacity.add('group');   

d.grpOpacity.grpSlider.spacing = 0;   

d.grpOpacity.grpSlide

...

Votes

Translate

Translate
Adobe
Community Expert ,
Feb 12, 2017 Feb 12, 2017

Copy link to clipboard

Copied

It is easy to change a layers opacity and there are many interfaces to do it. Short-cuts sliders and even in a layer style dialog.

a simple script line

app.activeDocument.activeLayer.fillOpacity = 50;

Also a Stroke layer style effect has many more attributed then just stoke size.  And as far as I know the only DOM support for layer style is one that applies a named layer style in the style palette.  With Action manager code you can add a layer style that spell out all layer effect desired. Including a stroke style effect.  You can change the stroke effect by adding that spelled out style again with the stroke size changed.  It will be applied without a preview.  If I want a preview I would need to open the dialog which would open the whole layer style dialog with the stroke effect in focus it the layer style just add a stroke effect.  There is not way you can edit or simulate editing the stroke with a preview. Layer style pixels only exists in the document composite rendered by Photoshop in the layer all there are are layer style effect settings. Stroke size is bold below. If  you do a copy and paste of a layer with a layer style all you paste in are the layers pixels you get no layer style or layer style pixels.

// =======================================================

var idsetd = charIDToTypeID( "setd" );

    var desc42 = new ActionDescriptor();

    var idnull = charIDToTypeID( "null" );

        var ref20 = new ActionReference();

        var idPrpr = charIDToTypeID( "Prpr" );

        var idLefx = charIDToTypeID( "Lefx" );

        ref20.putProperty( idPrpr, idLefx );

        var idLyr = charIDToTypeID( "Lyr " );

        var idOrdn = charIDToTypeID( "Ordn" );

        var idTrgt = charIDToTypeID( "Trgt" );

        ref20.putEnumerated( idLyr, idOrdn, idTrgt );

    desc42.putReference( idnull, ref20 );

    var idT = charIDToTypeID( "T   " );

        var desc43 = new ActionDescriptor();

        var idScl = charIDToTypeID( "Scl " );

        var idPrc = charIDToTypeID( "#Prc" );

        desc43.putUnitDouble( idScl, idPrc, 138.888889 );

        var idFrFX = charIDToTypeID( "FrFX" );

            var desc44 = new ActionDescriptor();

            var idenab = charIDToTypeID( "enab" );

            desc44.putBoolean( idenab, true );

            var idpresent = stringIDToTypeID( "present" );

            desc44.putBoolean( idpresent, true );

            var idshowInDialog = stringIDToTypeID( "showInDialog" );

            desc44.putBoolean( idshowInDialog, true );

            var idStyl = charIDToTypeID( "Styl" );

            var idFStl = charIDToTypeID( "FStl" );

            var idInsF = charIDToTypeID( "InsF" );

            desc44.putEnumerated( idStyl, idFStl, idInsF );

            var idPntT = charIDToTypeID( "PntT" );

            var idFrFl = charIDToTypeID( "FrFl" );

            var idSClr = charIDToTypeID( "SClr" );

            desc44.putEnumerated( idPntT, idFrFl, idSClr );

            var idMd = charIDToTypeID( "Md  " );

            var idBlnM = charIDToTypeID( "BlnM" );

            var idCBrn = charIDToTypeID( "CBrn" );

            desc44.putEnumerated( idMd, idBlnM, idCBrn );

            var idOpct = charIDToTypeID( "Opct" );

            var idPrc = charIDToTypeID( "#Prc" );

            desc44.putUnitDouble( idOpct, idPrc, 100.000000 );

            var idSz = charIDToTypeID( "Sz  " );

            var idPxl = charIDToTypeID( "#Pxl" );

            desc44.putUnitDouble( idSz, idPxl, 8.000000 );

            var idClr = charIDToTypeID( "Clr " );

                var desc45 = new ActionDescriptor();

                var idRd = charIDToTypeID( "Rd  " );

                desc45.putDouble( idRd, 254.000000 );

                var idGrn = charIDToTypeID( "Grn " );

                desc45.putDouble( idGrn, 4.980545 );

                var idBl = charIDToTypeID( "Bl  " );

                desc45.putDouble( idBl, 4.980545 );

            var idRGBC = charIDToTypeID( "RGBC" );

            desc44.putObject( idClr, idRGBC, desc45 );

            var idoverprint = stringIDToTypeID( "overprint" );

            desc44.putBoolean( idoverprint, true );

        var idFrFX = charIDToTypeID( "FrFX" );

        desc43.putObject( idFrFX, idFrFX, desc44 );

    var idLefx = charIDToTypeID( "Lefx" );

    desc42.putObject( idT, idLefx, desc43 );

executeAction( idsetd, desc42, DialogModes.NO );

JJMack

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
Engaged ,
Feb 12, 2017 Feb 12, 2017

Copy link to clipboard

Copied

This I know how to do JJMack I'm creating actions that add styles frames that will have the size controlled by the user through a small and practical dialog ... I just want to be able to increase or decrease the strock size by one Dialog box and avoid this annoying standard Photoshop dialog box. This script I posted was just to serve as a template, if someone with more connection can modify and make it work.

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 ,
Feb 13, 2017 Feb 13, 2017

Copy link to clipboard

Copied

Using action manager code like I posted made into a function where size is made a peramater could be used. The stroke would be updated with each slider move. When the user see what the want they would ckick OK.  If they click cancel the function could be used to reset the stroke to the default size.  There is no preview the user sees the actual layer style.

JJMack

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 ,
Feb 13, 2017 Feb 13, 2017

Copy link to clipboard

Copied

Please try this.

#target photoshop;

app.bringToFront();

var d= new Window('dialog','Style'); 

d.grpOpacity = d.add('panel', undefined,'Stroke');   

d.grpOpacity.orientation = 'column';   

d.grpOpacity.alignChildren = ['fill','top'];   

d.grpOpacity.grpSlider = d.grpOpacity.add('group');   

d.grpOpacity.grpSlider.spacing = 0;   

d.grpOpacity.grpSlider.orientation = 'column';   

d.grpOpacity.grpSlider.st1 =  d.grpOpacity.grpSlider.add('statictext',undefined,'Stroke-Size');   

d.grpOpacity.grpSlider.st1.alignment = 'left';   

d.grpOpacity.grpSlider.grpSlider = d.grpOpacity.grpSlider.add('group');   

d.grpOpacity.grpSlider.grpSlider.alignChildren = ['left','center'];   

d.grpOpacity.grpSlider.grpSlider.spacing = 0;   

d.slOpacity = d.grpOpacity.grpSlider.grpSlider.add('slider',undefined,0,0,255);   

d.slOpacity.value = app.activeDocument.activeLayer.opacity;   

d.slOpacity.preferredSize.width =100;   

d.etOpacityValue = d.grpOpacity.grpSlider.grpSlider.add('edittext');   

d.etOpacityValue.text = Math.round(app.activeDocument.activeLayer.opacity);   

d.etOpacityValue.addEventListener ('keydown', InitEditKeyboardHandler );   

d.etOpacityValue.preferredSize.width = 50;   

d.grpOpacity.grpSlider.grpSlider.stUnit = d.grpOpacity.grpSlider.grpSlider.add('statictext',undefined,' px');   

d.grpOpacity.grpSlider.grpSt = d.grpOpacity.grpSlider.add('group');   

d.grpOpacity.grpSlider.grpSt.orientation = 'row';   

d.grpOpacity.grpSlider.grpSt.alignment = 'fill';   

d.grpOpacity.grpSlider.grpSt.spacing = 0;   

d.grpOpacity.grpSlider.grpSt.margins = [5,0,0,0];   

d.grpOpacity.grpSlider.grpSt.grpLeft = d.grpOpacity.grpSlider.grpSt.add('group');   

d.grpOpacity.grpSlider.grpSt.grpLeft.st1 = d.grpOpacity.grpSlider.grpSt.grpLeft.add('statictext',undefined,'0');   

d.grpOpacity.grpSlider.grpSt.grpLeft.st1.alignment = ['left','center'];   

d.grpOpacity.grpSlider.grpSt.grpLeft.st1.preferredSize.width = 70;   

d.grpOpacity.grpSlider.grpSt.grpLeft.st3 = d.grpOpacity.grpSlider.grpSt.grpLeft.add('statictext',undefined,'255');   

d.grpOpacity.grpSlider.grpSt.grpLeft.st3.alignment = ['right','center'];   

d.grpOpacity.grpSlider.grpSt.grpLeft.st3.preferredSize.width = 40;   

d.grpButtons = d.add('group');   

d.grpButtons.alignment = "right";   

d.grpButtons.btnCanel = d.grpButtons.add( 'button', undefined, 'Cancel', { name:'cancel' });   

d.grpButtons.btnOK = d.grpButtons.add( 'button', undefined, 'Ok', { name:'ok' });   

d.etOpacityValue.onChanging = d.etOpacityValue.onChange = function(){   

var d = FindDialog(this);   

d.slOpacity.value = Number(this.text);   

d.slOpacity.onChange();   

                                                                                                                     

                                                                                                                  }   

    d.slOpacity.onChanging  = d.slOpacity.onChange = function(){   

     var d = FindDialog(this);   

     d.etOpacityValue.text = Math.round(this.value);   

     }   

           d.slOpacity.onChange = function(){   

     var d = FindDialog(this);   

     setStrokeSize(Math.round(this.value));

   //  app.activeDocument.activeLayer.opacity = Math.round(this.value);   

     app.refresh();   

     }   

                 

    d.show();   

       

    function FindDialog( inItem ) {   

         var w = inItem;   

         while ( 'dialog' != w.type ) {   

              if ( undefined == w.parent ) {   

                   w = null;   

                   break;   

              }   

              w = w.parent;   

         }   

         return w;   

    };

function KeyHasModifier (event) {

    return event.shiftKey || event.ctrlKey || event.altKey || event.metaKey;

}

function KeyIsNumeric (event) {

    return  (event.keyName >= '0') && (event.keyName <= '9') && ! KeyHasModifier (event);

}

function KeyIsDelete (event) {

    //    Shift-delete is ok

    return (event.keyName == 'Backspace') && ! (event.ctrlKey);

}

function KeyIsLRArrow (event) {

    return ((event.keyName == 'Left') || (event.keyName == 'Right')) && ! (event.altKey || event.metaKey);

}

function KeyIsTabEnterEscape (event) {

    return event.keyName == 'Tab' || event.keyName == 'Enter' || event.keyName == 'Escape';

}

    function InitEditKeyboardHandler (event) {   

        try {   

            var keyIsOK = KeyIsNumeric(event) ||   

                                       KeyIsDelete(event) ||    

                                       KeyIsLRArrow(event) ||   

                                       KeyIsTabEnterEscape(event);                    

            if (! keyIsOK) {   

                event.preventDefault();   

                app.beep();   

            }   

        }   

        catch (e) {   

        }   

    };  

// helper function for working with descriptors by Mike Hale

function getActiveLayerProperty( psKey, psType ) {

    var ref = new ActionReference();

    ref.putProperty( charIDToTypeID( 'Prpr' ), psKey );

    ref.putEnumerated( charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') );

    if( undefined == psType ){

      return executeActionGet( ref ).getObjectValue( psKey );

    }else{

        return executeActionGet( ref );

    }

};

function duplicateDescriptor( descriptor ) {

    var newDescriptor = new ActionDescriptor;

    newDescriptor.fromStream( descriptor.toStream() );

    return newDescriptor;

};

function localizeDescriptor( desc ) {

    var stream, pointer, zStringLength, zstring, localized_string, newZStringLength, previousStream, followingStream, newDesc;

    stream = desc.toStream();

    while( true ) {

        pointer = stream.search(/TEXT....\x00\$\x00\$\x00\$/);

        if( pointer === -1 ) {

            break;

        }

        zStringLength = getLongFromStream( stream, pointer + 4 );

        zstring = readUnicode( stream.substr( pointer + 8, ( zStringLength - 1 ) * 2) );

        localized_string = ( localize( zstring ) ) + '\u0000';

        newZStringLength = localized_string.length;

        previousStream = stream.slice( 0, pointer);

        followingStream = stream.slice( pointer + 8 + zStringLength * 2);

        stream = previousStream.concat( 'TEXT', longToString( newZStringLength ), bytesToUnicode( localized_string ), followingStream );

    }

    newDesc = new ActionDescriptor();

    newDesc.fromStream( stream );

    return newDesc;

};

function getShortFromStream( stream, pointer ) {

    var hi, low;

    hi = stream.charCodeAt( pointer ) << 8 ;

    low = stream.charCodeAt( pointer + 1 );

    return hi + low;

};

function getLongFromStream( stream, pointer ) {

    var hi, low;

    hi = getShortFromStream( stream, pointer) << 16;

    low = getShortFromStream( stream, pointer + 2);

    return hi + low;

};

function readUnicode( unicode ) {

    var string = "";

    for( i = pointer = 0; pointer < unicode.length; i = pointer += 2) {

        string +=String.fromCharCode( getShortFromStream( unicode, pointer ) );

    }

    return string;

};

function longToString( longInteger ) {

    var string;

    string = String.fromCharCode( longInteger >>> 24 );

    string += String.fromCharCode( longInteger << 8 >>> 24 );

    string += String.fromCharCode( longInteger << 16 >>> 24 );

    string += String.fromCharCode( longInteger << 24 >>> 24 );

    return string;

};

function bytesToUnicode( bytes ) {

    var unicode = "", char_code, charIndex;

    for( charIndex  = 0; charIndex < bytes.length; charIndex ++ ) {

        char_code = bytes.charCodeAt( charIndex );

        unicode += String.fromCharCode(char_code >> 8 ) +  String.fromCharCode( char_code & 0xff );

    }

    return unicode;

};

function setStrokeSize(Size ) {

    var layerEffects, newLayerEffects, currentDesc, newDesc, colorDesc, newLayerEffects, layerDesc, targetDesc, setDesc;

    layerEffects = getActiveLayerProperty( charIDToTypeID( 'Lefx' ) );

    newLayerEffects = duplicateDescriptor( layerEffects );

    currentDesc = layerEffects.getObjectValue( stringIDToTypeID( 'frameFX') );

    newDesc = duplicateDescriptor( currentDesc );  

    newDesc.putUnitDouble( charIDToTypeID('Sz  '), charIDToTypeID('#Pxl'), Size );

    newLayerEffects.putObject(  stringIDToTypeID( 'frameFX'),  stringIDToTypeID( 'frameFX'), newDesc );  

    newLayerEffects = localizeDescriptor( newLayerEffects );

    layerDesc = new ActionDescriptor();

    layerDesc.putObject( charIDToTypeID('Lefx'), charIDToTypeID('lfxv'), newLayerEffects);

    targetDesc = new ActionReference();

    targetDesc.putEnumerated( charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') );

    setDesc = new ActionDescriptor;

    setDesc.putObject( charIDToTypeID('T   '), charIDToTypeID('Lyr '), layerDesc );

    setDesc.putReference( charIDToTypeID('null' ), targetDesc );

    executeAction(charIDToTypeID('setd'), setDesc, 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
Contributor ,
Feb 13, 2017 Feb 13, 2017

Copy link to clipboard

Copied

SuperMerlin

I tried it on my photoshop cc2014

does not work?

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 ,
Feb 13, 2017 Feb 13, 2017

Copy link to clipboard

Copied

Ah well, not everything gets better with new versions

It works with CS6, a layer must be selected that has stroke layer effect.

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 ,
Feb 13, 2017 Feb 13, 2017

Copy link to clipboard

Copied

It work fine with CC 2014.  The current layer need to have a layer style that include a stroke effect to start with.  The script retrieves the layer's layer styles effects and the slider will change the size each time you move it and release the mouse button.  The Cancel part is not coded.

Capture.jpg

JJMack

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
Engaged ,
Feb 13, 2017 Feb 13, 2017

Copy link to clipboard

Copied

Thank you SuperMerlin . As always, you were great and genial, so you have a magician's name. I live dreaming of new updates, Adobe further decrease this "Layer Style" style box making it smaller allowing more space for the user.

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
Engaged ,
Feb 13, 2017 Feb 13, 2017

Copy link to clipboard

Copied

tssee@imgof.com  escreveu

SuperMerlin

I tried it on my photoshop cc2014

does not work?

I use the CC2017 version and it worked! Just the "Cancel" button that has a small bug ... What matters is that the "OK" Button fulfills its function well.

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 ,
Feb 13, 2017 Feb 13, 2017

Copy link to clipboard

Copied

Here is the fix for the cancel button also it starts with the correct stroke size.

#target photoshop;

app.bringToFront();

main();

function main(){

var strokeSize = getStrokeSize();

if(strokeSize == null) return;

var d= new Window('dialog','Style'); 

d.grpOpacity = d.add('panel', undefined,'Stroke');   

d.grpOpacity.orientation = 'column';   

d.grpOpacity.alignChildren = ['fill','top'];   

d.grpOpacity.grpSlider = d.grpOpacity.add('group');   

d.grpOpacity.grpSlider.spacing = 0;   

d.grpOpacity.grpSlider.orientation = 'column';   

d.grpOpacity.grpSlider.st1 =  d.grpOpacity.grpSlider.add('statictext',undefined,'Stroke-Size');   

d.grpOpacity.grpSlider.st1.alignment = 'left';   

d.grpOpacity.grpSlider.grpSlider = d.grpOpacity.grpSlider.add('group');   

d.grpOpacity.grpSlider.grpSlider.alignChildren = ['left','center'];   

d.grpOpacity.grpSlider.grpSlider.spacing = 0;   

d.slOpacity = d.grpOpacity.grpSlider.grpSlider.add('slider',undefined,0,0,255);   

d.slOpacity.value = strokeSize; 

d.slOpacity.preferredSize.width =100;   

d.etOpacityValue = d.grpOpacity.grpSlider.grpSlider.add('edittext');   

d.etOpacityValue.text = strokeSize; 

d.etOpacityValue.addEventListener ('keydown', InitEditKeyboardHandler );   

d.etOpacityValue.preferredSize.width = 50;   

d.grpOpacity.grpSlider.grpSlider.stUnit = d.grpOpacity.grpSlider.grpSlider.add('statictext',undefined,' px');   

d.grpOpacity.grpSlider.grpSt = d.grpOpacity.grpSlider.add('group');   

d.grpOpacity.grpSlider.grpSt.orientation = 'row';   

d.grpOpacity.grpSlider.grpSt.alignment = 'fill';   

d.grpOpacity.grpSlider.grpSt.spacing = 0;   

d.grpOpacity.grpSlider.grpSt.margins = [5,0,0,0];   

d.grpOpacity.grpSlider.grpSt.grpLeft = d.grpOpacity.grpSlider.grpSt.add('group');   

d.grpOpacity.grpSlider.grpSt.grpLeft.st1 = d.grpOpacity.grpSlider.grpSt.grpLeft.add('statictext',undefined,'0');   

d.grpOpacity.grpSlider.grpSt.grpLeft.st1.alignment = ['left','center'];   

d.grpOpacity.grpSlider.grpSt.grpLeft.st1.preferredSize.width = 70;   

d.grpOpacity.grpSlider.grpSt.grpLeft.st3 = d.grpOpacity.grpSlider.grpSt.grpLeft.add('statictext',undefined,'255');   

d.grpOpacity.grpSlider.grpSt.grpLeft.st3.alignment = ['right','center'];   

d.grpOpacity.grpSlider.grpSt.grpLeft.st3.preferredSize.width = 40;   

d.grpButtons = d.add('group');   

d.grpButtons.alignment = "right";   

d.grpButtons.btnCanel = d.grpButtons.add( 'button', undefined, 'Cancel', { name:'cancel' });   

d.grpButtons.btnOK = d.grpButtons.add( 'button', undefined, 'Ok', { name:'ok' });   

d.etOpacityValue.onChanging = d.etOpacityValue.onChange = function(){   

var d = FindDialog(this);   

d.slOpacity.value = Number(this.text);   

d.slOpacity.onChange();   

                                                                                                                     

                                                                                                                  }   

    d.slOpacity.onChanging  = d.slOpacity.onChange = function(){   

     var d = FindDialog(this);   

     d.etOpacityValue.text = Math.round(this.value);   

     }   

           d.slOpacity.onChange = function(){   

     var d = FindDialog(this);   

     setStrokeSize(Math.round(this.value));

   //  app.activeDocument.activeLayer.opacity = Math.round(this.value);   

     app.refresh();   

     }   

d.grpButtons.btnCanel.onClick=function(){

    d.close(2);

    setStrokeSize(strokeSize);

    }

    d.show();   

       

    function FindDialog( inItem ) {   

         var w = inItem;   

         while ( 'dialog' != w.type ) {   

              if ( undefined == w.parent ) {   

                   w = null;   

                   break;   

              }   

              w = w.parent;   

         }   

         return w;   

    };

function KeyHasModifier (event) {

    return event.shiftKey || event.ctrlKey || event.altKey || event.metaKey;

}

function KeyIsNumeric (event) {

    return  (event.keyName >= '0') && (event.keyName <= '9') && ! KeyHasModifier (event);

}

function KeyIsDelete (event) {

    //    Shift-delete is ok

    return (event.keyName == 'Backspace') && ! (event.ctrlKey);

}

function KeyIsLRArrow (event) {

    return ((event.keyName == 'Left') || (event.keyName == 'Right')) && ! (event.altKey || event.metaKey);

}

function KeyIsTabEnterEscape (event) {

    return event.keyName == 'Tab' || event.keyName == 'Enter' || event.keyName == 'Escape';

}

    function InitEditKeyboardHandler (event) {   

        try {   

            var keyIsOK = KeyIsNumeric(event) ||   

                                       KeyIsDelete(event) ||    

                                       KeyIsLRArrow(event) ||   

                                       KeyIsTabEnterEscape(event);                    

            if (! keyIsOK) {   

                event.preventDefault();   

                app.beep();   

            }   

        }   

        catch (e) {   

        }   

    };  

};

// helper function for working with descriptors by Mike Hale

function getActiveLayerProperty( psKey, psType ) {

    var ref = new ActionReference();

    ref.putProperty( charIDToTypeID( 'Prpr' ), psKey );

    ref.putEnumerated( charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') );

    if( undefined == psType ){

      return executeActionGet( ref ).getObjectValue( psKey );

    }else{

        return executeActionGet( ref );

    }

};

function duplicateDescriptor( descriptor ) {

    var newDescriptor = new ActionDescriptor;

    newDescriptor.fromStream( descriptor.toStream() );

    return newDescriptor;

};

function localizeDescriptor( desc ) {

    var stream, pointer, zStringLength, zstring, localized_string, newZStringLength, previousStream, followingStream, newDesc;

    stream = desc.toStream();

    while( true ) {

        pointer = stream.search(/TEXT....\x00\$\x00\$\x00\$/);

        if( pointer === -1 ) {

            break;

        }

        zStringLength = getLongFromStream( stream, pointer + 4 );

        zstring = readUnicode( stream.substr( pointer + 8, ( zStringLength - 1 ) * 2) );

        localized_string = ( localize( zstring ) ) + '\u0000';

        newZStringLength = localized_string.length;

        previousStream = stream.slice( 0, pointer);

        followingStream = stream.slice( pointer + 8 + zStringLength * 2);

        stream = previousStream.concat( 'TEXT', longToString( newZStringLength ), bytesToUnicode( localized_string ), followingStream );

    }

    newDesc = new ActionDescriptor();

    newDesc.fromStream( stream );

    return newDesc;

};

function getShortFromStream( stream, pointer ) {

    var hi, low;

    hi = stream.charCodeAt( pointer ) << 8 ;

    low = stream.charCodeAt( pointer + 1 );

    return hi + low;

};

function getLongFromStream( stream, pointer ) {

    var hi, low;

    hi = getShortFromStream( stream, pointer) << 16;

    low = getShortFromStream( stream, pointer + 2);

    return hi + low;

};

function readUnicode( unicode ) {

    var string = "";

    for( i = pointer = 0; pointer < unicode.length; i = pointer += 2) {

        string +=String.fromCharCode( getShortFromStream( unicode, pointer ) );

    }

    return string;

};

function longToString( longInteger ) {

    var string;

    string = String.fromCharCode( longInteger >>> 24 );

    string += String.fromCharCode( longInteger << 8 >>> 24 );

    string += String.fromCharCode( longInteger << 16 >>> 24 );

    string += String.fromCharCode( longInteger << 24 >>> 24 );

    return string;

};

function bytesToUnicode( bytes ) {

    var unicode = "", char_code, charIndex;

    for( charIndex  = 0; charIndex < bytes.length; charIndex ++ ) {

        char_code = bytes.charCodeAt( charIndex );

        unicode += String.fromCharCode(char_code >> 8 ) +  String.fromCharCode( char_code & 0xff );

    }

    return unicode;

};

function setStrokeSize(Size ) {

    var layerEffects, newLayerEffects, currentDesc, newDesc, colorDesc, newLayerEffects, layerDesc, targetDesc, setDesc;

    layerEffects = getActiveLayerProperty( charIDToTypeID( 'Lefx' ) );

    newLayerEffects = duplicateDescriptor( layerEffects );

    currentDesc = layerEffects.getObjectValue( stringIDToTypeID( 'frameFX') );

    newDesc = duplicateDescriptor( currentDesc );  

    newDesc.putUnitDouble( charIDToTypeID('Sz  '), charIDToTypeID('#Pxl'), Size );

    newLayerEffects.putObject(  stringIDToTypeID( 'frameFX'),  stringIDToTypeID( 'frameFX'), newDesc );  

    newLayerEffects = localizeDescriptor( newLayerEffects );

    layerDesc = new ActionDescriptor();

    layerDesc.putObject( charIDToTypeID('Lefx'), charIDToTypeID('lfxv'), newLayerEffects);

    targetDesc = new ActionReference();

    targetDesc.putEnumerated( charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') );

    setDesc = new ActionDescriptor;

    setDesc.putObject( charIDToTypeID('T   '), charIDToTypeID('Lyr '), layerDesc );

    setDesc.putReference( charIDToTypeID('null' ), targetDesc );

    executeAction(charIDToTypeID('setd'), setDesc, DialogModes.NO);

};

function getStrokeSize(){

var ref = new ActionReference();

ref.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );

var desc = executeActionGet(ref);

if(desc.hasKey(stringIDToTypeID( 'layerEffects' ))){

if(!desc.getBoolean (stringIDToTypeID( 'layerFXVisible'))) return undefined;

desc = desc.getObjectValue(stringIDToTypeID('layerEffects'));

if(!desc.hasKey(stringIDToTypeID( 'frameFX'))) return null;

desc = desc.getObjectValue(stringIDToTypeID('frameFX'));

return desc.getUnitDoubleValue (stringIDToTypeID( 'size' ));

    }

return null;

};

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
Engaged ,
Feb 13, 2017 Feb 13, 2017

Copy link to clipboard

Copied

Perfect SuperMerlin! I will be eternally grateful to you! Thank you one more time.

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 ,
Feb 13, 2017 Feb 13, 2017

Copy link to clipboard

Copied

That restores your Super prefix magician or is wizard.  I think I remember watching your farther MrWizard on TV that new invention my farther brought home when I was a boy.

It is also nice to see you leave Mike name in code he is missed RIP..

JJMack

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
Contributor ,
Feb 14, 2017 Feb 14, 2017

Copy link to clipboard

Copied

That's really cool, I was looking for something like that too. I did some tests here and realized that the Slider works well but if correctly position the mouse pointer over the slider arrow. I've found this script that shows you can get better and more precise control.

#target photoshop

function WinObject() {

  // Long resource String for 'palette' Window

  var windowResource = "palette {          orientation: 'column',         alignChildren: ['fill', 'top'],          preferredSize:[300, 130],         text: 'ScriptUI Window - palette',          margins:15,                 sliderPanel: Panel {             orientation: 'row',             alignChildren: 'right',             margins:15,             text: ' PANEL ',             st: StaticText { text: 'Value:' },             sl: Slider { minvalue: 1, maxvalue: 100, value: 30, size:[220,20] },             te: EditText { text: '30', characters: 5, justify: 'left'}             }                 bottomGroup: Group{             cd: Checkbox { text:'Checkbox value', value: true },             cancelButton: Button { text: 'Cancel', properties:{name:'cancel'}, size: [120,24], alignment:['right', 'center'] },             applyButton: Button { text: 'Apply', properties:{name:'ok'}, size: [120,24], alignment:['right', 'center'] },         }    }";

  var win = new Window(windowResource);

  win.bottomGroup.cancelButton.onClick = function() { win.close() };

  win.bottomGroup.applyButton.onClick = function() { win.close() };

  // Show the Window

  win.show();

};

// String message for BridgeTalk

var message = WinObject.toString();

// construct an anonymous instance and add it to the string

message += "\nnew WinObject();"

// $.writeln(message); // check it in the ESTK Console, just in case

var bt = new BridgeTalk();

bt.target = "photoshop";

bt.body = message;

bt.send();

SuperMerlin, could a better control be based on this script? Would be 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
Community Expert ,
Feb 14, 2017 Feb 14, 2017

Copy link to clipboard

Copied

I do not see any difference in the sliders except the one you like is displayed wider that is just a couple of setting in the dialog.

Is the length of the slider what make you state it more precise.  Precise is what the input field is. Adding 100 to a  couple of the width setting in SuperMerrlin dialog will make the slider wider precise is still the input field in both Dialog yours and his.

I have notice I can nudge the slider using the arrow keys and the stroke updates  but the number in the input field is not updated.

I also seem to be able to hang CC 2015, CC 2015.5 and CC 2017 using this script and playing around with the slider input filed and arrow keys.   I still use CC 2014 I have not been able to hang cc 2014 using this script.

I'm still testing CC 2014 for it is not that east the hand cc 2015, cc 2015.5 and cc 2017 but it is possible with this script.

JJMack

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 ,
Feb 14, 2017 Feb 14, 2017

Copy link to clipboard

Copied

It does seem smoother!

#target photoshop;

app.bringToFront();

if(documents.length) main();

function main(){

    function WinObject() { 

        try{

var strokeSize = getStrokeSize();

if(strokeSize == null) return;          

      /*Resource String for 'palette' Window */

      var windowResource = "palette {orientation: 'column',alignChildren: ['fill', 'top'],preferredSize:[300, 130],"+

      "text: 'Set Stroke Effect Size',margins:15,sliderPanel: Panel {orientation: 'row',alignChildren: 'right',"+

      "margins:15,text: ' Set Size ',st: StaticText { text: 'Value:' },sl: Slider{"+

      "minvalue: 1, maxvalue: 255, value: 0, size:[220,20] }, te: EditText { text: '30', characters: 5, justify: 'left'}}"+

      "bottomGroup: Group{cancelButton: Button {"+

      "text: 'Cancel', properties:{name:'cancel'}, size: [120,24], alignment:['right', 'center'] },"+

      "applyButton: Button { text: 'Apply', properties:{name:'ok'}, size: [120,24], alignment:['right', 'center'] },}}"; 

      var win = new Window(windowResource);

      win.sliderPanel.te.text=strokeSize;

      win.sliderPanel.sl.value=strokeSize;

      win.sliderPanel.te.onChanging = function(){

          win.sliderPanel.sl.value = Number(win.sliderPanel.te.text);

          setStrokeSize(win.sliderPanel.sl.value.toFixed(0));

          }

     win.sliderPanel.sl.onChanging = function(){

          win.sliderPanel.te.text=win.sliderPanel.sl.value.toFixed(0);

          setStrokeSize(Math.round(this.value));

          }

      win.bottomGroup.cancelButton.onClick = function() {

        win.close(2);

        setStrokeSize(strokeSize);

          }; 

      win.bottomGroup.applyButton.onClick = function() {

          win.close(0);

          setStrokeSize(win.sliderPanel.sl.value.toFixed(0));

          };    

      // Show the Window 

      win.show(); 

     

// helper function for working with descriptors by Mike Hale

function getActiveLayerProperty( psKey, psType ) {

    var ref = new ActionReference();

    ref.putProperty( charIDToTypeID( 'Prpr' ), psKey );

    ref.putEnumerated( charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') );

    if( undefined == psType ){

      return executeActionGet( ref ).getObjectValue( psKey );

    }else{

        return executeActionGet( ref );

    }

};

function duplicateDescriptor( descriptor ) {

    var newDescriptor = new ActionDescriptor;

    newDescriptor.fromStream( descriptor.toStream() );

    return newDescriptor;

};

function localizeDescriptor( desc ) {

    var stream, pointer, zStringLength, zstring, localized_string, newZStringLength, previousStream, followingStream, newDesc;

    stream = desc.toStream();

    while( true ) {

        pointer = stream.search(/TEXT....\x00\$\x00\$\x00\$/);

        if( pointer === -1 ) {

            break;

        }

        zStringLength = getLongFromStream( stream, pointer + 4 );

        zstring = readUnicode( stream.substr( pointer + 8, ( zStringLength - 1 ) * 2) );

        localized_string = ( localize( zstring ) ) + '\u0000';

        newZStringLength = localized_string.length;

        previousStream = stream.slice( 0, pointer);

        followingStream = stream.slice( pointer + 8 + zStringLength * 2);

        stream = previousStream.concat( 'TEXT', longToString( newZStringLength ), bytesToUnicode( localized_string ), followingStream );

    }

    newDesc = new ActionDescriptor();

    newDesc.fromStream( stream );

    return newDesc;

};

function getShortFromStream( stream, pointer ) {

    var hi, low;

    hi = stream.charCodeAt( pointer ) << 8 ;

    low = stream.charCodeAt( pointer + 1 );

    return hi + low;

};

function getLongFromStream( stream, pointer ) {

    var hi, low;

    hi = getShortFromStream( stream, pointer) << 16;

    low = getShortFromStream( stream, pointer + 2);

    return hi + low;

};

function readUnicode( unicode ) {

    var string = "";

    for( i = pointer = 0; pointer < unicode.length; i = pointer += 2) {

        string +=String.fromCharCode( getShortFromStream( unicode, pointer ) );

    }

    return string;

};

function longToString( longInteger ) {

    var string;

    string = String.fromCharCode( longInteger >>> 24 );

    string += String.fromCharCode( longInteger << 8 >>> 24 );

    string += String.fromCharCode( longInteger << 16 >>> 24 );

    string += String.fromCharCode( longInteger << 24 >>> 24 );

    return string;

};

function bytesToUnicode( bytes ) {

    var unicode = "", char_code, charIndex;

    for( charIndex  = 0; charIndex < bytes.length; charIndex ++ ) {

        char_code = bytes.charCodeAt( charIndex );

        unicode += String.fromCharCode(char_code >> 8 ) +  String.fromCharCode( char_code & 0xff );

    }

    return unicode;

};

function setStrokeSize(Size ) {

    var layerEffects, newLayerEffects, currentDesc, newDesc, colorDesc, newLayerEffects, layerDesc, targetDesc, setDesc;

    layerEffects = getActiveLayerProperty( charIDToTypeID( 'Lefx' ) );

    newLayerEffects = duplicateDescriptor( layerEffects );

    currentDesc = layerEffects.getObjectValue( stringIDToTypeID( 'frameFX') );

    newDesc = duplicateDescriptor( currentDesc );  

    newDesc.putUnitDouble( charIDToTypeID('Sz  '), charIDToTypeID('#Pxl'), Size );

    newLayerEffects.putObject(  stringIDToTypeID( 'frameFX'),  stringIDToTypeID( 'frameFX'), newDesc );  

    newLayerEffects = localizeDescriptor( newLayerEffects );

    layerDesc = new ActionDescriptor();

    layerDesc.putObject( charIDToTypeID('Lefx'), charIDToTypeID('lfxv'), newLayerEffects);

    targetDesc = new ActionReference();

    targetDesc.putEnumerated( charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') );

    setDesc = new ActionDescriptor;

    setDesc.putObject( charIDToTypeID('T   '), charIDToTypeID('Lyr '), layerDesc );

    setDesc.putReference( charIDToTypeID('null' ), targetDesc );

    executeAction(charIDToTypeID('setd'), setDesc, DialogModes.NO);

};

function getStrokeSize(){

var ref = new ActionReference();

ref.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );

var desc = executeActionGet(ref);

if(desc.hasKey(stringIDToTypeID( 'layerEffects' ))){

if(!desc.getBoolean (stringIDToTypeID( 'layerFXVisible'))) return undefined;

desc = desc.getObjectValue(stringIDToTypeID('layerEffects'));

if(!desc.hasKey(stringIDToTypeID( 'frameFX'))) return null;

desc = desc.getObjectValue(stringIDToTypeID('frameFX'));

return desc.getUnitDoubleValue (stringIDToTypeID( 'size' ));

    }

return null;

};

      }catch(e){alert(e + "\n" + e.line);}

    };       

    // String message for BridgeTalk 

    var message = WinObject.toString();       

    // construct an anonymous instance and add it to the string 

    message += "\nnew WinObject();" 

    // $.writeln(message); // check it in the ESTK Console, just in case    

    var bt = new BridgeTalk(); 

    bt.target = "photoshop"; 

    bt.body = message; 

    bt.send(); 

};

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
Engaged ,
Feb 14, 2017 Feb 14, 2017

Copy link to clipboard

Copied

Seeing the two examples here, I really noticed a difference in behavior, it slides smoother, I also had the sensation that the mouse arrow has a Snap linked to the slider indicator making it behave better than the standard Photoshop slider.

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
Contributor ,
Feb 14, 2017 Feb 14, 2017

Copy link to clipboard

Copied

SuperMerlin, Your modification is 100% better now, Congratulations ...

Thank you very much!

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 ,
Feb 14, 2017 Feb 14, 2017

Copy link to clipboard

Copied

So far I have not been able to hang CC 2015 and up with this version but I do notice some other strange thing.  The arrow keys will move the slider but nothing is updated.  If I type a number and have not first targeted the input field this script will change the layers opacity the old script does not. If I mover the slider with the arrow key and click apply the un-display moved value will be used to set the stroke at that point..   The two script seem to act differently if a I empty the input field and press enter. Nether acted as I expect them too.

JJMack

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
Engaged ,
Feb 14, 2017 Feb 14, 2017

Copy link to clipboard

Copied

This script is very good and very useful, Congratulations to those who had this brilliant idea and to the guy who made it funcinar: "SuperMerlin,". How many good ideas here! I'll leave my ideira here: A button with an option to alter the color of strock?

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 ,
Feb 14, 2017 Feb 14, 2017

Copy link to clipboard

Copied

LATEST

I would use CC 2014 that version of ScriptUI seems to work better than the newer versions of ScriptUI....

JJMack

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 ,
Feb 13, 2017 Feb 13, 2017

Copy link to clipboard

Copied

Impressive. Way over my abilities. However the cancel button should be removed. The script does not reset the stoke size to the initial size.

JJMack

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