Cocoa: Sidebar with Badges, Take 2
March 8, 2009 Matteo Bertozzi | Filed Under Cocoa | 13 Comments
Do you remember the Cocoa Sidebar? No, Take a Look at this post Cocoa Sidebar with Badges.
Joel asked me to revise the Sidebar, allowing to add/remove and do other operation at any time.
I’ve rewritten all the code of the Sidebar, and I’ve added a couple of new features, like the default action handler and obviously the ability to add, remove items and badges at any time.
All the past features, like Drag & Drop are still present, but there’s something else to do to improve it. If You’ve suggestions, patches or something else post a comment or send me a mail!
The Source Code is Available Here: Cocoa Sidebar 2 Source Code.
Update 10 March 2008 – Source Updated with Fixes.
Hi Matteo,
Are we free to use this in commercial applications? If so, under what license?
Thanks,
Rein
Comment by Rein — March 9, 2009 #
Hi, All the source code here, is Free to use. Qt4 Sources are released under LGPL license while other sources are under BSD license. Take a look at Source Code Page and let me know about your app!
Comment by Matteo Bertozzi — March 9, 2009 #
Looks perfect.
One small thing, shouldn’t the numbers in the circles be helvetica bold?
Mail.app and iTunes.app uses helvetica
Comment by Gordon S — March 9, 2009 #
I ran it and got a bunch of errors about a missing autorelease pool when clicking an item in the list. I didn’t have time to track the bug down but thought I’d let you know.
Comment by Hjalti — March 9, 2009 #
Not sure why my previous comment got deleted. There’s a bug in the code. The action performed when clicking an item detaches a new thread which displays an alert. In general you shouldn’t mess with the gui in threads but since it’s only for demonstration it’s not a big deal. Either way, you should call [target performSelector… instead or at least provide autorelease pool in the selector that the thread runs.
- H
Comment by Hjalti — March 9, 2009 #
Just, updated the source to fix leaks. Thanks for feedback.
Comment by Matteo Bertozzi — March 10, 2009 #
Very good job. Thanks a lot.
Comment by Paisible.fr — March 10, 2009 #
Hi, any chance of an update to match the colors of the Leopard Finder? And do you think its possible to change the background color when the window isn’t in focus.
Comment by zebrum — March 23, 2009 #
Here you go:
[self setBackgroundColor:[NSColor colorWithCalibratedRed:214.0/255.0 green:221.0/255.0 blue:229.0/255.0 alpha:1.0]];
Comment by zebrum — March 23, 2009 #
Ok just add this to Sidebar.m to make it more like the other apps:
- (void)drawRect:(NSRect)rect{
BOOL isWindowFront = [[NSApp mainWindow] isVisible];
if(isWindowFront){
[self setBackgroundColor:[NSColor colorWithCalibratedRed:214.0/255.0 green:221.0/255.0 blue:229.0/255.0 alpha:1.0]];
}else{
[self setBackgroundColor:[NSColor colorWithCalibratedRed:232.0/255.0 green:232.0/255.0 blue:232.0/255.0 alpha:1.0]];
}
[super drawRect:rect];
}
Comment by zebrum — March 24, 2009 #
sorry found another bug, Sidebar.m:170 requires this:
[node setData:data];
Otherwise on your button handler the [node data] is nil.
Comment by zebrum — March 25, 2009 #
Btw I agree with Hjalti that this code shouldn’t be spinning off threads. If someone is loading megs of data it is usually their own responsibilty to do it in a background thread, and they expect any UI class to fire events on the main UI thread. I’m seeing some insconsitant behavior just now with the list items sometimes not showing up. Calling tableView’s reloadData from a thread like the sample app does is definately not a good idea.
Comment by zebrum — March 25, 2009 #
last thing, my inconsistant behaviour was due to the fact you used awakeFromNib for initialisation. Typically, you implement awakeFromNib for the class you associate with the “File’s Owner” of the nib file because the loading order is random. Thus my controller’s awakeFromNib could fire and I’m setting things on the side bar when it hasn’t been initialised yet. The solution is for you to use this instead Sidebar.m:37:
- (id)initWithCoder:(NSCoder *)decoder
{
self = [super initWithCoder:decoder];
_contents = [[NSMutableDictionary alloc] init];
_roots = [[NSMutableArray alloc] init];
etc….
etc….
return self;
}
Btw I figured this out from the “Important” box on this page:
http://developer.apple.com/DOCUMENTATION/Cocoa/Reference/ApplicationKit/Protocols/NSNibAwaking_Protocol/Reference/Reference.html
Comment by zebrum — March 25, 2009 #