0

I would like to have a NSMenu with several NSMenuItems in it. Those items shall behave just like "normal" NSMenuItems, with one exception: I would like to be able to draw the contents (i.e. the "foreground") of each item on my own.

That is:

  • I would like the operating system to draw the blue highlight when I hover with the mouse, draw the checkmark or dash (to signify "selected"/"part of multi-selection"). Moreover, I would like "normal", i.e. menu-built-in mouse/keyboard behaviour.

  • I would like to draw the "contents" myself: Ideally, I would imagine that I would have to implement/override one single method drawMenuItem:withCGContext:inRectangle:withTextColor, which basically obtains the item, the CGContext to draw into, the NSRect of the item, and the text color that would be used by Mac OS if it drew the item itself.

I know (suspect very stronlgy) that my wish is probably too much, but I would be perfectly fine with something adequate (e.g. I could imagine fetching the NSRect from the NSMenuItem myself, obtaining the color using something like [NSColor selectedMenuItemTextColor], and the context using something like [NSContext currentContext]).

Of course I considered Apple's instruction on this. However, doing this prevents the menu from drawing the blue highlight background and the check mark. Moreover, as far as I could see, I would have to implement e.g. mouseUp myself.

To sum it up: Is there a way to get a (almost) fully functional menu, where I only customize the contents where usually the menu item title goes (possibly even without custom views)?

phimuemue
  • 34,669
  • 9
  • 84
  • 115
  • Can't you set the image of the menu item? – Willeke Feb 01 '17 at 13:49
  • @Willeke I thought about this, but was somewhat hesitant since I do now know whether that's what the image originally was conceived for. Moreover, I was not sure whether it is straightforward to change the foreground color dynamically, based on the "highlight" state of the `NSMenuItem`. – phimuemue Feb 01 '17 at 14:02

1 Answers1

2

The answer is: No.

Since you are replacing the entire view of the menu item you are responsible for the drawing and to handle the events.

vadian
  • 274,689
  • 30
  • 353
  • 361
  • Your answer is probably true. But couldn't it be that I possibly do not have to use a custom view in the first place? I was hoping that there is some technique, possibly without a custom view, to acchieve what I am after. – phimuemue Feb 01 '17 at 12:58
  • Unfortunately `NSMenuItem` inherits from `NSObject` so there is no (public) view related API to override. – vadian Feb 01 '17 at 13:05
  • True, and I observed in the view hierarchy debugger that an `NSMenu` with plain vanilla items does not contain subviews for each item, but instead seems to draw everything in the `NSView` of the whole menu. So I thought: "maybe I could subclass this one..." – phimuemue Feb 01 '17 at 13:08
  • I saw that you can install an image for an `NSMenuItem`. Couldn't I e.g. just use an image filling the whole item? – phimuemue Feb 14 '17 at 17:19
  • Yes you can, but the layout constraints are predefined that the image is displayed on the left side next to the text field. Just try it. – vadian Feb 14 '17 at 17:23