How do I cancel a window containing a NSProgress Indicator - NSTask ?

HI,

I’m trying to create a simple progress bar that also includes a Cancel button.
The as-is code to create the progress bar is shown below.

The issue that I am encountering is that the Cancel button does not activate when I run the script, therefore making it impossible for a user to cancel the progress.

To my limited understanding… I’m thinking that the problem is caused because the main loop() which updates the progress indicator runs on the main thread, therefore the cancel button handler cannot be fired.

What do I need to do so that the user can stop the script at any time by clicking the Cancel button?

I have tried adding the following code in an attempt to create a separate thread:

set theTask to current application's (NSTask's alloc)'s init()

…to above the line in the code below reading:

repeat with i from 1 to 20

and then wrapping the subsequent repeat loop in a

Tell theTask

statement.

This didn’t fully work. By adding the code above the cancel button can now be fired at any time, however, the progress bar only increments once and then stops.

Any advice or pointers on how to rectify this is much appreciated.

Best Regards, Rob.

-------- current script below -----------

script progressAppDelegate
	 property parent : class "NSObject"
	 property progressWindow : missing value
	 property progressBar : missing value
	 property currentProgressText : missing value
	 property cancelButton : missing value
	
	 on applicationDidFinishLaunching_(aNotification)
		progressWindow's makeKeyAndOrderFront_(me) --bring the window to front
		setCurrentProgressText_("Configuring settings...") --set the text in the window
                --Configure the progress bar
		tell progressBar
			setMinValue_(0)
			setMaxValue_(20)
			setIndeterminate_(true)
			setUsesThreadedAnimation_(true)
			startAnimation_(progressBar) --Spin the barbers pole for a second
			delay 1
			stopAnimation_(progressBar) --Stop spinning the barbers pole.
			setIndeterminate_(false) --switch back to an indeterminate progress bar.
		end tell
		loop() --start incrementing the progress bar.
	end applicationDidFinishLaunching_
	
	 on loop()
		repeat with i from 1 to 20
			delay 0.15
			progressBar's setDoubleValue_(i) --increment the progress bar.
			setCurrentProgressText_("Processing image: " & i & " of " & "20" as string) --update the text
		end repeat
		delay 0.5	
		tell me to quit
	end loop
	

	on cancelProgress_(sender)
		tell me to quit -- when the cancel button is clicked quit quit the program
	end cancelProgress_
	
end script

For indeterminate progress indicators, you just use startAnimation: and stopAnimation: – you don’t have to worry about setting values.

And don’t use delay like that – it just hogs the main thread. Use performSelector:withObject:afterDelay: or a timer. That way your app is free to respond to button clicks.