Monday, November 5, 2007

The Leopard Ate My Code

or: How I Learned to Stop Worrying and Love the Leopard

Since Tiger appeared, many people have been jumping through some interesting hoops to get the iTunes-style "inset" text appearance in metal windows. Some people draw the text twice, where the first drawing is a lighter color and offset down by one pixel. Others are now apparently resorting to image editing products to get a similar result. I've mentioned elsewhere that drawing the text twice is not necessary, and now it gets even easier with Leopard.

Update: Ken points out in a comment that drawing the text twice can have better results than using NSShadow on Tiger. It's still much easier on Leopard.

Here's a simple way to do it on Tiger, using attributed strings and NSShadow:

NSTextField* textField = something from IB;
NSShadow* textShadow = [[NSShadow alloc] init];

[textShadow setShadowColor: [NSColor
colorWithCalibratedRed: 1.0 green: 1.0 blue: 1.0 alpha: 0.5]];
[textShadow setShadowOffset: NSMakeSize(0.0, -1.0)];
[textShadow setShadowBlurRadius: 0.0];

NSMutableAttributedString* newString =
[[NSMutableAttributedString alloc] initWithAttributedString:
[textField attributedStringValue]];

[newString addAttribute: NSShadowAttributeName value: textShadow
range: NSMakeRange(0, [newString length])];
[textField setAttributedStringValue: newString];
[newString release];

Not too bad, although the color values, pixel offset, etc. are hardcoded. Now let's see how much code it takes to achieve a similar result in Leopard:

[[textField cell] setBackgroundStyle: NSBackgroundStyleRaised];

Nice.