Objective-Everything Release 5. Copyright ©1994-1998 by TipTop Software, Inc. All Rights Reserved.
The TTOBCellProtocol protocol specifies the functionality that an OB cell must implement, in addition to being a subclass of NSBrowserCell. The TTOBInspectorProtocol protocol specifies the functionality that OB inspectors must implement. You can extend OB to browse any kind of information by creating your cells and inspectors conforming to these two protocols.
The TTOBCell class implements TTOBCellProtocol. By default, TTOBCell's are used to represent objects in OB. The implementation of TTOBCell makes it easy to specify cell categories, subcells, and inspectors for your own objects without the need to create an OB cell class. The example below demonstrates this.
Given the following class:
class MyTreeNode NSObject { NSString *name; id left; id right; } { method -(void)dealloc { set name [nil] set left [nil] set right [nil] super dealloc } method -(void)setNodeName:(NSString*)s { set name $s } method -(NSString*)nodeName { return $name } method -(void)setLeft:l { set left $l } method -(id)left { return $left } method -(void)setRight:r { set right $r } method -(id)right { return $right } }
Let's create an OB category for instances of MyTreeNode which displays the "left" and "right" objects as subobjects, and let's create an OB inspector which displays the names of the object (-nodeName) as well as the names of the left and right objects. This example can be found in ObjBrowser.framework/Resources/Examples/API/.
If your object implements -obGetName, the TTOBCell's -getCellName will query this method for the cell's name. (The name is displayed underneath the cell's image.)
category MyTreeNode {
method -(NSString*)obGetName { return [$self nodeName] }
}
If your object implements -obGetImage, the TTOBCell's -getCellImage method will query this method for the cell's image. The default implementation of -obGetImage for NSObject invokes +obGetImage. Hence, to associate an image both with the class object and with instances of the class, just override +obGetImage.
category MyTreeNode { method +(NSImage*)obGetImage { return [TTObjBrowser getImageNamed: [@ "MyTreeNode"]] } }
The TTOBCell's -populateArrayWithSubcellCategories: delegates loading the list of categories to your object (i.e., it invokes the object's -obPopulateArrayWithSubcellCategories:). In this example, we will have one category: MyLRCategory.
category MyTreeNode { method -(NSString*)obPopulateArrayWithSubcellCategories:(NSMutableArray*)l { # Place MyLRCategory as the first element of the list $l insertObject: [MyLRCategory object] \ atIndex: 0 return [nil] } }
Now we need to implement the category object. The TTOBCell's -populateArray:withSubcellsForCategory: method delegates loading the subcells to the category object (the category object's -populateArray:withSubcellsForCell: is invoked). We simply subclass TTOBCCategory class.
class MyLRCategory TTOBCCategory { } { # This is what's displayed in the category popup button. method -(NSString*)stringValue { return "L&R objects" } # Create subcells and add them into list l. # This method is invoked by TTOBCell's -getSubcells:forCategory: method -(void)populateArray:(NSMutableArray*)l \ withSubcellsForCell:(TTOBCell*)c { set o [$c object] set b [$c browser] set nl [$o left] set x [$b newCellForObject: $nl] if [tt $nl] { $x setStringValue: "left: [$nl nodeName]" } \ else { $x setStringValue: "left: ---" } $l addObject: $x set nr [$o right] set x [$b newCellForObject: $nr] if [tt $nr] { $x setStringValue: "right: [$nr nodeName]" } \ else { $x setStringValue: "right: ---" } $l addObject: $x # Add a label cell: set x [TTOBCLabel object] $x setStringValue: [@ "my label"] $l addObject: $x }
Finally, implement an inspector which displays the MyTreeNode's name, and the name of left and right nodes.
category MyTreeNode OBInspectors { method -obPopulateArray: {NSMutableArray l} \ withInspectorClassNamesForCategory: {TTOBCCategory t} { super obPopulateArray: $l withInspectorClassNamesForCategory: $t $l insertObject: [@ MyTreeNodeInspector] atIndex: 0 return nil } } class MyTreeNodeInspector TTOBInspector { id nameField; id leftNameField; id rightNameField; } { method +(NSString*)inspectorName { return "L&R" } method -(BOOL)wantsButtons { return no } # Load the nib file MyTreeNodeInspector.nib. method -init { return [$self initAndLoadNib] } method -(void)revert: sender { set o [$self object] $nameField setStringValue: [$o nodeName] if ![tt [$o left]] { set lname "---" } \ elseif [tt [[$o left] respondsToSelector: nodeName]] { set lname [[$o left] nodeName] } else { set lname "???" } $leftNameField setStringValue: $lname if ![tt [$o right]] { set rname "---" } \ elseif [tt [[$o right] respondsToSelector: nodeName]] { set rname [[$o right] nodeName] } else { set rname "???" } $rightNameField setStringValue: $rname super revert: $sender } method -(void)ok: sender { # .... super ok: $sender } }
set n [MyTreeNode object] $n setNodeName: "Top Node" set nl [MyTreeNode object] $nl setNodeName: "Top->L" set nr [MyTreeNode object] $nr setNodeName: "Top->R" $n setLeft: $nl $n setRight: $nr # Note: circluar... $nr setRight: $n $nl setLeft: $n browse $n