Sunday, March 8, 2009

Cocoa: Sidebar with Badges, Take 2

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.

20 comments:

  1. Hi Matteo,

    Are we free to use this in commercial applications? If so, under what license?

    Thanks,
    Rein

    ReplyDelete
  2. 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!

    ReplyDelete
  3. Looks perfect.

    One small thing, shouldn't the numbers in the circles be helvetica bold?

    Mail.app and iTunes.app uses helvetica :)

    ReplyDelete
  4. 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.

    ReplyDelete
  5. 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

    ReplyDelete
  6. Just, updated the source to fix leaks. Thanks for feedback.

    ReplyDelete
  7. 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.

    ReplyDelete
  8. Here you go:

    [self setBackgroundColor:[NSColor colorWithCalibratedRed:214.0/255.0 green:221.0/255.0 blue:229.0/255.0 alpha:1.0]];

    ReplyDelete
  9. 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];
    }

    ReplyDelete
  10. sorry found another bug, Sidebar.m:170 requires this:

    [node setData:data];

    Otherwise on your button handler the [node data] is nil.

    ReplyDelete
  11. 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.

    ReplyDelete
  12. 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

    ReplyDelete
  13. Thanks for this great piece of code!
    I have one problem though - if I integrate this code into my project, the image, the badge, and the custom font get lost. It just looks like the average source list. Drag'n'drop still works.
    Do you know what could be to blame here? I have not found any codeparts where custom drawings or something take place, is there some kind of magic involved here? :)

    Thx & Best Regards,
    M.M.

    ReplyDelete
  14. Also note you can get all the pretty Finder icons for example

    [[NSWorkspace sharedWorkspace] iconForFileType: NSFileTypeForHFSTypeCode(kToolbarDesktopFolderIcon)]
    osx 10.6+

    Just checkout Iconscore.h for them all

    ReplyDelete
  15. Anyone used this code with CoreData? I would like to connect this with an some type of controller for easier undo/redo among other things.

    ReplyDelete
  16. Anyone having tip how to get ALL sidebar items showed ALL TIMES? Thanks.

    ReplyDelete
  17. The provided link seems to be broken...
    Does anyone know where I can download the source code ?
    Thanks ;-)

    ReplyDelete
  18. All files are available at github https://github.com/matteobertozzi/blog-code/tree/master/zips

    https://github.com/matteobertozzi/blog-code/blob/master/zips/cocoa-sidebar2.zip

    ReplyDelete
  19. ok great, thanks for your quick reply and work :-)

    ReplyDelete