A xibless UI script is a Python script that describes a UI to build through Objective-C code that xibless is going to generate from that script. It creates objects like Window or Button, sets their properties and place them in their superview.
When a UI script is generated, it creates an Objective-C unit with one function that takes one argument, the “File Owner”, and returns the script’s result (see next section). Here’s an example of what its signature might look like:
NSWindow* createMainWindow(AppDelegate *owner);
Every class described in the xibless API section are directly in the script namespace. Therefore, if you want to create a Label, you do it thus:
label = Label(parent, text="hello!")
Other than class references, there’s also a few special variables to keep in mind.
result = Window(400, 200, title="My Window")
button.action = Action(target=owner, selector='myAction:')
owner.mySuperButton = button
menu.addItem("Quit", action=Action(NSApp, 'terminate:'), shortcut='cmd+q')
ownerimport = 'AppDelegate.h'
ownerclass = 'AppDelegate'
Some widget attributes require literal constants from the Cocoa framework. For example, NSButton.state is either NSOnState, NSOffState or NSMixedState. You can’t use strings to set these values because they will be wrapped around @"" during code generation. When you need these types of values, use the const identifier which is present in the UI script namespace. For example:
findMenu.addItem("Find...", Action(None, 'performFindPanelAction:'), 'cmd+f', tag=const.NSFindPanelActionShowFindPanel)
The API documentation will indicate when such a constant is required. Ideally, there will be a constant in xibless (see Constants) wrapping every Cocoa constant, but doing so is boring work and I’m often too excited doing not-boring work to spend time wrapping constants. But eventually...
Bitwise OR-ed flags. Some attributes are actually masks, which required bitwise-OR-ed values. Well, you can do that in xibless. Use the | char as in const.flag1 | const.flag2.
Everything created inside a UI script is auto-released, which means that you have to retain it when you store the result and in your owner’s properties set by the script.
Of course, if an object is “naturally” retained by another object created in the script, such as a NSMenuItem added to a Menu or a view added to a superview, then you don’t have to manually retain those objects.
xibless being in early development, it doesn’t support everything Cocoa has to offer yet. If you find yourself in a situation where an attribute you want to set on an instance isn’t supported, you can always try to set it in its properties dictionary, for example with:
foo.properties['delegate'] = bar
It’s not guaranteed to work, but it very well might.
In XCode’s interface builder, it’s possible to specify a custom class to instantiate instead of the base class. For example, if you have a home grown NSTableView subclass and want to instantiate it in an XIB, you’d change the table view’s class name to MyTableView. In xibless, you can do the same by setting the OBJC_CLASS attribute in this fashion:
table = TableView(window)
table.OBJC_CLASS = 'MyTableView'
Of course, as is the case with XIB’s your custom class will be instantiated with the same arguments as a typical NSTableView would.
Because UI scripts are Python modules, it’s possible to import from other modules. The folder in which the UI script is will be in PYTHONPATH, so you can do stuff like add a common.py unit and then do from common import MyLabelSubclass in your UI scripts.
The only thing to remember, however, is that the magic that goes on in UI scripts to put all xibless classes in your UI script’s global namespace doesn’t work for imported modules. Therefore, if your module use any xibless classes, you have to import them yourself from the xibless package (and you’ll have to figure out where they live in the package). That’s far from ideal, I’ll fix that some day.