Your prescription for increased productivity and profitability
A new year. A new InDesign CC version (2017); and lots to talk about.
Whether you are new to working with scripts or an old hat, one thing that is for certain, almost every script you write will in some way need to communicate with the user.
The dialogs built into JavaScript and AppleScript have a limited user interface, and in the event you want more than one value returned, the Prompt dialog for JavaScript (Display Dialog for AppleScript) just doesn’t cut it. For this, there are a number of other options depending on the language you are using. Adobe provides a custom dialog which is fairly easy to use, With adequate dialog controls (widgets) within an intuitive user interface. The only problem is that these dialogs are modal.
Modal dialogs take over the system until the dialog is closed. No other user activity can be performed by the target application until the dialog is closed.
For most processes, the modal dialog is amply adequate. The user enters information or makes choices, and clicks a button to dismiss the dialog. From there the script takes over to accomplish its task. If there is no reason that the dialog must remain open while other processes take place, you should find its ease of use may make it your preferred user interface. Dialog controls that the custom dialog provides include:
For a dialog that offers a number of user dialog controls in a fairly intuitive interface, the custom dialog provided by an Adobe application may be your most used./p>
It is easy to understand and set up. Its downside is that it is modal. This means that the dialog must be dismissed before any other activity can be done by the user within the application. For most purposes, this is not a problem.
The code structure for creating and utilizing a dialog is fairly consistent:
Let’s see how this works in code with a simple dialog that gets the user’s response from a radio button group.
The following dialog will return a value of 0, 1, or 2 depending on the radio button chosen when the OK button is clicked.
//call function within a try/catch block to handle error if thrown try { var userResponse = dialogWRadio ("PDF Preferences", true, "PDF Prefs"); //alert ("user entered" + userResponse); } catch (e) { alert (e); } function dialogWRadio (dlgName, cancelIt, dlgLabel) { var userCancelled = true; //is set to false if user clicks OK button var oldPrefs = app.scriptPreferences.userInteractionLevel; app.scriptPreferences.userInteractionLevel=UserInteractionLevels.INTERACT_WITH_ALL; //create dialog var dlgRef = app.dialogs.add({name:dlgName, canCancel:cancelIt, label:dlgLabel}); //add a column var dlgColumn = dlgRef.dialogColumns.add(); //add a row var dlgRow = dlgColumn.dialogRows.add(); //add radio elements to row var rGroup = dlgRow.radiobuttonGroups.add(); rGroup.radiobuttonControls.add({staticLabel:"Hi-res_PDF", checkedState:true}); rGroup.radiobuttonControls.add({staticLabel:"Low-res_PDF"}); rGroup.radiobuttonControls.add({staticLabel:"PRINTER"}); if (dlgRef.show() == true) { userCancelled = false; var radioValue = rGroup.selectedButton; } dlgRef.destroy(); app.scriptPreferences.userInteractionLevel=oldPrefs; if (userCancelled) { throw ("User Cancelled"); } return radioValue; }
(*Result from dialog will return 0, 1, or 2 to correspond with Hi-res, Low-res, or PRINTER choices*) try set userResponse to dialogWRadio("PDF Preferences", true, "PDF Prefs") activate display alert ("user entered " & userResponse) on error (errMsg) activate display alert (errMsg) end try --userResponse on dialogWRadio(dlgName, cancelIt, dlgLabel) tell application "Adobe InDesign CC 2017" activate set userCancelled to true set oldPrefs to user interaction level of script preferences set user interaction level of script preferences to interact with all set dlgRef to make dialog with properties {name:dlgName, can cancel:cancelIt, label:dlgLabel} tell dlgRef set dlgColumn to (make dialog column) tell dlgColumn set labelRow to make dialog row tell labelRow to make static text with properties {static label:"PDF Output"} set dlgRow to make dialog row tell dlgRow set rGroup to make radiobutton group tell rGroup make radiobutton control with properties {static label:"Hi-res_PDF", checked state:true} make radiobutton control with properties {static label:"Low-res_PDF"} make radiobutton control with properties {static label:"PRINTER"} end tell end tell end tell end tell set userOK to show dlgRef if (userOK) then set dlgResult to selected button of rGroup end if destroy dlgRef set user interaction level of script preferences to oldPrefs if (userOK is false) then error ("User Cancelled") end if end tell return dlgResult end dialogWRadio
There are a number of ways the example scripts can be coded. For Javascript, an optional way is to use the with operator option. Instead of assigning a variable to a parent object (such as the dialog itself), an arbitrary variable is created in memory which references the object. You will find examples of this structure in the Sample scripts provided by Adobe. For instance, the AddGuides.jsx script uses the with operator. The script starts by creating a variable for the dialog and from there uses with to reference each parent object. Of course, for those objects that will have input values that will need to be referenced later, variables are assigned.})
... var myDialog = app.dialogs.add({name:"AddGuides"}); with(myDialog) { with(borderPanels.add()){ staticTexts.add({staticLabel:"Add Guides At:"}); with(dialogColumns.add()) { var myTopCheckbox = checkboxControls.add({staticLabel:"&Top", checkedState:true}); var myLeftCheckbox = checkboxControls.add({staticLabel:"&Left", checkedState:true}); ,,, } } } myReturn = myDialog.show(); ...
The whole idea of writing and using scripts is to eliminate repetitive processes while ensuring consistency. If you haven’t created a library of script functions (handlers) of your own, may I suggest that you start today. Copy the code from above to provide a template with which you can create your next user interface dialog. In the next few blog installations, we will be creating some simple projects that will do just that.
For the JavaScript language, Adobe provides an alternate dialog module. If you open the Add Guides Sample script provided by Adobe, in later versions of InDesign, you will see that it also includes a ScriptUI version of the dialog. ScriptUI seems to present some problems for beginning users. One problem I have is that the author of the script has forgotten to dismiss the window, and ends up with a number of windows in memory even before the script finishes testing. If you are interested in learning more about ScriptUI may I suggest that you look up the documentation provided on the web by Peter Kahrel (www.kahrel.plus.com/idesign/scriptui.html).
Introduced for Macintosh in OS X10.6, AppleScript Objective C provides a way to create rich user interfaces. It was designed to allow developers to write AppleScript-based applications with a rich interface in Xcode. For those wanting to take advantage of tis powerful language, Shane Stanley has written several manuals for writing AppleScriptObjC. His latest, Everyday AppleScriptObjC, Third Edition, is highly recommended. For more see macosxautomation.com/applescript/apps/everyday_book.html.