NSBrowser Datasource Implementation Notes

Continuing the discussion from UI Browser Documents:

UI Browser differs from many NSBrowser-based applications in that the model array is created and maintained on the fly, as the browser is being used, based on the current selection. Apple’s SimpleCocoaBrowser and ComplexBrowser example code demonstrate the use of the item-based datasource delegate methods with an underlying data source that is an existing, fully built, static data hierarchy. UI Browser, by contrast, builds the underlying hierarchy on the fly, adding and removing columns as the user selects specific cells. Pruning and rebuilding the array lazily in this fashion allows rapid initialization of the first column, minimizes work required to respond to changed selection, and keeps the datasource small.

The question is where, when and how to add columns to the underlying model object so that the item-based datasource delegate methods will have data to work with when the user makes a new selection.

The browser(_:selectRow:inColumn:) method seems like a good candidate, but it only fires in response to programmatic selection, which may typically be used only for automatic selection of the first column when the browser is initially set up.

For user clicks to select a cell, the answer is the browser(_:selectionIndexesForProposedSelection:inColumn:) method. It fires after the user’s click and before the selection is actually made, so it is a perfect time to update the model array by adding the children of the proposed selection.

(The problem with UI Browser as it stands is that the first two columns are pre-installed. This can only be done in the first two columns only because column 1 can never have more than 1 root application UI element. So when the user clicks column 1, its children are already loaded in column 2. But when the user clicks column 2, nothing has been loaded into column 3 yet. So the click must add the clicked item’s children.)