AppleScript_ The Definitive Guide - Matt Neuburg [244]
Observe the use of the Parameters settings to supply part of our interface with initial values by way of the bound keys; so, for example, the bitrate field will initially contain "128" because we say so here. It is crucial that the name and spelling for the keys, such as cbrText, should match exactly between Interface Builder (where the interface item is bound to that key) and here (where the key's initial value is given).
You should be wondering what the exampleText parameter is for, as we have no interface element bound to this key. This parameter is part of a trick that will be used later to communicate between our ui.applescript and main.applescript files, so read on and all will be made clear.
So much for the info window, but unfortunately we still need to edit Info.plist a bit further by hand. Select Info.plist in the project window and choose File → Open With Finder to bring up the file for editing in Property List Editor. (Under no circumstances should you attempt to edit this file by hand as a text file, as you will invariably make a mistake and render the file invalid as a property list.) Open each triangle and select and delete each line that we've left as a default comment (such as AMDInput and most of the other entries under AMDescription). When you're done with all that, save the file and quit Property List Editor. But, alas, we are still not done. We must also edit the localised versions of these settings, in the file called InfoPlist.strings. Open this file as a text file and delete everything except the CFBundleName and the AMName, and save it.
We are now ready, at long last, to write our code. Start with ui.applescript. Remember, the purpose of this script is to interact with our action's interface. The code is almost identical to what we'd put in a standalone application built with AppleScript Studio. I'll present the code a bit at a time.
Example 27-8 shows start of the code. The very first thing is to capture a reference to the NSView that contains the interface elements so that the rest of our code can refer to them. (Unlike our earlier standalone application example, we have no globally available named window, such as window "search", on which to base a reference to an interface element.) We have set the NSView to send us an awake from nib notification; this notification is guaranteed to arrive very early when our action's interface loads, and since theObject in this case in the NSView itself, we simply copy it to a property. To this and all the other action messages and notifications, we respond by calling our updateInterface handler; thus our interface will be "live," updating itself whenever the user does anything.
Example 27-8. Keeping the interface updated
property theView : missing value
on awake from nib theObject
set theView to theObject
updateInterface( )
end awake from nib
on action theObject
updateInterface( )
end action
on clicked theObject
updateInterface( )
end clicked
on changed theObject
updateInterface( )
end changed
Example 27-9 shows the updateInterface handler. The idea is to construct the lame command based on what the user has selected and typed in the interface, displaying this command in the example text field in the action's interface. To keep things simple, I have omitted to perform certain validations; in particular, the user can enter anything in the bitrate text field. (If the value is an unreasonable number, we use it anyway, and if it's not a number, we treat it as 128.)
Example 27-9. Constructing the lame command
on updateInterface( )
tell theView
set s to title of popup button 1
set s1 to "lame --preset "
if (state of button "fastSwitch") is 1 then
if state of button "cbrSwitch" is 0 then
if s is in {"medium", "standard", "extreme"} then
set s1 to s1 & "fast "
end if
end if
end if
if (state of button "cbrSwitch") is 1 then
try
set s to "cbr " & (content of text field "cbrText" as integer)
on error
set s to "cbr 128"
end try
end if
set content of text