I am creating a custom view for an NSMenuItem
. In order to draw the background when selected, I adapted a couple of lines from the CustomMenus sample. The CustomMenus sample has:
[[NSColor alternateSelectedControlColor] set];
NSRectFillUsingOperation(dirtyRect, NSCompositeSourceOver);
.. and I am using the selectedMenuItemColor because the alternateSelectedControlColor was a solid color and it did not look very good:
[[NSColor selectedMenuItemColor] set];
NSRectFillUsingOperation(dirtyRect, NSCompositeSourceOver);
Using selectedMenuItemColor is better, but it's still not exactly the same as a real selected NSMenuItem
.
Here is a screenshot showing the real selected NSMenuItem
background on the left and the selectedMenuItemColor on the right in the "Blue" appearance:
You can see that there is an additional translucent white gradient overlay on the real selected NSMenuItem
background.
How do I replicate the real selected NSMenuItem
background?
EDIT: This is for Mac OS 10.9.5.
EDIT2: Here is a side-by-side comparison in the "Graphite" appearance:
Through trial and error I came up with the following code that draws a background almost indistinguishable from the real selected NSMenuItem
background in both "Blue" and "Graphite" appearances:
[[NSColor selectedMenuItemColor] set];
NSRectFillUsingOperation(dirtyRect, NSCompositeSourceOver);
if (dirtyRect.size.height > 1) {
const NSControlTint currentControlTint = [NSColor currentControlTint];
const CGFloat startingOpacity = (NSBlueControlTint == currentControlTint ? (CGFloat)0.16 : (CGFloat)0.09);
NSGradient *grad = [[NSGradient alloc] initWithStartingColor:[NSColor colorWithWhite:(CGFloat)1.0 alpha:startingOpacity] endingColor:[NSColor colorWithWhite:(CGFloat)1.0 alpha:(CGFloat)0.0]];
const CGFloat heightMinus1 = (CGFloat)(dirtyRect.size.height - 1);
[grad drawFromPoint:NSMakePoint(dirtyRect.origin.x, dirtyRect.origin.y + heightMinus1) toPoint:NSMakePoint(dirtyRect.origin.x, dirtyRect.origin.y + 1) options:0u];
if (NSBlueControlTint == currentControlTint) {
[[NSColor colorWithWhite:(CGFloat)1.0 alpha:(CGFloat)0.1] set];
NSRectFillUsingOperation(NSMakeRect(dirtyRect.origin.x, dirtyRect.origin.y + heightMinus1, dirtyRect.size.width, (CGFloat)1.0), NSCompositeSourceOver);
}
}
Here are side-by-side comparisons:
The left halves (80px) of the two images show the real selected NSMenuItem
background and the right halves of the two images are the result of the code.