oreilly.comSafari Books Online.Conferences.


AddThis Social Bookmark Button

Building Applications with AppleScript and FaceSpan
Pages: 1, 2, 3

The Search TidBITS Example (Interface)

The Search TidBITS example in Chapter 24 of my book is rather more elaborate, involving interactive interface elements, multiple windows, and an embedded Perl script. The purpose of the application is to act as a front end to the TidBITS archive server. The user enters text in some search fields, and presses a button; the application constructs an HTTP POST request and uses curl to submit it to the TidBITS server. When the response comes back as an HTML page, the application uses Perl to parse the HTML, extracting the titles and URLs of the found articles, and presents the list of titles to the user; the user can then double-click on a title to open the corresponding URL in a browser.

To create the Search TidBITS example, start up FaceSpan and create a new project called "Search TidBITS". In the Project Window, select Other and use the contextual menu's Add Files item to copy the Perl script into the project; this insures that the Perl script will appear in the built application's package, within its Contents/Resources directory, where we will be able to access it from our running code. Here is the Perl script (p. 364):

$s = "";
while (<>) {
    $s .= $_;
$s =~ m{search results (.*)$}si;
$1 =~ m{<table(.*?)</table>}si;
@rows = ($1 =~ m{<tr(.*?)</tr>}sig);
for ($i=0;$i<$#rows;$i++) {
    ($links[$i], $titles[$i]) = 
        ($rows[$i+1] =~ m{<a href="(.*?)">(.*?)</a>}i);
print join "\n", @links, @titles;

In the Project Window, select Windows and use the the contextual menu's New Window item to create the second window. Now you can design the interface. First, design the windows; this is like the design in the AppleScript Studio implementation, except that FaceSpan has no NSForm control, so I just use separate text fields to make up the Search window (see figure below).

Now, we'll design the menu. We provide two menu items of our own, New and Close, as shown in the following figure:

If you want a menu item to be active and to send an event when it is chosen, you must select it and choose the "execute script" action in the Info Panel. So, this must be done now for the New and Close menu items.

Next we assign names to those interface elements that need them, by selecting each element and typing into the Info Panel: I've called the two windows "main" and "results"; in the "main" window, the three editable text fields have been named "textField," "titleField," and "authorField". Other interface elements can be identified easily enough by index number or in some other way, so there's no need to assign any further names.

The Search TidBITS Example Code

Next, we'll write our application's code. There are two big differences between what you do in AppleScript Studio and what you do in FaceSpan.

First, in AppleScript Studio, you must use the Info Window to declare explicitly what events sent by each interface item you wish to handle. In FaceSpan, there is no need for this; if you want to handle an event, you just write a handler for it.

Second, FaceSpan permits you to organize your code according to a container script inheritance hierarchy. The idea is that different interface elements can have scripts of their own. Behind the scenes, these scripts are related using script inheritance (see p. 178 of my book). Therefore, a script can "see" handlers and globals in the script of the interface element's container; and when an interface element generates a user event, the event propagates up the container hierarchy, starting with the script of the interface element itself, until it finds a matching handler. This permits an object-based style of code organization. This code organization, while purely optional, can be considerably neater than what you have to do in AppleScript Studio.

To illustrate, we're going to make three more scripts, each attached to a particular interface element: one for the push button within the "main" window; one for the "main" window itself; and one for the table view within the "results" window. Thus, counting the Project Script.applescript script that comes with the project, we will end up with four scripts.

These scripts will automatically form a hierarchy corresponding to the container hierarchy. (I have put the the "results" window script in brackets, because we're not going to bother creating it.)

Project Script.applescript
    "main" window script
        push button script
    ["results" window script]
        table view script

A script at a lower level of the hierarchy can call a handler or (using the keyword my) access a property in a script at a higher level above it. Furthermore, propagation of a user event will start with the script of the interface element that generated the event.

For example, both a push button and a table view will generate a "clicked" event when the user clicks on them. In AppleScript Studio, you might have just one "on clicked" handler where both these events would arrive; that handler would then have to distinguish which interface element generated the event, in order to decide what to do. But in FaceSpan there is no need for this. We can put an "on clicked" handler in the push button script, and it will be called only when this push button is clicked.

To create a script associated with an interface element, select it in its window editor and use the contextual menu to choose Edit Script. After you've created a script for an interface element, FaceSpan displays a little script icon in the lower left of that element.

Pages: 1, 2, 3

Next Pagearrow