New Example: Nib Files

Thursday October 4, 2007

A question arose on the mailing list about loading nib files with Nu. Since none of the Nu sample programs used nib files, it wasn't clear how to write Nu code to use them. To help with that, I added a new example, another version of the RandomApp program from Aaron Hillegass' Cocoa Programming for Mac OS X.

The new example is called RandomAppWithNibFile and it is included in the Nu-0.1.2 and later distributions. Here it is in the git archives. If you already have Nu installed, you can download RandomAppWithNibFile.tgz.

screen shot

From inside the example directory, build and run the example with nuke run. It will load a nib file containing a window definition; that definition includes the two buttons and text field that make the RandomApp interface. The button actions are set in the nib file to the seed: and generate: methods, which are implemented in the Nu source, and the text field is connected to the textField outlet, which is declared in the Nu source as an instance variable (ivar) of the RandomAppWindowController class.

All the Nu code for the application fits in one file.

;; main.nu
;;  Aaron Hillegass' RandomApp example, the nib way. 
;;  a how-to for cooking with Nu and Cocoa.
;;
;;  Copyright (c) 2007 Tim Burks, Neon Design Technology, Inc.

(load "Nu:nu")         ;; basics
(load "Nu:cocoa")      ;; cocoa definitions

;; the window controller loads and manages the window.
;; you can have as many of these running at the same 
;; time as you want.
(class RandomAppWindowController is NSWindowController
     ;; you need this to complete the outlet connection in the nib.
     (ivar (id) textField) 

     (imethod (id) init is
          (self initWithWindowNibName:"Random")
          ((self window) makeKeyAndOrderFront:self)
          self)

     (imethod (void) seed: (id) sender is
          (NuMath srandom:
                  ((NSCalendarDate calendarDate) timeIntervalSince1970))
          (@textField setStringValue:"generator seeded"))

     (imethod (void) generate: (id) sender is
          (@textField setIntValue:(NuMath random))))

;; the application delegate sets up your app once Cocoa 
;; has finished initializing itself.
(class ApplicationDelegate is NSObject
     (imethod (void) applicationDidFinishLaunching: (id) sender is
          (set $windows (NSMutableArray array))
          (10 times:
              (do (i)
                  (let ((controller 
                          ((RandomAppWindowController alloc) init)))
                       ((controller window) setTitle:
                           "#{(+ i 1)}. Yes, I can load nibs with Nu.")
                       ($windows << controller))))))

;; install the delegate and keep a reference to it since the 
;; application won't retain it.
((NSApplication sharedApplication) setDelegate:
        (set delegate ((ApplicationDelegate alloc) init)))

;; this makes the application window take focus when we've 
;; started it from the terminal (with "nuke run", for example).
((NSApplication sharedApplication) activateIgnoringOtherApps:YES)

;; run the main Cocoa event loop
(NSApplicationMain 0 nil)