• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Modifying Library to Run NSAlert on main thread
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Modifying Library to Run NSAlert on main thread


  • Subject: Modifying Library to Run NSAlert on main thread
  • From: "Jacob M. Small" <email@hidden>
  • Date: Wed, 20 Jul 2016 08:56:33 -0400

I’m using Dialog Toolkit 1.0.3 by Shane Stanley. But I’m writing in Script Debugger 6, which is problematic because the Dialog Toolkit commands need to be run on the main thread, which Script Debugger 6 doesn’t seem to support yet. 

So I’m trying to adapt the approach in Chapter 26 of Everyday AppleScriptObjC for ensuring that Dialog Toolkit’s handler that creates the NSAlert is always run on the main thread.

For this, I’m kind of bumbling around in the dark, as ASObjC is pretty new to me. I’ll paste the handler twice below, first prior to my edit and then with the edit suggested in Everyday AppleScriptObjC. My question is whether my modification will permanently remove the need for me to be concerned about using this library on the main thread, or if I need to find a different approach.

The modification is after the tell block for theAlert. I’ve just added its performSelectorOnMainThread:"displayAlert:" withObject:theAlert waitUntilDone:true within the handler. I’m asking because I don’t quite understand yet what this is doing, just following the book’s instructions.

Original handler in Dialog Toolkit 1.0.3:

on displayAlert:mainText message:theExplanation asStyle:styleNum buttons:buttonsList suppression:showSuppression givingUpAfter:giveUp AVWidth:theWidth AVHeight:theHeight AVControls:controlsList
-- check we have the OK
set theResult to (current application's AEInteractWithUser(-1, missing value, missing value)) as integer
if theResult is not 0 then error "Unable to show dialog (AEInteractWithUser() failed)."
-- make the accessory view
set theAccessoryView to current application's NSView's alloc()'s initWithFrame:(current application's NSMakeRect(0, 0, theWidth, theHeight))
theAccessoryView's setSubviews:controlsList
-- reverse buttons because they get added in reverse order cf AS
set buttonsList to reverse of buttonsList
-- create an alert
set theAlert to current application's NSAlert's alloc()'s init()
-- set up alert
tell theAlert
its setAlertStyle:styleNum
its setMessageText:mainText
its setInformativeText:theExplanation
repeat with anEntry in buttonsList
(its addButtonWithTitle:anEntry)
end repeat
its setShowsSuppressionButton:showSuppression
its setAccessoryView:theAccessoryView
its (|window|()'s setAutorecalculatesKeyViewLoop:true)
end tell
-- if giveUp value > 0, tell the app to abort any modal event loop after that time, and thus close the panel
if giveUp > 0 then current application's NSApp's performSelector:"abortModal" withObject:(missing value) afterDelay:giveUp inModes:{current application's NSModalPanelRunLoopMode}
-- show alert in modal loop
set returnCode to theAlert's runModal()
-- if a giveUp time was specified and the alert didn't timeout, cancel the pending abort request
if giveUp > 0 and returnCode is not current application's NSModalResponseAbort then current application's NSObject's cancelPreviousPerformRequestsWithTarget:(current application's NSApp) selector:"abortModal" object:(missing value)
-- get values after alert is closed
set suppressedState to theAlert's suppressionButton()'s state() as boolean
set buttonNumber to returnCode mod 1000 + 1 -- where 1 = right-most button
if buttonNumber = 0 then
set buttonName to "Gave Up"
else
set buttonName to item buttonNumber of buttonsList
end if
-- get values from controls
set controlResults to {}
repeat with aControl in controlsList
if (aControl's isKindOfClass:(current application's NSTextField)) as boolean then
set end of controlResults to aControl's stringValue() as text
else if (aControl's isKindOfClass:(current application's NSPopUpButton)) as boolean then
set end of controlResults to aControl's titleOfSelectedItem() as text
else if (aControl's isKindOfClass:(current application's NSButton)) as boolean then
set end of controlResults to aControl's state() as boolean
else if (aControl's isKindOfClass:(current application's NSPathControl)) as boolean then
set end of controlResults to aControl's |URL|()'s |path|() as text
else if (aControl's isKindOfClass:(current application's NSMatrix)) as boolean then
set end of controlResults to aControl's selectedCell()'s title() as text
else -- NSBox
set end of controlResults to missing value
end if
end repeat
return {buttonName, suppressedState, controlResults}
end displayAlert:message:asStyle:buttons:suppression:givingUpAfter:AVWidth:AVHeight:AVControls:

and as modified:

on displayAlert:mainText message:theExplanation asStyle:styleNum buttons:buttonsList suppression:showSuppression givingUpAfter:giveUp AVWidth:theWidth AVHeight:theHeight AVControls:controlsList
-- check we have the OK
set theResult to (current application's AEInteractWithUser(-1, missing value, missing value)) as integer
if theResult is not 0 then error "Unable to show dialog (AEInteractWithUser() failed)."
-- make the accessory view
set theAccessoryView to current application's NSView's alloc()'s initWithFrame:(current application's NSMakeRect(0, 0, theWidth, theHeight))
theAccessoryView's setSubviews:controlsList
-- reverse buttons because they get added in reverse order cf AS
set buttonsList to reverse of buttonsList
-- create an alert
set theAlert to current application's NSAlert's alloc()'s init()
-- set up alert
tell theAlert
its setAlertStyle:styleNum
its setMessageText:mainText
its setInformativeText:theExplanation
repeat with anEntry in buttonsList
(its addButtonWithTitle:anEntry)
end repeat
its setShowsSuppressionButton:showSuppression
its setAccessoryView:theAccessoryView
its (|window|()'s setAutorecalculatesKeyViewLoop:true)
end tell
its performSelectorOnMainThread:"displayAlert:" withObject:theAlert waitUntilDone:true
-- if giveUp value > 0, tell the app to abort any modal event loop after that time, and thus close the panel
if giveUp > 0 then current application's NSApp's performSelector:"abortModal" withObject:(missing value) afterDelay:giveUp inModes:{current application's NSModalPanelRunLoopMode}
-- show alert in modal loop
set returnCode to theAlert's runModal()
-- if a giveUp time was specified and the alert didn't timeout, cancel the pending abort request
if giveUp > 0 and returnCode is not current application's NSModalResponseAbort then current application's NSObject's cancelPreviousPerformRequestsWithTarget:(current application's NSApp) selector:"abortModal" object:(missing value)
-- get values after alert is closed
set suppressedState to theAlert's suppressionButton()'s state() as boolean
set buttonNumber to returnCode mod 1000 + 1 -- where 1 = right-most button
if buttonNumber = 0 then
set buttonName to "Gave Up"
else
set buttonName to item buttonNumber of buttonsList
end if
-- get values from controls
set controlResults to {}
repeat with aControl in controlsList
if (aControl's isKindOfClass:(current application's NSTextField)) as boolean then
set end of controlResults to aControl's stringValue() as text
else if (aControl's isKindOfClass:(current application's NSPopUpButton)) as boolean then
set end of controlResults to aControl's titleOfSelectedItem() as text
else if (aControl's isKindOfClass:(current application's NSButton)) as boolean then
set end of controlResults to aControl's state() as boolean
else if (aControl's isKindOfClass:(current application's NSPathControl)) as boolean then
set end of controlResults to aControl's |URL|()'s |path|() as text
else if (aControl's isKindOfClass:(current application's NSMatrix)) as boolean then
set end of controlResults to aControl's selectedCell()'s title() as text
else -- NSBox
set end of controlResults to missing value
end if
end repeat
return {buttonName, suppressedState, controlResults}
end displayAlert:message:asStyle:buttons:suppression:givingUpAfter:AVWidth:AVHeight:AVControls:
—
Jacob M. Small, Principal
J. Madison PLC
1750 Tysons Boulevard, Suite 1500
McLean, Virginia 22102
T 703.910.5062 F 703.910.5107
www.jmadisonplc.com





 _______________________________________________
Do not post admin requests to the list. They will be ignored.
AppleScript-Users mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:
Archives: http://lists.apple.com/archives/applescript-users

This email sent to email@hidden

  • Follow-Ups:
    • Re: Modifying Library to Run NSAlert on main thread
      • From: Shane Stanley <email@hidden>
  • Prev by Date: Re: need explanation for trivial Safari script behavior
  • Next by Date: Re: Modifying Library to Run NSAlert on main thread
  • Previous by thread: Re: Help for optimization of my script
  • Next by thread: Re: Modifying Library to Run NSAlert on main thread
  • Index(es):
    • Date
    • Thread