• 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
Re: Scripting alerts
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Scripting alerts


  • Subject: Re: Scripting alerts
  • From: Shane Stanley <email@hidden>
  • Date: Wed, 19 Nov 2014 23:55:37 +1100

Extra buttons and suppression buttons are well and good, but things get more interesting when you start adding accessory views. This is similar to how it is done in open and save panels, except they appear above the buttons.

Different controls have different properties, and there are different ways of creating and positioning them. This script will use a label next to a popup menu.

For a label, you want an NSTextField. You create it using alloc and initWithFrame:. This creates it and sets its frame -- its position and size, known as an NSRect -- at the same time. Setting the position can be a bit of trial and error, but in this case we will start with an x coordinate of 0, a y coordinate of 8 (y 0 is at the bottom), a width of 200 and a height of 20. 

The properties we set are whether it is in a box (setBordered:), whether the user can edit it (setEditable:), whether it draws a background (setDrawsBackground:), and its text (setStringValue:). We also set it's alignment so it appears next to the popup -- this is pretty rough positioning, but it will do for now.

For the popup menu, we create an NSPopUpButton similarly, with an extra parameter, pullsDown -- this sets whether the menu pops up or drops down with a fixed title. Then all we need to do is add a list of names for the menu's items.

Next we make the accessory view itself, an NSView, and add the controls to it. Again, the sizes are a bit arbitrary. And we pass it to the displayAlert handler, to add to the alert. To make this handler more flexible, it will not try to add an accessory view if it is passed missing value instead of a view.

Once the view has been dismissed, we ask for the popup's selectedTitleOfChoice.

Ideally this should all be done in handlers, but first off it's probably a bit easier to follow if it's done in a bit more linear fashion.

So here is the code, and again it needs to be run in the foreground:

use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"

-- check we are running in foreground
if not (current application's NSThread's isMainThread()) as boolean then
display alert "This script must be run from the main thread." buttons {"Cancel"} as critical
error number -128
end if

-- for styleNum, 0 = warning, 1 = informational, 2 = critical; for givingUpAfter, 0 means never; accessoryView of missing value means none
on displayAlert:mainText message:theExplanaton asStyle:styleNum buttons:buttonsList suppression:showSuppression givingUpAfter:giveUp accessoryView:theView
set buttonsList to reverse of buttonsList -- because they get added in reverse order cf AS
-- 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:theExplanaton
repeat with anEntry in buttonsList
(its addButtonWithTitle:anEntry)
end repeat
its setShowsSuppressionButton:showSuppression
if theView is not missing value then its setAccessoryView:theView
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
return {buttonName, suppressedState}
end displayAlert:message:asStyle:buttons:suppression:givingUpAfter:accessoryView:

-- The accessory view will have a label followed by a popup menu
set theLabelText to "Choose a value from:"
-- rect values are trial and error for x, y, width, height, with y = 0 at the bottom
set theLabel to current application's NSTextField's alloc()'s initWithFrame:(current application's NSMakeRect(0, 8, 200, 20))
tell theLabel
its setStringValue:theLabelText
its setEditable:false
its setBordered:false
its setDrawsBackground:false
its setAlignment:(current application's NSRightTextAlignment)
end tell
-- create a popup to the right of the label
set thePopUp to current application's NSPopUpButton's alloc()'s initWithFrame:(current application's NSMakeRect(200, 10, 100, 20)) pullsDown:false
thePopUp's addItemsWithTitles:{"One", "Two", "Three", "Four"}
-- create a view and add items
set theView to current application's NSView's alloc()'s initWithFrame:(current application's NSMakeRect(0, 0, 400, 40))
theView's setSubviews:{thePopUp, theLabel}
-- pass the view to the alert handler
set {buttonName, suppressedState} to (my displayAlert:"This is a dialog" message:"And this is the 9 o'clock news." asStyle:2 buttons:{"Cancel", "Maybe", "Possibly", "Probably", "OK"} suppression:false givingUpAfter:20.0 accessoryView:theView)
set popupChoice to thePopUp's titleOfSelectedItem() as text
return {buttonName, popupChoice, suppressedState}


-- 
Shane Stanley <email@hidden>
<www.macosxautomation.com/applescript/apps/>

 _______________________________________________
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: Scripting alerts
      • From: Shane Stanley <email@hidden>
References: 
 >Scripting alerts (From: Shane Stanley <email@hidden>)
 >Re: Scripting alerts (From: Shane Stanley <email@hidden>)
 >Re: Scripting alerts (From: Shane Stanley <email@hidden>)

  • Prev by Date: Re: is Shane's advice being collated?
  • Next by Date: Re: Scripting alerts
  • Previous by thread: Re: Scripting alerts
  • Next by thread: Re: Scripting alerts
  • Index(es):
    • Date
    • Thread