Blog Archives
applescript: many buttons
Posted by philastokes

I thought I’d share some code Shane Stanley wrote in response to a question I posed on ASUsers list a few weeks back. Both Shane and myself have modified that original answer, which wasn’t directly about how to display a dialog with more than three buttons like this.
This should work on all versions of OS X / macOS from 10.10 Yosemite onwards and produce something like the screenshot above. Obviously, you’ll want to adapt the size, message and buttons to fit your own circumstances. The parts you need to edit are near the end and begin with the commented line ‘set up the paramaters…’.
The script is helpfully peppered with notes but if you get stuck, just drop a question in the Comments below.
STARTuse AppleScript version "2.4" -- 10.10 or lateruse framework "Foundation"use framework "AppKit"use framework "Carbon" -- AEInteractWithUser() is in Carbonuse scripting additionsproperty returnCode : missing valueon showMessage:theMessage withTitle:boldBit textFrame:textFieldSize textMaxWidth:maxWidth withButtons:buttonsList# credit to Shane Stanley for this handler-- make attributed string system font with monospaced digitsset fontSize to current application's NSFont's systemFontSizeForControlSize:(current application's NSRegularControlSize)set theFont to current application's NSFont's systemFontOfSize:fontSizeset attsDict to current application's NSDictionary's dictionaryWithObject:theFont forKey:(current application's NSFontAttributeName)set attString to current application's NSAttributedString's alloc()'s initWithString:theMessage attributes:attsDict-- make a text field to hold the messageset theField to (current application's NSTextField's alloc()'s initWithFrame:textFieldSize)tell theField(its setEditable:false)(its setBordered:false)its setDrawsBackground:falseits (cell()'s setWraps:true)its setPreferredMaxLayoutWidth:maxWidthits setAttributedStringValue:attStringend tell-- make it fit; needs to be done on the main threadmy performSelectorOnMainThread:"fitToSizeView:" withObject:theField waitUntilDone:true-- make sure we have permissionset theError to current application's AEInteractWithUser(-1, missing value, missing value) -- -1 is kAEDefaultTimeoutif theError is not 0 then error "User interaction disallowed" number theError-- create an alertset theAlert to current application's NSAlert's alloc()'s init()tell theAlertits setMessageText:boldBitrepeat with anEntry in buttonsList(its addButtonWithTitle:anEntry)end repeatits setAccessoryView:theFieldend tell-- show the alert; needs to be done on the main threadmy performSelectorOnMainThread:"showTheAlert:" withObject:theAlert waitUntilDone:trueset buttonNumber to returnCode mod 1000 + 1 -- where 1 = right-most buttonset buttonName to item buttonNumber of buttonsListreturn buttonNameend showMessage:withTitle:textFrame:textMaxWidth:withButtons:on showTheAlert:theAlert# credit to Shane Stanley for this handler-- check we are running in foregroundif not (current application's NSThread's isMainThread()) as boolean then error "This handler must be called on the main thread." from current applicationset my returnCode to theAlert's runModal()end showTheAlert:on fitToSizeView:aView# credit to Shane Stanley for this handleraView's setFrameSize:(aView's fittingSize())end fitToSizeView:# set up the parameters for the showMessage call:set theMessage to "How many buttons would you like? There's no real limit except for practical and aesthetic considerations." & return & "Of course, I hope you'll never really think about using something as ugly as this!" & return & return & "Choose your heart out!"set theTitle to "Many Buttons"# increase or decrease the second item's numbers# to fit larger or smaller amounts of text# the '650' here is the text field's width# the '80' is its heightset theTextFieldSize to {{0, 0}, {650, 80}}set buttonsToDisplay to {"OK", "Five", "Four", "Three", "Two", "One", "Cancel"}set theButtonReturned to its showMessage:theMessage withTitle:theTitle textFrame:theTextFieldSize textMaxWidth:(650) withButtons:buttonsToDisplayEOF
Enjoy 🙂
