Your prescription for increased productivity and profitability
In our previous blog we demonstrated how one could create a mult-istate object using an AppleScript. To keep it simple, we left the process of adding buttons to the object up to the reader.
As long as you have gone to the trouble of creating a script to create a multi state object, it makes sense to let the script add the buttons automatically. For demonstration, we will create the buttons to a selected multi-state object. For creating interactive buttons, you have two options:
For this sample script we will use a button from InDesign’s button library.
The first task for the script will be to get a reference to the multi-state object to which the buttons will be associated. For now, we will assume the object has been created and is selected. For the purpose of calculation, make sure the measurement units for the document are in points or pixels. When the following is run, a reference to the selected object will be placed in the variable MSObject:
set MSObject to checkSelection() --========= --HANDLERS --========= on checkSelection() tell application "Adobe InDesign CC 2014" set selList to selection if length of selList is 0 then error "Requires multi state object selection" end if set selItem to item 1 of selList if class of selItem = multi state object then return selItem else error "Requires multi state object selection" end if end tell end checkSelection
Notice that the checkSelection handler will throw an error if there is no selection or if the class of the selected item is not the required class.
InDesign’s button library has a number of pre-defined buttons in a variety of colors. To allow the user to choose the buttons from a color list, we can use the following:
--at top of script global buttonColors global buttonNumbers set buttonColors to {"Blue", "Gray", "Green", "Red", "Black"} set buttonNumbers to {143, 145, 147, 149, 151} --after call to checkSelection set buttonNumber to getButtonChoice() --in HANDLERS section of script on getButtonChoice() set buttonChoice to choose from list buttonColors if class of buttonChoice is list then set buttonColor to item 1 of buttonChoice else error "User Cancelled" end if repeat with i from 1 to length of buttonColors if buttonColor = item i of buttonColors then set buttonNumber to item i of buttonNumbers exit repeat end if end repeat return buttonNumber end getButtonChoice
This returns the number of the back button that corresponds to the chosen color. For the forward button, the script will add 1 to this number. The following opens the button library and gets a reference to the assets for both buttons.
--add to top of script set libName to "ButtonLibrary.indl" --after call to getButtonChoice set {buttonLeft, buttonRight} to getButtonRefs (libName, buttonNumber, MSObject) --place in HANDLERS section for script on getButtonRefs (libName, buttonNumber, MSObject) tell application "Adobe InDesign CC 2014" set docRef to document 1 set pageRef to parent page of MSObject set appPath to file path as string set libraryPath to appPath & "Presets:Button Library" set filePath to libraryPath & libName if not (exists library libName) then set fileAlias to (libraryPath & ":" & libName) as alias set libReference to open fileAlias else set libReference to library libName end if set buttonLeft to asset ("" & buttonNumber) of libReference set rightNumber to buttonNumber + 1 set buttonRight to asset ("" & rightNumber) of libReference return {buttonLeft, buttonRight} end tell end getButtonRefs
All that is left at this point is to calculate the page position at which the buttons will be placed, place them, and set their behaviors. Notice for calculating place point the script does the math using the center point of the buttons as reference.
--at top of script set buttonHalfSize to 10 --after call to getButtonRefs addButtons(MSObject, buttonLeft, buttonRight, buttonHalfSize) --place in HANDLERS section for script on addButtons(MSObject, buttonLeft, buttonRight, buttonHalfSize) tell application "Adobe InDesign CC 2014" set docRef to document 1 set pageRef to parent page of MSObject set itemBounds to geometric bounds of MSObject --calculate the vertical center of MSObject set cy to (((item 3 of itemBounds) - (item 1 of itemBounds)) div 2) + (item 1 of itemBounds) set cx to (item 2 of itemBounds) - (buttonHalfSize * 2) set backButton to my makeButton(docRef, pageRef, buttonLeft, buttonHalfSize, cx, cy) tell backButton make goto previous state behavior with properties {associated multi state object:MSObject, event:mouse up, enable behavior:true, loops to next or previous:true} set x to behaviors end tell set cx to (item 4 of itemBounds) + (buttonHalfSize * 2) set nextButton to my makeButton(docRef, pageRef, buttonRight, buttonHalfSize, cx, cy) tell nextButton make goto next state behavior with properties {associated multi state object:MSObject, event:mouse up, enable behavior:true, loops to next or previous:true} end tell end tell end addButtons on makeButton(docRef, pageRef, assetRef, bSize, cx, cy) set placePt to {cx - bSize, cy - bSize} tell application "Adobe InDesign CC 2014" set placedObj to place asset assetRef on docRef move placedObj to pageRef move placedObj to placePt end tell return item 1 of placedObj end makeButton
Interesting to note in the makeButton handler, the value for placedObj is a list with the button reference as its first and only item. For this reason the handler returns item 1 of placedObj.
To handle errors and call the handlers, the top portion of the script should look similar to the following:
global buttonColors global buttonNumbers set buttonColors to {"Blue", "Gray", "Green", "Red", "Black"} set buttonNumbers to {143, 145, 147, 149, 151} set buttonHalfSize to 10 try set MSObject to checkSelection() set buttonNumber to getButtonChoice() set libName to "ButtonLibrary.indl" set {buttonLeft, buttonRight} to getButtonRefs(libName, buttonNumber) addButtons(MSObject, buttonLeft, buttonRight, buttonHalfSize) on error errStr activate display alert "Error: " & errStr return end try
Now that you have the button portion of the script working, you can add it to the script from the previous blog to create a script that creates the multistate object and buttons. For this the top portion of the script will read as follows:
global buttonColors global buttonNumbers set buttonColors to {"Blue", "Gray", "Green", "Red", "Black"} set buttonNumbers to {143, 145, 147, 149, 151} set buttonHalfSize to 10 set libName to "ButtonLibrary.indl" try set selBounds to getSelectionBounds() set buttonNumber to getButtonChoice() set imagePath to getImagePath("Images") set fileList to getFileList(imagePath) set MSObject to makeMSO(selBounds, imagePath, fileList, "MultiImages") set {buttonLeft, buttonRight} to getButtonRefs(libName, buttonNumber, MSObject) addButtons(MSObject, buttonLeft, buttonRight, buttonHalfSize) on error errStr activate display alert errStr end try
You will also need to add the following handlers from our AddButton script above:
Now open or create a document for the multi-state object. Make sure measurements are in points or pixels. Create a rectangle the desired size of the object and at the required position on the page. With the rectangle selected, test out your MSOWithButtons script.
Our multi-state object with buttons
You should now be well on your way to being able to to refine this script by using a custom dialog for the user interface. In addition to choosing the color, you may want to give the user the option of positioning the buttons on the top, bottom, or sides (as above).