Skip to main content
Inspiring
August 26, 2014
Answered

Is it possible to script a Pause, allowing brushing etc

  • August 26, 2014
  • 4 replies
  • 8489 views

I use a workflow script and actions to retouch large numbers of files and it would be fabulous if I could do some layer mask brushing on each image "mid batch". Is it possible to create a Pause Script (60-120 seconds would be ideal) that can be called from an action or inserted into my pressing script?

Can anyone tell me a) if this possible b) which Javascript commands I should try ?

This topic has been closed for replies.
Correct answer r-bin

Works well on CS6.

Worse on CC2018 due to the use of refresh()

You can draw, adjust adjustments layers and even invoke other scripts.

var cs6 = (parseInt(app.version)==13)

var time = 60;

var old_time;

var msg = new Window("palette", "Draw or do something while script is waiting");

msg.preferredSize.width = 200;

msg.txt = msg.add("statictext", undefined, "");

msg.txt.preferredSize.width = 220;

msg.txt.justify = "center";

msg.btn = msg.add("button", undefined, "Continue");

msg.btn.onClick = function() { msg.hide(); }

msg.show();

msg.frameLocation = [50, 100];

$.hiresTimer;

set_performance("stepByStep");

app.displayDialogs = DialogModes.ERROR;

try {

    while (msg.visible && time > 0)

        {

        if (old_time != time.toFixed(0))

            {

            msg.txt.text = "You have: " + time.toFixed(0) + " sec";

            old_time = time.toFixed(0);

            }

        if (cs6) app.bringToFront();

        else     app.refresh(); 

        time -= ($.hiresTimer/1000000);

        }

    }

catch (e) { }           

set_performance("accelerated");

msg.close();

alert("Script End")

function set_performance(mode)

    {

    try {

        var r1 = new ActionReference();

        r1.putProperty( charIDToTypeID( "Prpr" ), charIDToTypeID( "PbkO" ) );

        r1.putEnumerated( charIDToTypeID( "capp" ), charIDToTypeID( "Ordn" ), charIDToTypeID( "Trgt" ) );

        var d1 = new ActionDescriptor();

        d1.putReference( charIDToTypeID( "null" ), r1 );

        var d2 = new ActionDescriptor();

        d2.putEnumerated( stringIDToTypeID( "performance" ), stringIDToTypeID( "performance" ), stringIDToTypeID( mode ) );

        d1.putObject( charIDToTypeID( "T   " ), charIDToTypeID( "PbkO" ), d2 );

        executeAction( charIDToTypeID( "setd" ), d1, DialogModes.NO );

        }

    catch (e) { throw(e); }

    }

4 replies

r-binCorrect answer
Brainiac
February 21, 2018

Works well on CS6.

Worse on CC2018 due to the use of refresh()

You can draw, adjust adjustments layers and even invoke other scripts.

var cs6 = (parseInt(app.version)==13)

var time = 60;

var old_time;

var msg = new Window("palette", "Draw or do something while script is waiting");

msg.preferredSize.width = 200;

msg.txt = msg.add("statictext", undefined, "");

msg.txt.preferredSize.width = 220;

msg.txt.justify = "center";

msg.btn = msg.add("button", undefined, "Continue");

msg.btn.onClick = function() { msg.hide(); }

msg.show();

msg.frameLocation = [50, 100];

$.hiresTimer;

set_performance("stepByStep");

app.displayDialogs = DialogModes.ERROR;

try {

    while (msg.visible && time > 0)

        {

        if (old_time != time.toFixed(0))

            {

            msg.txt.text = "You have: " + time.toFixed(0) + " sec";

            old_time = time.toFixed(0);

            }

        if (cs6) app.bringToFront();

        else     app.refresh(); 

        time -= ($.hiresTimer/1000000);

        }

    }

catch (e) { }           

set_performance("accelerated");

msg.close();

alert("Script End")

function set_performance(mode)

    {

    try {

        var r1 = new ActionReference();

        r1.putProperty( charIDToTypeID( "Prpr" ), charIDToTypeID( "PbkO" ) );

        r1.putEnumerated( charIDToTypeID( "capp" ), charIDToTypeID( "Ordn" ), charIDToTypeID( "Trgt" ) );

        var d1 = new ActionDescriptor();

        d1.putReference( charIDToTypeID( "null" ), r1 );

        var d2 = new ActionDescriptor();

        d2.putEnumerated( stringIDToTypeID( "performance" ), stringIDToTypeID( "performance" ), stringIDToTypeID( mode ) );

        d1.putObject( charIDToTypeID( "T   " ), charIDToTypeID( "PbkO" ), d2 );

        executeAction( charIDToTypeID( "setd" ), d1, DialogModes.NO );

        }

    catch (e) { throw(e); }

    }

Gabarito
Known Participant
February 21, 2018

Very interesting!!!

It's what I was looking for.

But where do I put my code?

Inside that try statement?

try { 

    while (msg.visible && time > 0) 

        { 

        if (old_time != time.toFixed(0)) 

            { 

            msg.txt.text = "You have: " + time.toFixed(0) + " sec"; 

            old_time = time.toFixed(0); 

            } 

  Here???

        if (cs6) app.bringToFront(); 

        else     app.refresh();   

  Here??? 

        time -= ($.hiresTimer/1000000); 

        } 

    } 

catch (e) { }             

So, where?

Brainiac
February 21, 2018

Place the first part of your code before all this script. Place the second part instead of the alert ("Script End") command.

It's better to make my entire script as a function and call it in the necessary places in your scripts.

Known Participant
August 28, 2014

OrchidPhoto,

You can try running the first half of the script normally, then show a ScriptUI palette where you want to break. The palette should contain a 'Continue' button. Add the rest of the functionality of the script to the callback of this Continue button.

JJMack
Community Expert
February 20, 2018

Photoshop ScriptUI does not actually support Palette Windows in a Photoshop Script run in from Photoshop. The Script though suspended and waiting on the palette being used.  Photoshop UI is not given back control.  So the user can do nothing in Photoshop but use the Palette window.  I have been able to write a Photoshop Script that opens palette window from a Photoshop Extention and use Photoshop with the Palette window open.

JJMack
JJMack
Community Expert
August 27, 2014

OrchidPhoto wrote:

I use a workflow script and actions to retouch large numbers of files and it would be fabulous if I could do some layer mask brushing on each image "mid batch". Is it possible to create a Pause Script (60-120 seconds would be ideal) that can be called from an action or inserted into my pressing script?

"that can be called from an action"   I do not understand if your using an action to begin with you can pause an action with a stop message like "Piant on the layer mask to make it better. When done click on "PLAY" in the Actions Palette  to continue the action.


However you also write batch.   Having interaction in a batch process sort of negate it being a batch process.

JJMack
AviMathur
Adobe Employee
Adobe Employee
September 11, 2014

hey JJMack can you provide an example..

JJMack
Community Expert
September 11, 2014

It more important to understand that it is not possible to pause an action or a script.  That you can program both to simulate a pause.   What is good about that is everything is programmed into a single file.  There is only one file to maintain.  However the file when used must be used twice to get its full function.  If  you look at the action palette and expand an action part way so you can see all the steps but not the setting used in the steps.  You can highlight the action and click the play button and the action will run.  You could also have highlighted one of the action step and clicked the play button and the action would have starter from the highlighted step.   So you could say a action contains many actions.   Inserting a STOP in an action  in effect breaks and action into at least two every stop you add basically adds an additional action.  So if you add a single stop into an action it brakes the action into the first part and a second part.  So when you highlighted the action it will play the first part and stop when it encounter the stop and the step after the stop is  highlighted. when you click the play button a second time the second part plays plays and the action complete it job. The Stop is not a pause its a place holder.  You do not have to play the second part.  You can do the same in a script you can program  Part One and program Part Two what you need do is program the place holder.  It could be a crude as a prompt which part do you want to execute One or Two or the place holder could be set by part one so that when and it the script is run the second time part two would execute.

You might call the Actions and Scripts "Run or Play Twice" programs....

Here is and example of one of my run twice scripts I created to be used within actions.

SaveAndRestoreResolution.jsx

/* ======================================================================================

// 2009  John J. McAssey (JJMack)  http://www.mouseprints.net/

//

// This script is supplied as is. It is provided as freeware.

// The author accepts no liability for any problems arising from its use.

//

// This script is designed to be used by a Photoshop Action twice

// A good pratice to use when creating an actions that use this scipt is for the action

// not to do a save or play some other action between its two useages of this Script.

//

// The first time this script is used by an action the documents current resolution

// and ruler units are saved into the document's meta-data Info Instructions field.

//

// The second time this script used by the action the script retreives what was

// saved in the meta-data during the first usage, resolution and ruler units.

// The document is resized to the saved resolution,

// Photoshop's ruler units are set to saved units

// and the saved data is removed from the document's meta-data Info Instructions field.

//

// ===================================================================================== */

/*

<javascriptresource>

<about>$$$/JavaScripts/SaveAndRestoreResolution/About=JJMack's SaveAndRestoreResolution.^r^rCopyright 2009 Mouseprints.^r^rRun twice script utility for action.^rNOTE:Don't play other actions between runs!^r^rFirst Run records Photoshop's preferences Units and documents DPI resolution.^rSecond Run restores the recorded setting and removes the recording.</about>

<category>JJMack's Action Run Twice Utility</category>

</javascriptresource>

*/

if (app.documents.length > 0) {

  if (app.activeDocument.info.instructions.indexOf("<Resolution>") == -1 ){ // no footprint fisrt useage

  //alert("first");

  // Retreive Document information for Foot Print

                var units = app.preferences.rulerUnits;

  app.preferences.rulerUnits = Units.PIXELS; // set ruler units to PIXELS

                var typeunits = app.preferences.typeUnits;

  var res = app.activeDocument.resolution;

  // put footprint in metadata info instructions

  app.activeDocument.info.instructions = app.activeDocument.info.instructions + "<Units>" + units + "</Units>"  + "<Tunits>" + typeunits + "</Tunits>" + "<Resolution>" + res + "</Resolution>";

  //alert( "Saved ="  + "<Units>" + units + "</Units>" + "<Tunits>" + typeunits + "</Tunits>" + "<Resolution>" + res + "</Resolution>" );

  app.preferences.rulerUnits = units; // restore ruler units

  }

  else {

  //alert("second");

  // Retreive saved information

  unitsOffset = app.activeDocument.info.instructions.indexOf("<Units>") + "<Units>".length;

  unitsLength = app.activeDocument.info.instructions.indexOf("</Units>") -unitsOffset;

  savedUnits = app.activeDocument.info.instructions.substr(unitsOffset, unitsLength);

  tunitsOffset = app.activeDocument.info.instructions.indexOf("<Tunits>") + "<Tunits>".length;

  tunitsLength = app.activeDocument.info.instructions.indexOf("</Tunits>") -tunitsOffset;

  savedTunits = app.activeDocument.info.instructions.substr(tunitsOffset, tunitsLength);

  resOffset = app.activeDocument.info.instructions.indexOf("<Resolution>") + "<Resolution>".length;

  resLength = app.activeDocument.info.instructions.indexOf("</Resolution>") + -resOffset;

  savedResolution = app.activeDocument.info.instructions.substr(resOffset, resLength);

  //alert("Resolution = " + savedResolution + " Units = " + savedUnits );

  // Restore resolution

  app.preferences.rulerUnits = Units.PIXELS;

  activeDocument.resizeImage(null, null, savedResolution, ResampleMethod.NONE);

  // Restore ruler units

  // I get a message Enumerated value expected if I try to use var savedUnits app.preferences.rulerUnits = savedUnits;

  // perhaps if I knew Javascript I would not need to use the following if else if .....

  if ( savedUnits == "Units.INCHES" ){ app.preferences.rulerUnits = Units.INCHES;}

  else if ( savedUnits == "Units.CM" ){ app.preferences.rulerUnits = Units.CM;}

  else if ( savedUnits == "Units.PERCENT" ){ app.preferences.rulerUnits = Units.PERCENT;}

  else if ( savedUnits == "Units.MM" ){ app.preferences.rulerUnits = Units.MM;}

  else if ( savedUnits == "Units.PIXELS" ){ app.preferences.rulerUnits = Units.PIXELS;}

  else if ( savedUnits == "Units.POINTS" ){ app.preferences.rulerUnits = Units.POINTS;}

  else if ( savedUnits == "Units.PICAS" ){ app.preferences.rulerUnits = Units.PICAS;}

  // Restore Type units

  if ( savedTunits == "TypeUnits.PIXELS" ){ app.preferences.typeUnits = TypeUnits.PIXELS;}

  else if ( savedTunits == "TypeUnits.POINTS" ){ app.preferences.typeUnits = TypeUnits.POINTS;}

  else if ( savedTunits == "TypeUnits.MM" ){ app.preferences.typeUnits = TypeUnits.MM;}

  // Remove footprint from metadata info instructions

  before = app.activeDocument.info.instructions.substr(0,app.activeDocument.info.instructions.indexOf("<Units>"));

  afterOffset = app.activeDocument.info.instructions.indexOf("</Resolution>") + "</Resolution>".length;

  after = app.activeDocument.info.instructions.substr(afterOffset, app.activeDocument.info.instructions.length - afterOffset);

  //alert ("before = " + before + " after = " + after);

  app.activeDocument.info.instructions = before + after;

  }

}

else { alert("You must have at least one open document to run this script!"); }

JJMack
pixxxelschubser
Community Expert
August 26, 2014

Hi OrchidPhoto,

yes, you can say: "script wait any time" e.g. like this:

alert("wait a second");

$.sleep( 999 ); /*Milliseconds*/

alert ("done");

But in this time IMHO the script is always activ and you cannot work in PS meantime, sorry.