3

I've recently come across a problem with a custom NSButtonCell subclass. We have a dark interface with white text, and all is going as expected, until we try to make a default button (i.e. assigning a key equivalent of \r). What we get seems mysterious: The bezel draws, but the text doesn't. But if I make the text black, it draws. If I make the text white with a black shadow, only the shadow draws!

The mystery started to unravel when I tried a test with the text set to [NSColor redColor] on a lark. (The "Create" button here has a key equivalent of \r, "Cancel" is Esc.)

red button test

What I eventually figured out is that the default button's cell is drawing into a bitmap context, presumably so that the rendered glyphs can be cached for the animated blue pulsing background that the Aqua look gives. That makes total sense, but the surprise is that that bitmap is then drawn with a multiply compositing operation. Hence black shows up and white doesn't, and anything in between shows up darkened.

I've managed to hack a workaround, by taking the text rendering out of -drawTitle:withFrame:inView: and doing it in -drawBezelInFrame:inView: instead. But that gets called repeatedly, so I'll need to manually cache the image. Plus it's just conceptually ugly, because it's specifically the wrong method for rendering the title!

My question: Surely there must be a better way, right? Is there some way to tell the button cell not to automatically use this offscreen rendering path even though the button is default?

4

0 回答 0