Demo of a Real Progress Bar for JXA using ASObjC Runner app

Demo of a Real Progress Bar for JXA using ASObjC Runner app

Although Apple provided a so-called “Progress Bar” for scripting in Yosemite, it is, IMO, not really usable. It doesn’t provide what most users would expect: A visible small window showing the progress.

Long before Yosemite, Shane Stanley wrote the ASObjC Runner app, and many other very useful ASObjC apps and scripts.

I have taken the code provided at MacOSXAutomation.com, and converted it to JXA, and put the reusable code into functions.

It seems to work well, although I have NOT given it extensive testing. If you find any issues or bugs, or have suggestions for improvement, please feel free to post below. I am new to JXA, and I’m sure there are things that could be done in a better way.

My eternal thanks to Shane for all that he has provided, and all of the support he provides in this forum.

Here’s what the Progress Bar looks like:


/*
==============================================================================
PURPOSE:  Show how to display real Progress Bar using ASObjC Runner app in JXA
					¢ Redesigned to use FUNCTIONS

VER:	2.0		DATE:  Tue, Jan 12, 2016

AUTHOR: JMichaelTX 
        Please PM me with any bugs/issues/questions
				
	  ¢ All of the credit for this functionality goes to Shane Stanley,
		  who wrote the ASObjC Runner app, and many other incredible ASObjC apps
			and libraries
		¢ My only real contribution is in putting this in functions, and
		  converting to JXA
			
REF:  	http://www.macosxautomation.com/applescript/apps/runner_vanilla.html

SHARED ONLINE:
	1.  AppleScript version was posted to MacScripter on Mon, May 18, 2015
		http://macscripter.net/viewtopic.php?pid=180778#p180778

REQUIRES:
	1.  Mac OS X Mavericks, or later
	2.  ASObjC Runner app (see free download below)
	2.  ProgressBar Functions (included below)
		1.  initProgressBar(psTitle, psMsg, piMax, piCurrent)
		2.  updateProgressBar(piCurrent, piMax)
		3.  closeProgressBar()

The free ASObjC Runner app may be downloaded from:
http://www.macosxautomation.com/applescript/apps/ASObjC_Runner.zip

Previously, there was no good way to show a standard progress bar from AppleScript.  
Yosemite adds a Progress Bar to AppleScript & JXA, but it is very poor, IMO.
This ASObjC Progress Bar is much, much better.
Also, it provides a solutoin for Mavericks.

This script provides a demo of the ASObjC Runner Progress Bar.  I adapted the 
demo code from MacOSXAutomation.com to use functions, and to convert to JXA.
===============================================================================
*/
var app = Application.currentApplication()
app.includeStandardAdditions = true

var sPBStatus = "TBD" // Will be set to "Cancel" if User Cancels.  Otherwise set to "OK"

//--- VARIABLES TO BE SET IN YOUR SCRIPT ---
var sPBTitle 	= "ASObjC Runner Progress Bar" 					//-- Window Title
var sPBMsg 		= "DEMO Progress Bar by ASObjC Runner" 	//-- Msg ABOVE progress bar

//--- FOR DEMO ONLY ---
var iStart = 1
var iEnd = 50
//---------------------------------------------

// *** INITIALIZE PROGRESS BAR ***
initProgressBar(sPBTitle, sPBMsg, iEnd, 0)

//--- REPLACE with your own LOOP ---

for (var iCurrent = iStart; iCurrent <= iEnd; iCurrent++) {
		
	//	-- *** UPDATE PROGRESS BAR JUST BEFORE YOUR PROCESSING ***
		var sPBStatus = updateProgressBar(iCurrent, iEnd)
		
	//	-- HANDLE CANCEL BY USER --
	
		if (sPBStatus === "Cancel") {
			break;
		} //“““ end if “““
		
	//	--- INSERT YOUR PROCESSING HERE --
		delay(0.1)		// for demo only, not needed in production use
		
} //“““ END for “““

//-- *** CLOSE PROGRESS BAR ***
closeProgressBar()

//--- HANDLE ANY CLEANUP IF USER CANCELED ---

if (sPBStatus === "Cancel") {

	app.displayNotification ("User CANCELED process", {title: sPBTitle})
	
	//	-- YOUR CODE HERE --

} else {

	app.displayNotification ("Process SUCCESSFULLY Completed", {title: sPBTitle})
	
} //“““ end if User Canceled “““


//===================== END OF MAIN SCRIPT ===============

//“““““““““““““““““““““““““““““““““““““““““““““““““““““““““
//		FUNCTIONS
//“““““““““““““““““““““““““““““““““““““““““““““““““““““““““

/*
“““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““
ASObjC Runner FUNCTIONS

	AUTHOR: JMichaelTX 
	REF:  	http://www.macosxautomation.com/applescript/apps/runner_vanilla.html
	
	CREDIT:
	  ¢ All of the credit for this functionality goes to Shane Stanley,
		  who wrote the ASObjC Runner app, and many other incredible ASObjC apps
			and libraries
		¢ My only real contribution is in putting this in functions, and
		  converting to JXA
“““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““
*/

//”””””””””””””””””””””””””””””””””””””””””””””””””””””””””””””
function initProgressBar(psTitle, psMsg, piMax, piCurrent) {
//”””””””””””””””””””””””””””””””””””””””””””””””””””””””””””””
	/*
	PURPOSE:  Initialize the ASObjC Runner Progress Bar	
	VER:  		2.0			DATE:  Tue, Jan 12, 2016
	
	-- NOTE:  The "name" and "message" properties need to be set only here.
	--			They will continue to show when the UPDATE is called 
	--			without being included in the properties there.
	*/
	//““““““““““““““““““““““““““““““““““““““““““““““““““““““““““
	
	var ASORun = Application("ASObjC Runner")
	
	ASORun.resetProgress()
	
	ASORun.progressWindow.properties = {
			buttonTitle:			"Cancel"
			, buttonVisible:	true
			, name:						psTitle
			, message:				psMsg
			, detail:					""
			, indeterminate:	false
			, maxValue:				piMax
			, currentValue:		piCurrent
		}
	
	ASORun.showProgress()
	
} //“““““““““ END function initProgressBar “““““““““““““““““““

//”””””””””””””””””””””””””””””””””””””””””””””””””””””””””””””
function updateProgressBar(piCurrent, piMax) {
//”””””””””””””””””””””””””””””””””””””””””””””””””””””””””””””
	/*
	PURPOSE:  UPDATE the ASObjC Runner Progress Bar	
	VER:  		2.0			DATE:  Tue, Jan 12, 2016
	*/
	//““““““““““““““““““““““““““““““““““““““““““““““““““““““““““
	
	var ASORun = Application("ASObjC Runner")
	
	ASORun.progressWindow.properties = {
			detail:("This is number " + piCurrent + " of " + piMax)
			, currentValue:piCurrent
		}
				
		if (ASORun.progressWindow.buttonWasPressed()) {
			return "Cancel";
		} else {
			return "OK";
		}
		

} //““““““““  END function updateProgressBar “““““““““““““

//”””””””””””””””””””””””””””””””””””””””””””””””””””””””””””””
function closeProgressBar() {
//”””””””””””””””””””””””””””””””””””””””””””””””””””””””””””””
	/*
	PURPOSE:  HIDE the ASObjC Runner Progress Bar	
	VER:  		2.0			DATE:  Tue, Jan 12, 2016
	*/
	//““““““““““““““““““““““““““““““““““““““““““““““““““““““““““
	
	var ASORun = Application("ASObjC Runner")
	ASORun.hideProgress()

} //““““““““““““  END function closeProgressBar “““““““““““““““

Nice example code Micheal!

Like your csv example code, these kind of posts should be posted in ‘Code Exchange’

Nice :slight_smile: Let me point out a couple of things:

  • ASObjC Runner still works, but it’s unsupported and will not run beyond OS X 10.11.x.

  • Apple’s progress properties do provide a window when used in applets. Unfortunately the Cancel button it provides is a disaster in 10.10.

Thanks for pointing that out. Maybe by the time 10.12 is released, Apple will have provided us with a real progress bar that works in scripts.

Shane, you have published several ASObjC libraries, some that suggest they provide the same capability as ASObjC Runner. Could one of those be used to produce the progress bar, and would continue to work beyone OS X 10.11?

Thanks, I should have mentioned that. However, there is NOT a real progress bar when just running a script. In fact, you have to look very close to even notice any progress info at all. Most of my use cases are just scripts. I rarely have a need to create an applet.

Sorry about that. Please feel free to move this thread to the appropriate forum.

May be an useful addition to BridgePlus.

Yvan KOENIG running El Capitan 10.11.2 in French (VALLAURIS, France) jeudi 14 janvier 2016 20:45:43

Problem remains that progress bars works asynchronously and work parallel to the executed task which updates the indicator. This doesn’t fit with the design of AppleScript. Also StefanK has written a background application to show progress indicators and is fully scriptable.

DJ has summarized it well.

I still have an idea or two, because dedicated apps don’t share well, but I have to say it’s a low priority.

I’m not sure I understand that, since the ASObjC Runner progress bar seems to work fine.
The Apple Yosemite progress bar works if you create an applet.
So, what’s the issue?

If you are referring to SKProgressBar 1.0, a fully scriptable progress bar, it hasn’t been updated since 2013, so I have no idea if it is compatible with Yosemite or El Capitan. It also appears to have significant issues. Based on the comments below, I decided to not even consider it.

So, let me ask you guys, what are using today for a progress bar in AppleScript and JXA?

Today, ASObjC Runner works.

Yvan KOENIG running El Capitan 10.11.2 in French (VALLAURIS, France) vendredi 15 janvier 2016 09:37:32

To avoid any confusion lets make clear from what I understand from you saying “a real progress bar” in AppleScript. It would mean that when used in any application context it would show the progress indicator in that particular application it is called from. So when the progress indicator is used in the Finder context it should be shown in the Finder application right?

To make it support for every application like a display dialog or activate command would mean it has to be send as an AppleEvent. In that case the application class has to support a new type of AppleEvent next to open, reopen, etc. or it has to be written in an scripting addition and loaded into the process when the AppleEvent is send to it. No matter how you implement it, it should be handled by one single AppleEvent and not by a series of instructions like it is working in your applet now. That would mean that during the time of showing the progress indicator your script is waiting for the event to be finished and you can do nothing.

The fact that AppleScript engineers has chosen to define progress bar properties in AppleScript’s global namespace (read: properties of the AppleScript object) says it all, it’s both the most odd and obvious choice to put it there.

Your choice of course I’m just mentioning it because ASObjC is officially unsupported while StefanK’s progress indicator is not. I understand your arguments not to use it but they are based on feelings rather than facts.

UPDATE: StefanK has updated his SKProgressIndicator today :slight_smile:

It’s one of the reasons I don’t use JXA while I love the true JavaScript language.

Just to be clear: if you ignore the non-progress related stuff ASObjC Runner does, it’s just another faceless-background app like Stefan’s. My personal feeling is that it’s better if we try to use common tools if possible, for reasons like trouble-shooting and avoiding duplication of effort, so as long as Stefan’s app is working, I don’t see any point in my writing one.

I assume Stefan is using auto-layout to make his automatically resize, and so on.

Honestly I am not but the autoresizing masks are set accordingly.

I don’t get this. The issue with the progress bar is the same for either AppleScript or JXA.
So, how could it be a rationale for choosing one or the other?