Copyright ©1998 by AAA+ Software Forschungs- und Entwicklungs Ges.m.b.H. All Rights Reserved.
2
Exploring Mac OS X With Joy
This sections explains how you can use the Joy interpreter to interactively explore the Mac OS X API. It assumes that you have loaded the Joy palette into Interface Builder (as explained in the previous section ).
By default, Joy uses JavaScript as a base language. If you want to use Tcl instead, you have to switch languages using the Preferences menu item in the Info submenu of InterfaceBuilder's Joy menu.
First exploration with Joy: NSWindow
Let's now start to create a New Application which already contains a Joy interpreter by selecting the New Joy Application command in InterfaceBuilder's Joy menu. This will create a new UNTITLED application with a standard window and a default menu.
Figure 1: A new UNTITLED application containing a Tcl interpreter.
We will now interactively play around with the NSWindow API. We already have a window in our application (called My Window), we only have to tell the Joy interpreter to give it a Joy name:
1. | Ctrl-Drag from the Interpreter object to the MyWindow Object inside the nib document window. This will bring up the interpreter's own connections inspector. |
Figure 2: Connecting the Interpreter with the Application's window.
2. | Click the Connect button. |
3. | Type in a variable name for the NSWindow object. Call it window. Press Enter. |
Figure 3: The Interpreter's Connections Inspector.
You should now be able to start your application and its Joy interpreter: Choose Test Interface in InterfaceBuilder's Document menu and then choose Command Window... in your application's Joy menu. The interpreter window will appear and now the real joy starts: You can send Objective-C messages directly to your window and see what happens.
Note that the dollar sign is needed for variable substitution. Brackets are only needed for nested commands. Spaces after method name colons are required. Type
tcl> $window miniaturize: nil
and your window gets miniaturized. Of course you can deminiaturize it by double-clicking on the mini-window icon. You can replay this sequence by pressing cursor up and Enter in the Joy window. You can deminiaturize the window by typing:
tcl> $window makeKeyAndOrderFront: nil
You can close an NSWindow with the performClose: method:
tcl> $window performClose: nil
But you can still reopen it as before (press cursor up twice):
tcl> $window makeKeyAndOrderFront: nil
You may want to change the window's title, but if you try
tcl> $window setTitle: Apple
Error: invalid object: Apple
you get an error message. Why is that? The setTitle: method needs an NSString as parameter, not a Joy string. Luckily, there is the convenient conversion operator @ just like in ObjectiveC, but the syntax is slightly different (you have to put it in brackets and a space is needed after the @).
tcl> $window setTitle: [@ Apple]
Note that this worked immediately without needing to redisplay the window.
There is also an operator for converting an NSString to a Joy string:
tcl> * [$window title]
Apple
If the Joy string contains spaces, you need to quote it:
tcl> $window setTitle: [@ "Apple is great!"]
(As an exercise, you may want to change the title of the miniaturized window to something shorter.)
If you use a method which is not recognized, you get an error message:
tcl> $window setColor: 1
Error: invalid selector: "setColor:"
You may want to quickly find out how the method really is named without searching the documentation:
tcl> objc:info methods NSWindow *Color*
{char canStoreColor} {id backgroundColor} {void setBackgroundColor: id}
So we try again:
tcl> $window setBackgroundColor: 1
Error: invalid object: "1"
This time we get an error message because the setBackgroundColor: message expects an NSColor object. What's a class method of NSColor to create an object representing the white color?
tcl> objc:info methods -class NSColor *white*
{id whiteColor}
So this is how it works:
tcl> $window setBackgroundColor: [NSColor whiteColor]
Or does it? Try sending the window a display message.
tcl> $window display
You may want to try the same with a more fancy color (maybe orange?).
Second exploration with Joy: NSSavePanel
We now demonstrate using a save panel. We will use the same application as before.
If you are new to the Yellow Box API, you may be unsure of which class to use for a save panel. Use a glob-style search to locate the correct class (note that if the search pattern contains square brackets then you need to enclose it with curly braces):
tcl> objc:info classes {*[sS]ave*}
NSSavePanel
And how can we create an instance of that class?
tcl> objc:info methods -class NSSavePanel
{id _updateWorkspace: id} {id savePanel}
The first result looks like an internal method (you won't find it in the documentation), so we will use the second:
tcl> NSSavePanel savePanel
NSSavePanel@0x8bb324
For convenience, assign this object to a variable, using Tcl's set command.
tcl> set sp [NSSavePanel savePanel]
NSSavePanel@0x8bb324
(Interestingly, each time the [NSSavePanel savePanel] expression is evaluated, the same object is returned. You can check this by pressing the cursor up key, to retreive the last typed message, and pressing Enter to re-execute it.)
So how can we display the NSSavePanel? The same way as an NSWindow? (NSSavePanel is an descendant of NSWindow in the class hierarchy, so it should recognize the same methods.)
tcl> $sp makeKeyAndOrderFront: nil
Yes, it's there. But it does not display anything. And how do you close it? If you try NSWindow's performClose: method it will not work because the panel has no close box. Is there another method?
tcl> objc:info methods NSSavePanel {*[cC]lose*}
What about in one of NSSavePanel's superclasses?
tcl> objc:info methods -all NSSavePanel {*[cC]lose*}
{void performClose: id} {char isReleasedWhenClosed}
{void setReleasedWhenClosed: char} {void close}
The close method looks promising. It also comes from NSWindow and does the same as performClose: but without simulating a mouse click (just removing the window from the screen). You may want to try out the difference with the application's default window (you will only see the difference if you have fast eyes or a slow computer).
tcl> $sp close
If you want, you can redisplay the save panel and try other NSWindow methods you are already familiar with (e.g. setTitle:).
If you look into the Yellow Box developer documentation, you will learn the existence of the runModal and the runModalForDirectory:file: methods. Let's have a go:
tcl> $sp runModalForDirectory: [@ /tmp] file: [@ tempfile]
0
You can't type anything into the interpreter now until you click on OK or Cancel in the save panel (that's what modal means!). Note that this method returns 1 if you click on OK and 0 if you click on Cancel. Try what happens if you select an existing file!
You can find out the name of the selected file with the filename method:
tcl> * [$sp filename]
/Local/Users/joy/newfile
The next section explains how you can use Joy to write a full application right inside InterfaceBuilder without any compiling or linking.