Skip to content

SourceListView

UPDATE: I have released an updated version of this sample that takes advantage of improvements Apple made in Leopard (Mac OS X 10.5).

Download SourceListView

I’ve been looking for a SourceList outline view for FaceSpan that I can use under Mac OS X 10.4. A bunch of Googling revealed parts of the puzzle, but nothing that pulled all the pieces together. So I decided to produce my own SourceList view using the pieces I found.

I used iPhoto ’08, iTunes 7, Numbers ’08 and Mail as models. Here are the elements of the SourceList views in these applications that seem to be different from the stock NSTableView/NSOutlineView:

  1. Light blue background color
  2. Darker blue or blue gradient selection background
  3. The selection background color does not honor the system’s selection color preference
  4. Source Groups are not selectable
  5. Source Groups are drawn All Caps, Bold, Gray with a white shadow (appear embossed into the background)
  6. Source Group rows are a little taller than the others
  7. When inactive, the selection background turns gray, and the text switches from white to black
  8. The disclosure triangles are smaller than the ones provided by NSOutlineView (I’ve still not figured out how to accomplish this).

Here’s what I came up with:

Gradient Selection background (thank’s to Matt Gemmell’s iTableView):

itunessourcelist.jpg

Flat Selection background:

numberssourcelist.jpg

Matt Gemmell’s license seems reasonable, so I’m releasing the SourceList code under his license.

14 Comments

  1. Ok, so let me see if I get this right. If anyone uses the code that you’re providing here, he/she should give credit to Matt Gemmell???????

  2. Obviously you’d replace ‘Matt Gemmell’ with ‘Mark Alldritt’…

  3. Nice work with this.

    Just some suggestions for making SourceListView look closer to the source lists in iTunes / Leopard:

    • The colour of the embossed disclosure triangle and header should be RGB(113,125,142).
    • When the window is inactive, the selection should be a line of RGB(151,151,151) and a gradient from RGB(180,180,180) to RGB(138,138,138).
    • The source list background colour should be RGB(232, 232, 232) when the window is inactive.
    • When the window is active, the source list background colour should be RGB(214, 221, 249).
  4. This is really nice. Thanks for sharing it!

  5. As irony would have it I’ve been working on a Source List View myself this week. Your code is a bit more polished than mine, so I’ve started taking the relevant parts out of mine and tacking them onto yours. So far I’ve almost got source list item images working; I say almost since I haven’t had time yet to implement a way to set custom images, currently they just display a default folder image. If you, or anyone else is interested the modified code can be found at

  6. […] Developer Mark Alldritt posted a pretty nice bit of code (XCode project) for making nice Apple-Like menus in applications. I thought I would try to replicate this same idea with CSS. It worked out fairly well, check out the screenshot: […]

  7. This is really useful code that I suspect many other developers have been struggling to implement on their own. There’s been lots of itunes-like tableviews, but yours is the first outlineview to really hit the mark.

    Might I suggest that you add this to the MacCode Project. This is an open repository of useful source code for Mac Developers. It already houses code for Growl, AquaticPrime, Sparkle, etc.

  8. Hi Mark,

    Cool, thanks for releasing that. I’m glad you found some of my code useful!

    It’s actually a bit of a milestone for me to hear that something which uses a little of my source will end up in FaceSpan. My first ever apps were created with FaceSpan 1/2/3.x way back in the day, so this is sort of like coming full-circle for me. 🙂

    Take it easy, -Matt

  9. Soraya Soraya

    Nice work on this class!

    Apologies for a newcomer-to-cocoa-question…

    I’d like to use your SourceList on a project, but I have an issue reflecting changes when adding to the object array.

    I have downloaded the standard package and:

    1. Added an nsbutton “Add Client” (in IB)
    2. Added an NSObject for MyDocument (in IB)
    3. Linked “Add Client” to a method addClient:sender: (in IB)
    • (IBAction) addClient: (id) sender{

      NSLog(@”Pre Count: %i”, [mSourceList count]);

      [mSourceList addObject:[NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:YES], @”isSourceGroup”, @”Test”, @”name”, [NSArray arrayWithObjects: [NSDictionary dictionaryWithObjectsAndKeys: @”Party Shuffle”, @”name”, nil], nil], @”children”, nil]];

      [mSourceListView reloadData]; [mSourceListView reloadItem:nil];

      NSLog(@”Post Count: %i”, [mSourceList count]); }

    Question 1: I have tried to reload the view using both ways (nil in reloadItem should reload the entire tree) but no changes are made to the tree structure… only the array reflects the correct count… What am I missing?

    Question 2: The compiler whines about no -observedObject methods. Is it safe to replace it by -representedObject?

    Thank you!

    S.

  10. Karsten Karsten

    This is really excellent work.

    However, I tried to use it within a core data app as follows: – I started a new core data app (non-doc-based) and integrated your code, hooked up my IB, so I got the view likely as yours. This works perfectly. BTW: I changed observedObject to represented Object w/o loss of functionality. – Now I build some entities, let’s say 2, in the model: LibraryElement and DeviceElement (names just to keep changes less) and gave them a name attribute. – I dragged LibraryElement to my window next to the SourceListView, so IB gave me a full featured editable list of LibraryElements and an ArrayController.

    Now my problem: I want to change the static NSArray in mSourceList for the children node under “Library” to display the contents of my Core Data bound Array. I tried it using a NSArrayController in my app bound to the IB Controller and using arrangedObjects to set the Contents, but it’s always empty.

    Any suggestions how to use core data controller arrays with this?

    Regards Karsten

Comments are closed.