CurrencyConverter HOWTO

# Building the User Interface

The next step in creating a Lisp version of the currency converter application is to construct the user interface. Apple's tutorial describes in detail how to do this.

## Apple's Tutorial

Apple's tutorial explains how to use InterfaceBuilder to create the user interface, and how to use XCode to create project files and write Objective-C code. Our project uses Lisp instead of Objective-C, and does not use XCode project files, so you can skip the part of the tutorial that explains how to use XCode.

## Using InterfaceBuilder to Create the UI

We'll begin by using Apple's InterfaceBuilder application to create a nibfile. The nibfile contains archived versions of the Objective-C objects that define the application's user interface. When you launch an application, Mac OS X uses the archived objects in the nibfile to create the windows and menus you see on the screen.

Start by locating Apple's InterfaceBuilder application. If you installed Apple's Developer Tools, InterfaceBuilder should be in the folder "/Developer/Applications/":

NOTE: If you have not installed Apple's Developer Tools, you should do that now. You will not be able to build the CurrencyConverter example without them. The Developer Tools are distributed as an optional install with Mac OS X 10.5 ("Leopard"). Look for the "XCode Tools" package in the "Optional Installs" folder on the Mac OS 10.5 install disk.

Once you have located InterfaceBuilder, double-click to launch the application. InterfaceBuilder presents a window you can use to choose a template for the nibfile you are going to create.

Click the "Application" icon and then click the "Choose" button to create an application nibfile. InterfaceBuilder creates a new application nibfile, but doesn't immediately save it. The Objective-C objects that represent the new application's interface appear in a new untitled window:

The intial window and menubar also appear on the screen. The new application's name appears in the menus as "NewApplication". Save the new nibfile into the "currency-converter" folder that you created earlier (on this page). InterfaceBuilder 3.0 gives you a choice of file formats when you save a new nibfile; use the "NIB 3.x" format—the "XIB 3.x" format works fine for editing your user interface, but will not work correctly if you try to use it in a working application. Give the new file the name "CurrencyConverter.nib".

NOTE: Most Objective-C application projects use a main nibfile called "MainMenu.nib", and if you use XCode to create a new application project, it creates a nibfile with that name. Apple's CurrencyConverter tutorial assumes that the name of the main nibfile is "MainMenu.nib".

So, why do we tell you to use a different name? Clozure CL has a main nibfile built into it, whose name is "MainMenu.nib". Normally you don't see it, and don't even need to know that it exists. But the Clozure CL application-building tools create a new application by copying resources from the Clozure CL application, so that your new application has available to it all the built-in Clozure CL tools. We ask you to name your nibfile "CurrencyConverter.nib" so that it can coexist with the Clozure CL main nibfile without causing any problems.

This difference between a Lisp project and an Objective-C project might be a little confusing at first. Just try to keep in mind that whenever Apple's tutorial refers to the "MainMenu.nib" file, it means the file we have just created and named "CurrencyConverter.nib". In a Clozure CL project, "MainMenu.nib" is the name of the main Lisp nibfile, not your application's main nibfile.

Skip straight to the part of Apple's tutorial called Defining the View: Building the User Interface. Read the introduction to nibfiles, and follow the instructions to create the Currency Converter interface. (Remember that when the tutorial tells you to open and edit "MainMenu.nib", you will instead open and edit your "CurrencyConverter.nib".) When you reach the end of the section called Test the Interface, and move on to the short section afterward called What's Next, you are done creating the interface for your application. Save your nibfile and continue with the next section of this HOWTO.

## What if You Need to Use InterfaceBuilder 2.x?

If you are still using Mac OS X 10.4.x ("Tiger"), you can still create a working nibfile and you can still follow the instructions in this HOWTO to create a Cocoa application with Clozure CL. The main obstacle to doing so is that the earlier versions of InterfaceBuilder have a significantly different user interface, and so you may find it hard to follow Apple's tutorial when working with InterfaceBuilder.

If you are working with Mac OS X 10.4.x ("Tiger"), you can look here to find a description of how to build the user interface files with the earlier version of InterfaceBuilder. When you have finished building your user interface, you can continue with the next section, "Creating a Lisp File".

One other thing: if you are using Mac OS X 10.4.x ("Tiger"), you will be able to build Cocoa applications only on PPC Macs. The Clozure CL Objective-C support for Intel systems works only on Mac OS X 10.5.x ("Leopard").

## Adding Custom Classes to the nibfile

Once the user interface for your application looks right, there is still one important task to complete before you can use it. You must record some information in the nibfile about the classes of the objects, so that the application can create them with the right connections in place.

When you use XCode to write an Objective-C application, InterfaceBuilder can read the Objective-C header files and use the information in them to create descriptions of the classes in the Objective-C code. When the application is written in Lisp, InterfaceBuilder can't read the class descriptions from the code, and so we'll have to manually tell the nibfile about any classes that we use in the user interface.

As you will see in the following sections, we'll use Lisp code to define two Objective-C classes: Converter, and ConverterController. The Converter class implements the method that performs the actual currency conversion for our application; the ConverterController class provides communication between the user interface and the Converter object. We need a way to create instances of these two classes in the nibfile, so that launching the application sets up all the objects correctly.

## Create Instances of Custom Classes

In InterfaceBuilder's Library window, select the Cocoa Objects and Controllers view:

Drag an Object from the Library window and drop it into the main CurrencyConverter window:

Now tell InterfaceBuilder the name of the new object's class. With the Object icon selected in the main CurrencyConverter window, choose the Identity tab of the Inspector. At the top of the Identity view is a "Class" field; type the name of your custom class (in this case, "Converter") into the "Class" field and save the nibfile:

Repeat the previous steps to create an instance of the ConverterController class: drag an "Object" icon and drop it in the main CurrencyConverter window. Then, change the name of the Object's class to "ConverterController".

That's all it takes to add an instance of a custom class to the nibfile. We do still have to add the names of instance variables and actions, and we need to create the connections between the instances.

## Add Outlets and Actions

Now, using the "+" button below the "Class Outlets" section of the Inspector, add outlets to the ConverterController class. The outlets you need to add are named "amountField", "converter", "dollarField", and "rateField".

We'll connect each of the "field" outlets to one of the text fields in the CurrencyConverter UI, and we'll connect the "converter" outlet to the Converter instance that we created before. When the application launches, it creates the Converter and ConverterController instances and establishes the connections that we've specified in the nibfile.

First, though, we need to tell the nibfile about actions as well as outlets. With the "ConverterController" instance selected, use the "+" button below the "Class Actions" section to add a new action. Name the action "convert:":

In this application, the "convert:" action is the only action defined for the user interface, so we are done with actions now. In more complex applications you may need to define many actions and outlets.

Now we'll connect outlets and actions to objects.

## Add Connections

InterfaceBuilder enables you to connect objects by "Control-dragging" from one to another. To "Control-drag", you hold down the Control key while dragging from one object to the next.

Select the "ConverterController" instance in the nibfile's main window, and Control-drag a connection to the "Exchange rate" text field in the application's main window. (Be sure to connect to the text field, not to its label!) When you release the mouse button, InterfaceBuilder pops up a menu that lists the available outlets. Choose "rateField" from the menu. The "rateField" outlet of the "ConverterController" instance is now connected to the "Exchange rate" text field.

Repeat the same steps for the "Dollars" field and the "Amount" field, connecting them to the "dollarField" and "amountField" outlets, respectively.

Finally, Control-drag a connection from the "ConverterController" instance to the "Converter" instance. Choose "converter" from the popup menu to connect the "converter" field of the "ConverterController" instance to the "Converter" instance.

To confirm that the connections are correct, you can use the Connections view in the inspector. With the "ConverterController" instance selected, click the blue arrow icon at the top of the Inspector window to display connections. You should see a list of outlets and the types of objects they are connected to:

We need to add one more connection: from the "Convert" button in the application window to the "ConverterController" instance. Control drag a connection from the "Convert" button in the application window to the "ConverterController" instance in the nibfile's main window. InterfaceBuilder pops up a menu; choose the "convert:" action from the menu to connect the button to the action.

The nibfile now contains descriptions of the needed cusstom classes and their connections. You can continue with the next section, which explains how to write the Lisp code that implements the application's behavior.