I recently ran into a problem with a custom subclass of NSButtonCell. We have a dark interface with white text, and everything goes as expected until we try to make the default button (i.e., Assign a key equivalent \r). What we get seems mysterious: the frame draws, but the text does not. But if I make the text black, it draws. If I make the text white with a shadow shadow, the shadow draws only!
The mystery started to unravel when I tried the test with the text set on [NSColor redColor]the lark. (The "Create" button here has a key equivalent \r, "Cancel" - Esc.)

In the end, I realized that the button cell by default draws into a raster context, apparently so that the displayed glyphs can be cached for an animated blue pulsating background that gives an Aqua look. This makes general sense, but the surprise is that the bitmap is then drawn using the multiple-link operation. Consequently, blacks appear, but white ones do not, and everything in between becomes dark.
I managed to crack the workaround by extracting text from -drawTitle:withFrame:inView:and executing it in -drawBezelInFrame:inView:. But this is called multiple times, so I will need to manually cache the image. Plus, it's just conceptually ugly, because it's a specially wrong method for rendering a name!
My question is: Of course, there must be a better way, right? Is there a way to tell the button cell not to automatically use this on-screen rendering path, even if the button is the default?
source
share