Page 1 of 4

UI progressbar example

Posted: Thu Jan 04, 2007 11:57 pm
by Holograph
No problem Patrick. Thanks to you for getting us all started on the topic!

UI progressbar example

Posted: Sun Jun 17, 2007 2:17 pm
by xbytor
Here's my contribution to this thread.

Code: Select all//
// createProgressWindow
//   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)
//   
//   onCancel  This method will be called when the Cancel button is pressed.
//             This method should return 'true' to close the progress window
//
function createProgressWindow(title, min, max, parent, useCancel) {
  var win = new Window('palette', title);
  win.bar = win.add('progressbar', undefined, min, max);
  win.bar.preferredSize = [300, 20];

  win.parent = undefined;

  if (parent) {
    if (parent instanceof Window) {
      win.parent = parent;
    } else if (useCancel == undefined) {
      useCancel = parent;
    }
  }

  if (useCancel) {
    win.cancel = win.add('button', undefined, 'Cancel');
    win.cancel.onClick = function() {
      try {
        if (win.onCancel) {
          var rc = win.onCancel();
          if (rc || rc == undefined) {
            win.close();
          }
        } else {
          win.close();
        }
      } catch (e) {
        alert(e);
      }
    }
  }

  win.updateProgress = function(val) {
    var win = this;
    win.bar.value = val;
    // recenter the progressWindow if desired
    // win.center(win.parent);
    win.show();
    win.hide();
    win.show();
  }
  win.center(win.parent);
  return win;
};


And here's an example of how it would be used:


Code: Select all  // we have to process an array of files

  var progressWindow = createProgressWindow("Progress...",
                                            0, files.length, true);
  progressWindow.isDone = false;
  progressWindow.onCancel = function() {
    this.isDone = true;
    return true;  // return 'true' to close the window
  }

  try {
    for (var i = 0; i < files.length; i++) {
      if (progressWindow.isDone) {
        break;
      }
      progressWindow.text = ("Processing file " + (i+1) + " of " + files.length + "...");
      progressWindow.updateProgress(i);

       // now process the next file
       processFile(files);
    }
  } catch (e) {
    alert(e);

  } finally {
    progressWindow.close();
  }


The big addition here is the Cancel button. This lets us use the progress window to stop processing prematurely.

I'll be adding this to GenericUI in xtools.

Edit:
I've added this functionality to CSX and tested it in both CS2 and CS3. I have not yet tested this on the Mac...

-X

UI progressbar example

Posted: Mon Jun 18, 2007 5:58 am
by Holograph
Hey X,

Nice work...it's really clean code.

I actually have a related question. The cancel button...does it really cancel the script? If so, how? That would be useful. I know you can cancel the current process by hitting escape during any script run, but if it's in a big loop or something, it will only cancel the current loop iteration.

Along those lines, it is possible to override the Esc key cancel functionality to make a full hard break or something (to ensure an immediate full cancel of any script process)?

Thanks in advance.

-Brian-

UI progressbar example

Posted: Mon Jun 18, 2007 11:50 am
by xbytor
Holograph wrote:Nice work...it's really clean code.

Thanks. After seeing variants of the idea a few times, writing it was pretty easy.

I actually have a related question. The cancel button...does it really cancel the script? If so, how? That would be useful. I know you can cancel the current process by hitting escape during any script run, but if it's in a big loop or something, it will only cancel the current loop iteration.

The Cancel button, as it's used in the sample code, only stops the loop where it's used. That's what this code does:

Code: Select all      if (progressWindow.isDone) {
        break;
      }


The JS interpreter is apparently interleaving the onClick function with the loop so I'm able to set the progressWindow.isDone variable to true asynchronously. And this is the perfect use of that capability. I really needed something like this in CSX so I"m glad I was able to get this all worked out.

Along those lines, it is possible to override the Esc key cancel functionality to make a full hard break or something (to ensure an immediate full cancel of any script process)?

As far as I can tell, the only way to immediately terminate the execution of a script is to have the script reach completion (as is normally the case) or to shutdown Photoshop completely ala File->Quit. There is no other mechanism, unless you want to use

Code: Select all$.level = 1; debugger;

to dump the user into the debugger. But, as with the File->Quit event, you have to be at a known place in the script in order to do this.

-X

UI progressbar example

Posted: Mon Jun 18, 2007 5:12 pm
by Holograph
Thanks X. I kinda thought I'd explored all possible options to do it neatly/cleanly (exit on Esc no matter where it's at within the script), but I thought it was worth asking you.

-Brian-

UI progressbar example

Posted: Mon Jan 28, 2008 9:49 pm
by Larry Ligon
Xbytor,

Your function and example code causes my Photoshop window to flicker really bad! Is that how it works?

UI progressbar example

Posted: Mon Jan 28, 2008 11:49 pm
by xbytor
What OS/PS versions is this happening on?

-X

UI progressbar example

Posted: Tue Jan 29, 2008 5:22 pm
by Larry Ligon
I'm using Photoshop CS3 on Windows XP.

Also, where is the function :
// now process the next file
processFile(files);

The Photoshop CS3 documentation states that Photoshop CS3 does not support 'palette"! How does this work?

Also, the 'cancel' button doesn't work.

UI progressbar example

Posted: Tue Jan 29, 2008 11:24 pm
by xbytor
I'll try to put together a more fully functional demo.

This code is actually the basis for the progress bar that's in CSX v1.3, if you want to see what it looks like in a production script.

-X

UI progressbar example

Posted: Thu Jul 09, 2009 3:56 pm
by Patrick
I did some more work with this and thought I would share what I used. I have a script that loops through all the layers in a layerset and exports them one by one. Below snippit will determine the right % to jump to based on the total number of steps, and animate the bar for every progression.

Code: Select all// build window to show progress
var win = new Window("palette{text:'Export .tif files for catalog',bounds:[100,100,860,170],\
panel0:Panel{bounds:[5,5,755,65] , text:'' ,properties:{borderStyle:'black',su1PanelCoordinates:true},\
    progbar1:Progressbar{bounds:[5,5,740,50] , value:0,maxvalue:100}\
}\
};");

// show palette
win.center();
win.show();

// function to grow the progress bar
function animate(bar, end)
{   

    var p = bar.value;

    while (p <= end) {
       bar.value = p;
       p++;
       $.sleep(10);
    };
}

// incriment per image
var progress = 100 / (docRef.layerSets['alts'].layers.length);

// grow progress meter by one incriment
animate(win.panel0.progbar1, win.panel0.progbar1.value + progress);   

Patrick