Copy link to clipboard
Copied
I have a few scripts that take quite a long time to execute (15 seconds typically) and I would like to display some sort of Waiting message (change cursor to hourglass for example).
I can change the tool to something like the Hand tool while the script is executing and then change it back to the selected tool ... which is sort of OK but not exactly very user-friendly (the Hand tool itself could well have already been selected!)
Thanks
Robert
Here is code that I have used in one form another for close to a decade. It is also used in releases of ImageProcessorPro and CSX so it has been fairly well vetted.
//
// Function: createProgressPalette
// Description: Opens up a palette window with a progress bar that can be
// 'asynchronously' while the script continues running
// Input:
// title the window title
// min the minimum value for the progress bar
// max the maximum value for the progress bar
// parent
Copy link to clipboard
Copied
Search for a script that displays a progress bar.
https://forums.adobe.com/search.jspa?place=%2Fplaces%2F1383833&sort=updatedDesc&q=progress+bar
Copy link to clipboard
Copied
Thanks ... but doProgress is not available pre CC2015 (I think) and my customers use everything from CS upwards.
Copy link to clipboard
Copied
I do not know when the support was added to Photoshop scripting. CS is 13 years old and many features have been added to Photoshop scripting since then. Also some old scripting bugs have been fixed after CS. Scripting was a PS 7 optional Plug-in and CS was the first release to have scripting. If you want to use scripting you should move to a newer version of Photoshop CS6 or a creative cloud subscription.
Some on my scripts test Photoshop version to code around CS2 scripting bugs. I have also coded some Plug-ins scripts. These can not be used in version of Photoshop prior to CS3. There are new bugs in CC 2015.5 and CC 2017 scriting.
Copy link to clipboard
Copied
Unfortunately I can't dictate to my customers what version of Photoshop to use ... although very few are on pre-CS5. But I do need to cater for CS6 users and doProgress isn't available on CS6. I do check for the Photoshop version and if I had an alternative that worked for CS6 ... CC2014 then I would use that and use doProgress for newer versions.
Copy link to clipboard
Copied
Then you script would needs to test which version of Photoshop the users is using. If a new version provide a progress bar. Old version of Photoshop you may be able to provide an audible progress signal like a beep every so often. Your script can easily test which Photoshop version running. When I use the Image Processor Pro Plug-in script I see a progress bar in CC 2015 the progress in CS6, CC and CC 2014 I see a progress bar that does not progress one that just goes away. You need a solution available for the different Photoshop Script plug-in versions.
Copy link to clipboard
Copied
Here is code that I have used in one form another for close to a decade. It is also used in releases of ImageProcessorPro and CSX so it has been fairly well vetted.
//
// Function: createProgressPalette
// Description: Opens up a palette window with a progress bar that can be
// 'asynchronously' while the script continues running
// Input:
// title the window title
// min the minimum value for the progress bar
// max the maximum value for the progress bar
// parent the parent ScriptUI window (opt)
// useCancel flag for having a Cancel button (opt)
// msg message that can be displayed and changed in the palette (opt)
//
// onCancel This method will be called when the Cancel button is pressed.
// This method should return 'true' to close the progress window
// Return: The palette window
//
function createProgressPalette(title, min, max,
parent, useCancel, msg) {
var opts = {
closeButton: false,
maximizeButton: false,
minimizeButton: false
};
var win = new Window('palette', title, undefined, opts);
win.bar = win.add('progressbar', undefined, min, max);
if (msg) {
win.msg = win.add('statictext');
win.msg.text = msg;
}
win.bar.preferredSize = [500, 20];
win.parentWin = undefined;
win.recenter = false;
win.isDone = false;
if (parent) {
if (parent instanceof Window) {
win.parentWin = parent;
} else if (useCancel == undefined) {
useCancel = !!parent;
}
}
if (useCancel) {
win.onCancel = function() {
this.isDone = true;
return true; // return 'true' to close the window
};
win.cancel = win.add('button', undefined, localize("$$$/JavaScripts/psx/Cancel=Cancel"));
win.cancel.onClick = function() {
var win = this.parent;
try {
win.isDone = true;
if (win.onCancel) {
var rc = win.onCancel();
if (rc != false) {
if (!win.onClose || win.onClose()) {
win.close();
}
}
} else {
if (!win.onClose || win.onClose()) {
win.close();
}
}
} catch (e) {
LogFile.logException(e, '', true);
}
};
}
win.onClose = function() {
this.isDone = true;
return true;
};
win.updateProgress = function(val) {
var win = this;
if (val != undefined) {
win.bar.value = val;
}
// else {
// win.bar.value++;
// }
if (win.recenter) {
win.center(win.parentWin);
}
win.update();
win.show();
// win.hide();
// win.show();
};
win.recenter = true;
win.center(win.parent);
return win;
};
Copy link to clipboard
Copied
Many thanks! I'll give your script a go. A couple of questions:
- is the only way of ending the progress palette to terminate the script (or for the user to press cancel)? The reason I ask is that my script handles several separate longish tasks with user input in between the tasks. I would like to have the progress palette show for each one separately. I guess I could make createProgressPalette as a class...
- would it be asking too much for you to give me an example of calling the function? It might save me quite a bit of messing. This seems to be the minimum: createProgressPalette("Please Wait", min, max,,, ) ... but i'm not sure what min and max values are for.
Thanks!
Robert
Copy link to clipboard
Copied
It's used in ImageProcessorPro (ps-scripts - Browse /Image Processor Pro/v3_2 betas at SourceForge.net). It's actually used twice in the script: once for startup window creation, the other for iteration over the file being processed. The latter is probably of most interest.
You don't really need to create a class. It's a function that creates a 'palette' window that I've added stuff to. When you are done with it, just close it.
Copy link to clipboard
Copied
Many thanks ... the function works very well. My only issue is that it flickers during execution. Is there any way to prevent this?
This is how I've used the function:
win = createProgressPalette("In progress", 1,100,null, false,null) ;
for(j = 1; j < 100; j++){
if(j===parseInt(j,10)) win.updateProgress(j);
// do something
}
I'm only calling updateProgress every 10th iteration to reduce flickering.
Thanks
Robert
Copy link to clipboard
Copied
To avoid flickering You may add refresh() (Ps must be turned on) to your function, but unfortunately it's going to slow down the process about 100 times
win = createProgressPalette("In progress", 1,100,null, false,null) ;
for(j = 1; j < 100; j++) if (j == parseInt(j, 10)) win.updateProgress(j), refresh()
Copy link to clipboard
Copied
I think I'll put up with the flickering!
Copy link to clipboard
Copied
You may also be able to speed up the execution of your scripts by toggling Photoshop Palettes off so Photoshop does not need to update them while your script run. Reducing the number of Photoshop steps your script does will also help. Shorten the code path length or use a faster method. Action Manager code may perform better then DOM code in places.
Copy link to clipboard
Copied
Action Manager code will perform better then DOM code in all places.
FTFY
Copy link to clipboard
Copied
Thanks ... I hadn't thought about closing panels