Over the past several months, we have been discussing command handlers and subroutine handlers in detail. This month, we will begin discussing a new topic … AppleScript Studio. As we proceed, you will find that we will be using handlers regularly, especially command handlers, as AppleScript Studio makes heavy use of them. If you’d like to refer back to my previous columns on handlers, you can do so here… (Part 1, Part 2, and Part 3).
What is AppleScript Studio
When developers first hear the name AppleScript Studio, they often mistake it for an actual application. However, this is not the case. AppleScript Studio is actually a subset of features in two much more comprehensive applications, Xcode and Interface Builder. These applications are installed as part of the Mac OS X Xcode Developer Tools package, which comes on the Mac OS X installation CD. Since Apple updates the Xcode Developer Tools fairly regularly, the best way to gain access to updates is to become a member of the Apple Developer Connection. There are multiple levels of membership available, and the online level is free.
Using AppleScript Studio, developers can create AppleScript-based applications, complete with interfaces that look and feel just like any other Mac OS X application. The concept is fairly straightforward. You begin by creating an Xcode project based on a template. This project contains, among other things, an interface component and a code component. Next, you design the interface for your project in Interface Builder, adding buttons, text fields, progress bars, and any other desired elements. You then specify events to which your interface elements will respond by initiating code within the Xcode project. For example, you might want specific code to trigger when a user clicks a button, when a user enters text into a text field, or when a window is displayed on screen. Once events have been assigned within your interface, you add AppleScript code within the Xcode project to execute when those events take place.
Let’s walk through this process now. We will create a very basic AppleScript Studio project that will resize an image using information specified by a user via an interface. In future columns, we will continue to expand on the steps that we will discuss here.
If you have not yet installed the Xcode Developer Tools, you will need to do so if you intend to follow along with this tutorial.
Creating an AppleScript Studio Project
Begin by launching the Xcode application (/Developer/Applications/Xcode), and then selecting New Project from the File menu. Upon doing so, you will be presented with an Assistant window, which will allow you to select from a list of pre-existing project templates provided by Apple. Select the AppleScript Application template, located in the Application category, and click the Next button to proceed.
Figure 1: Selecting an AppleScript Studio Project Template
Next, you will be asked to specify a name and location for your project. For this demonstration project, enter Resize Image for the project name, and click the Choose button if desired to specify a directory in which you would like the project to be created. Click the Finish button to proceed.
Figure 2: Naming an AppleScript Studio Project
Xcode will now create your project, based on the specified template, and display it in a new project window. If you have not used Xcode in the past, this window may look a bit complex and confusing, and you will find that it contains a number of components. However, for the purposes of creating a simple AppleScript Studio project, we will only work with a handful of these components.
Figure 3: An AppleScript Studio Project’s Components
Resize Image.applescript is the file that will contain our AppleScript code, and MainMenu.nib is the Interface Builder file for our project. For this demonstration project, you will not need to work with any other files. Although, you may double click on AppleScriptKit.sdef in order to view AppleScript Studio’s AppleScript dictionary, if you are interested in exploring it.
Designing the Interface
We are now ready to begin designing our project’s interface. To get started, double click on MainMenu.nib in the Xcode project window. Doing so should cause Interface Builder to launch and open the MainMenu.nib file in a window.
Figure 4: The MainMenu.nib File in Interface Builder
By default, a blank interface window, called simply “Window”, already exists in MainMenu.nib. If it’s not already visible, double click on it in the MainMenu.nib window, and it will be opened.
Figure 5: A Blank Window in Interface Builder
Interface elements are contained within a palette window. To bring up this window if it is not already visible, select Show Palettes from the Tools > Palettes menu.
Figure 6: The Interface Element Palette
The palette window is broken into a number of different categories of interface elements, including menus, controls and indicators, text controls, and more. You can switch between categories using the toolbar in the palette window. To add an interface element, select it in the palette window, and drag it into the desired location in your project’s window. As you move the element around in the window, guides will help to ensure that you are adhering to Apple’s guidelines for interface design. For this demonstration, we will be adding some buttons, labels, and a text field to the interface. However, if you explore the available interface elements further, you will find that it is possible to add new windows, panels, drawers, tables, tab views, and much more to your interface.
Interface Builder will also allow you to modify many different attributes of the elements within your interface. This is done via the Inspector palette. If this palette is not visible, select Show Inspector from the Tools menu to display it, and select Attributes from the popup at the top of the palette.
Now, as you select different interface elements, you will find that modifiable attributes for those elements are displayed in the Inspector palette. These attributes will vary depending on the element that is selected. For example, if you select the window in your interface, you will find that its title is a modifiable attribute, as are options to allow the user to close, minimize, and zoom the window.
Figure 7: The Inspector Palette
Drag two buttons, two labels, and a text field from the interface element palette into your window. Next, using the Inspector palette, modify the attributes (title, size, etc.) of these elements, as well as the window itself, to closely resemble the screenshot below.
Figure 8: The Completed Interface
Linking the Interface Elements to the Project Code
Now that the interface for our project is complete, we are ready to begin linking it to AppleScript code. For this demonstration, we will need specific code to be triggered when the interface is initialized, as well as when the user clicks one of the buttons in the interface. To configure the interface in this manner, we must assign event handlers to elements of the interface.
An event handler is a command handler, which will be called when a specific event takes place. Like interface element attributes, the event handlers that may be assigned to an element will vary depending on the element itself. For example, a button may be assigned to a clicked event handler, while a window may not, allowing code to trigger when the button is clicked.
Event handlers are assigned to interface elements via the Inspector palette. Select an element, and then choose AppleScript from the popup at the top of the Inspector palette to display the event handlers for the selected element.
Let’s begin assigning event handlers to our interface. Select the Resize button. In the Inspector palette, select the clicked checkbox (listed under the Action grouping) to configure the button to execute AppleScript code when it is clicked. Next, select the Resize Image.applescript radio button in the Script area of the Inspector palette. This indicates the AppleScript file in which the clicked event handler will reside within our project.
Since our interface contains two buttons, we’ll need a way to identify one from another within our code. One way that this can be done is by assigning an AppleScript name to the buttons. Once an AppleScript name has been assigned to an element, you can refer to that element using its name within your AppleScript code. For the Resize button, enter a name of resize into the Name field in the Inspector palette.
Figure 9: Assigning Event Handlers to Interface Elements
Repeat the steps above in order to link the clicked event handler in the Resize Image.applescript script to the Cancel button too. For its name, enter cancel into the Name field.
Next, click on the text field in the interface. Enter an AppleScript name of “size” into the Name field in the Inspector palette.
Next, click on the window to select it. This time, you should see a different set of event handlers in the Inspector palette. Select the checkbox for the awake from nib event handler (listed under the Nib grouping), and link it to the Resize Image.applescript script. The awake from nib handler will be executed when the interface is first loaded. Since our interface will only contain a single window, there is not a need to give it an AppleScript name at this time.
Adding Code to the Project
Now that we have assigned event handlers to our interface elements, we are ready to add the event handlers to our project’s AppleScript code. Click the Edit button in the Inspector palette to navigate to the Resize Images.applescript file in your Xcode project. Xcode should be brought to the front, and your script window should be displayed before you. The empty event handlers that you have assigned to your interface elements should have been added automatically to the script. Modify the AppleScript code within this script as follows:
global theImage
on clicked theObject
-- Handle if the "Resize" button was clicked
if name of theObject = "resize" then
-- Retrieve the resize percentage amount
set theNewSize to (contents of text field "size" of window 1) as integer
-- Determine a path in which to save the resized image
tell application "Finder"
set theImageName to name of theImage
set theImageFolder to (folder of theImage) as string
end tell
set theResizedImagePath to theImageFolder & "Resized-" & theImageName as string
-- Open the image, resize it, and save it as a new file
tell application "Image Events"
launch
set theImage to open theImage
tell theImage
scale to size theNewSize
save in theResizedImagePath
close
end tell
end tell
end if
-- Quit the application
quit
end clicked
on awake from nib theObject
-- Prompt the user to select a file
set theImage to choose file with prompt "Please select an image file:" without invisibles
end awake from nib
Building and Running the Project
Now, we are ready to test our project. To build and run the project from within Xcode, click the Build and Go button in the project window’s toolbar. If all goes well, the project should launch as an application, and you should be prompted to select an image to be processed. Navigate to and select an image. Next, the interface should be displayed. Enter the desired number of pixels into the text file in the interface, and click the Resize button. The script should then resize the image using Image Events, and output it into the same directory as the original image. Please note that you won’t actually see the image open as this process is performed, as Image Events is a background application.
Our AppleScript Studio project is currently in Debug mode. Once you have tested the project, and are ready to begin using it or distributing it to others, you will need to change it to release mode. To do this, select Release from the Project > Set Active Build Configuration menu, and then click the Build and Go button in the project window’s toolbar again. The project will now be rebuilt in release mode. You will find the final built application in the /Build/Release folder within the main project folder.
In Conclusion
You should now have at least a basic understanding of how AppleScript Studio works. Obviously, we have truly only scratched the surface here, and there is much, much more to learn. We will continue to discuss AppleScript Studio in future columns, but you are encouraged to begin exploring it further on your own. As you do so, be sure to check out the fully editable example projects included in the /Developer/Examples/AppleScript Studio folder, as well as the AppleScript Studio documentation that can be found in the Apple Developer Connection reference library (accessible online or via the Help > Documentation menu in Xcode). If you get stuck, you can also post your questions to MacScripter’s AppleScript Studio forum.
You are also welcome to download the demonstration project discussed in this column. You can find it here.
Until next time… just script it!
-Ben Waldie