Mapping the Interface to the Code
Now that the interface is built, we're ready to begin linking it to the project's code. At this point, we don't have any code other than the default code that comes from the template, so we'll need to write some.
First we'll add the bindings, which are essentially links between our code and interface. In the Project Navigator, click the AppDelegate.applescript file to display its contents in the editor. This file already contains some code to get you started in a script object named AppDelgate (see Figure 11).
Figure 11 Default code in an AppleScriptObjC Xcode project.
Bindings are defined using the following AppleScript syntax:
property bindingName: bindingValue
We'll need a binding for each of the processing options we added to the application's interface window. Add the following properties to the AppDelegate.applescript, beneath the default parent property.
property photoPath : "" property outputFolderPath : "" property flipHorizontal : false property flipVertical : false property applyRotation : false property applyScaling : false property rotationAmount : 90 property scaleAmount : 150 property scaleUnits : 0 property outputType : 1
Next, we need to add these bindings to our interface file. Click MainMenu.xib to display the interface again. (The main window should still be visible.) Systematically select each of the following interface elements and apply their corresponding bindings in the Bindings Inspector (Command-Option-7).
- Bind the Photo Path Text Field element's Value attribute to the App Delegate. Set the Model Key Path field to our binding property, photoPath. Then select the Continuously Updates Value checkbox, leaving all other checkboxes set to their default values (see Figure 12).
- Bind the Value attribute of the Flip Horizontal checkbox to the App Delegate, and set its Model Key Path field to flipHorizontal (see Figure 13).
- Bind the Value attribute of the Flip Vertical checkbox to the App Delegate, and set its Model Key Path to flipVertical.
- Bind the "Scale to:" checkbox to the App Delegate, and set its Model Key Path to applyScaling.
- Two attributes of the scaling amount text field (next to the "Scale to:" checkbox) will be bound to the App Delegate. Set the Model Key Path for Value to scaleAmount, and select the Continuously Updates Value checkbox. Then set the Model Key Path for Enabled to applyScaling. This setting will cause the text field to become enabled only when the user selects the "Scale to:" checkbox (see Figure 14).
- For the scaling units pop-up button (located next to the "Scale to:" checkbox and scaling amount text field), bind the following two attributes to the App Delegate. Set the Model Key Path for Selected Index to scaleUnits. Then set the Model Key Path for Enabled to applyScaling. When the user selects the "Scale to:" checkbox, both the scaling amount text field and the scaling units pop-up button will be enabled.
- Bind the Value attribute of the Rotate checkbox to the App Delegate, and set its Model Key Path to applyRotation.
- Bind the following two attributes to the App Delegate for the rotation amount text field (next to the Rotate checkbox). Set the Model Key Path for Value to rotationAmount, and select the Continuously Updates Value checkbox. Then set the Model Key Path for Enabled to applyRotation.
- Bind the photo path text field's Value attribute to the App Delegate, set the Model Key Path field to outputFolderPath, and select the Continuously Updates Value checkbox.
- Bind the Selected Index attribute of the Save As pop-up button to the App Delegate, set the Model Key Path field to outputType.
Figure 12 Configuring the value bindings for the Photo path field.
Figure 13 Configuring the value binding for the Flip Horizontal checkbox.
Figure 14 Configuring two bindings, Value and Enabled, for the scaling amount text field.
Next, we'll create an outlet for our photo preview. In the Project Navigator, click AppDelegate.applescript to return to the AppleScript code. An AppleScriptObjC outlet is defined in the same manner as a binding, but with a missing value, rather than a defined value. Here's the proper format:
property outletName : missing value
Add the following property to the AppDelegate.applescript, beneath the binding properties we added earlier.
property imageView : missing value
Now, click the MainMenu.xib file to return to the interface. While holding down the Control key, click the App Delegate in the left sidebar of the editor area, and drag it to the Image Well element in the window, as shown in Figure 15.
Figure 15 Connecting the App Delegate to the image well.
When you select the image well, a window appears, displaying a list of outlets. Since there's only one outlet in our code, only one is displayed. Select the imageView outlet to complete the link (see Figure 16).
Figure 16 Connecting the imageView outlet to the image well in the window.
Adding Processing Handlers
Now we're ready to add processing handlers (methods) to our code, linking them to the buttons in our interface. Return to the AppDelegate.applescript file, and add the following empty handlers to the script, beneath the imageView outlet binding we just defined in the preceding section. We'll add code to the handlers in the next section.
on browseForPhoto_(sender) end browseForPhoto_ on browseForOutputFolder_(sender) end browseForOutputFolder_ on processPhoto_(sender) end processPhoto_
Click MainMenu.xib to go back to the interface. Select the Browse button under the photo text field; then, while holding down the Control key, drag the Browse button to the App Delegate in the left sidebar of the editor area (see Figure 17). A window appears, listing the handlers in our main script. Select browseForPhoto to complete the link (see Figure 18).
Figure 17 Linking the Browse button to the App Delegate AppleScript file.
Figure 18 Connecting the Browse button to the browseForPhoto handler.
Repeat these steps for the buttons in the Output Options area, mapping the Browse button beneath the output text field to the browseForOutputFolder handler, and the Process button to the processPhoto handler.