I wanted an NSBrowser with checkboxes for Arq to replace its ugly file-selection mechanism. Some type of file tree with checkboxes UI (like Dropbox and Crashplan use) seemed like a good fit, and I prefer NSBrowser to a (potentially gigantic) NSOutlineView. But I was stumped as to how to get checkboxes in an NSBrowser.
Searching the net gave me some clues, like I should subclass the cell that the NSBrowser uses and call [NSBrowser setCellClass:], but searching also led me down some fruitless paths. Contrary to what you may have read, don’t subclass NSBrowserCell — it’s unsubclassable.
Finally I stumbled on Apple’s ComplexBrowser sample code. It uses a subclass of NSTextFieldCell. And it gives some clues on how to capture the checkbox click.
The Code
When I began my search, I was hoping to find someone’s sample project that did just what I wanted, but no luck. So I’m publishing my sample project for the next person who goes looking for such a thing:
https://github.com/sreitshamer/FSBrowser
Enjoy!
- Stefan
“Contrary to what you may have read, don’t subclass NSBrowserCell — it’s unsubclassable.”
What do you base this on?
I don’t believe it to be true.
I subclassed it and got random intermittent crashes. I tried everything I could think of to debug it, including overriding retain/release/copyWithZone/etc. I switched to subclassing NSTextFieldCell like Apple’s sample code, and it worked great.
Do you have code you can share that subclasses NSBrowserCell successfully?
The secret is to override copyWithZone:, but you have to do it like this:
@interface CBrowserCell : NSBrowserCell { id anIVar; }- (id) copyWithZone: (NSZone*) zone {
CBrowserCell* obj = [super copyWithZone: zone];
obj->anIVar = [anIVar retain]; // MUST zero or copy/retain all added i-vars
return obj;
}
@end
Without this you WILL get ‘random’ crashes, notably when Cocoa tries to display expansion tool-tips. (Displaying one of these tool-tips deallocates a copy of the target cell.)
Typically this does not appear to be documented anywhere, but It does work 100%.
If you don’t add i-vars you don’t need to override copyWithZone:.
Thanks Chris. I learned during the process that NSCell was using NSCopyObject, so I did handle my ivars appropriately in copyWithZone:, but couldn’t get it to work. If your code works, then apparently I was doing something wrong. I don’t have the code anymore to check.