I Love Outline Views - Here’s Mine

October 24, 2008

Apps like Coda are the de-facto standard for good user-interface design nowadays. You can do a lot with the standard Cocoa controls provided by Apple, but you can’t always get exactly what you want out-of-the-box. For example, the CSS edit section of Coda has a fantastic way of dividing tasks: the animated outline view.

Rather than having a monolithic view that has all the controls grouped with dividing lines; each section, “Text”, “Colors and Background”, “Dimensions”, all exist in their own collapsible view. Clicking the separating bar animatedly expands or collapses the view.


To make one of these views isn’t quite as easy as you first think, and you can quickly go down the wrong road in the design. The super-secret trick is to *not* use Core Animation, or more precisely: ignore the lure of NSViews conformance to the NSAnimatablePropertyContainer protocol. As of Mac OS X 10.5, a few of the properties of a view or window can be animated simply be replacing calls like [view setFrame:newFrame]; with [[view animator] setFrame:newFrame];. This is fine when you have one or two views that you want to move but it’s impossible to coordinate the movements of multiple view using this API. After using Core Animation, one would expect that after a call such as [[view animator] setFrame:newFrame]; requesting the frame from the view would return newFrame. Unfortunatley it returns the original frame of the view. Only when the animation is done, do you get newFrame. Furthermore, just try setting the delegate of the CABasicAnimation object that handles the implicit animation and getting any form of useful information back. You can’t. You’re in for a world of pain if you try.

The solution: use good-ol’ NSViewAnimation. That way you can create all the dictionaries containing the animations for all the views you want to, then instantiate one NSViewAnimation object to handle the lot and set them off at the same time. Simple.

The Animating Outline View

The outline view is made up of a few classes, the TLDisclosureBar, a subclass of the highly-configurable TLGradientView; the TLCollapsibleView which has a TLDisclosureBar and any NSView you like as its subviews. A TLCollapsibleView itself can be used alone, and will animate the collapse/expansion of the NSView subview (which I term the “detail view”).

The fun part comes when TLCollapsibleViews are subviews of a TLAnimatingOutlineView. In this case, the TLAnimatingOutlineView takes over all the animations, simply asking the TLCollapsibleView that the user has selected for the NSDictionary object that describes the collapse/expansion animation. With this information, it constructs the movement animations for all the subviews below the collapsing/expanding view and handles the required change of frame size to accommodate the changing content size. It’s all quite elegant, if I do say so myself.

Not being content with example code, I’ve made sure these classes are real-world useful. This view is integral to BibTeX management in Scribbler so it needs to be good. Some of the relevant parts of the NSOutlineView API are replicated and the delegate of the TLAnimatingOutlineView gets will/did/expand/collapse notifications, along with allowing the delegate to deny/allow animations, too. Each of the TLCollapsibleViews will also ask their detail views if the collapse/expansion is allowed if the TLCollapsibleDetailView protocol is implemented. The TLAnimatingOutlineView itself works when in an NSScrollView.

The code, along with an example project, is hosted on Google Code here. It is distributed under the new BSD license.

So why is is not ESAnimatingOutlineView, why the TL namespace? Well, I’m working on something big, at the same time as writing Scribbler. Start guessing.

Update

I’ve fixed a few bugs in the code, the current version can be checked out of the repository. Fixes include: proper support for hiding subviews of the TLDisclosureBars when the outline view is resized small, a correction to the autoresizing mask of the TLAnimatingOutlineView itself, declaration of keys that the TLCollapsibleView supplies with the animation dictionaries, the delegate of the outline view and subclasses of TLGradientView are no longer unregistered for notifications that client code specifies (i.e. no longer uses [[NSNotifcationCenter defaultCenter] removeObserver:_delegate];).


Creating iTunes Scrollers

June 18, 2008

Apple introduced new scrollers in iTunes 7 and then moved on to give us the HUD, which many developers want their own scrollers for too. In Leopard, many of us thought that these would come in a nice, shiny box; but as they didn’t we’re all forced to roll our own. The common method is to draw all the components in Photoshop and then make a composite image when subclassing, but now with NSGradient and some nice additions to NSBezierPath all these have become quite easy to do, even for those with little artistic ability.
Read the rest of this entry »


NSTreeController and Core Data, Sorted.

May 13, 2008

Having recently taken the plunge into Core Data I decided it was time to rip out all the model code from my current application and replace it with a Core Data version. After about a day I had my app up and running again but with one huge problem, the content of my NSOutlineView always appeared in a random order. Such is the problem with Core Data that NSManagedObjects store their to-many relationships in an NSSet, not an NSArray, which is unordered. So when your NSTreeController tries to display its data it appears in a random order.

This is not nice, imagine if the playlists in your iTunes library always changed their order? It gets even worse if your user wants to use drag and drop. In this case they decide the order, and they’d probably want it to stay that way.
Read the rest of this entry »


Using NSTreeController

April 6, 2008

A common UI concept in Mac development is that of the source list, which everybody knows from iTunes, iPhoto, etc. To do this, NSTreeController can come in particular handy, although it can come with a bit of a headache as the API is somewhat lacking and a proper model is essential to making this easy to use.  I’m going to go over the solution that’s worked for me.
Read the rest of this entry »


DRM-Free Tracks to be Sold on iTunes

April 2, 2007

Gracefulflavor

I understand why people don’t particularly like DRM on their tracks, but let’s not forget that it allowed the iTS possible. I’m hesistant to hail this is a killer move; but a great option, yes.

I wonder how long it will take for all the non-DRM tracks to be available over sharing networks like BitTorrent. Call me naïve but I do think that too many people will take advantage of this to get more free music. I know lots will be careful enough to not put them in a shared folder for the world t see, but there’s many stupid people out there.

I’ll get slated for this, but I like DRM, it has allowed me to get the music I want, simply and cheaply. The iTS enabled me to buy music, rather than paying for overpriced CDs. Having the option to choose your player is great, but I love iPods, and I think its very important that people don’t steal.

Anyway, if I wanted to put all my stuff on another player I’d burn it and rip it(which would take forever), I’d never share it, I have a conscience. Please don’t think I’m implying everyone who has non-DRM music is a criminal, but there are enough people out there who copy music to damage iTunes sales in the long-run.

The best part of this is the higher bit-rate of these unprotected tracks. I’ll buy some for that reason alone, but don’t expect to get them off me!

UPDATE: Just listening to the news on BBC Radio 1, only the biggest radio station in the UK, broadcast worldwide; and what was their headline?

“Why it will now be a little easier for you to share music with your mates.”

That’s irresponsible.


Klingon Language in Mac OS 10.4?

March 23, 2007

Klingon Language in 10.4

Can somebody please tell me why I have KLINGON language support on my computer! Well, when I turned it on, no programs had a Klingon interface, but still. I think someone somewhere has way too much time on their hands. And yes, the reason I know that it says Klingon is because I used to watch Star Trek avidly, like you wouldn’t believe. I’m kinda glad those days are gone now, I still appreciate it but one day I just stopped watching. I think the sun was shining outside, so I went out.


Macworld 2007

January 9, 2007

Well, I have to say it was a let-down. After all the rumours of upgraded Mac computers, more on the upcoming Leopard operating system and new iLife and iWork applications, the keynote at the expo in San Francisco was disappointing. Don’t get me wrong, the iPhone looks excellent, and seems to be the phone I’ve been wanting for such a long time. Finally we have one that is intuitive and simple to use, but does so much you want it to do. The touch screen is a fantastic addition, and the only way to allow a complicated phone to be operated. I don’t mind about the price of it, or the availability in the fourth-quarter of 2007 here in the UK, but I was expecting more about the Mac. The Apple TV isn’t bad too, but I would never need anything like that, especially since the rumoured TV and Movie download service from iTunes in the UK didn’t come to fruition.

For a computer company, I think many people will be disappointed at the lack of computing innovation at the expo, and the loss of ‘Computer’ from the the name ‘Apple Computer Inc.’ may, for some, hail the beginning of the end for the Mac. I’m not so pessimistic, but I would definitely be loathed to return to using Windows after 3 years of an iMac doing everything I wanted to do, and more.