[Openmcl-devel] Deep menu magic
plkrueger at comcast.net
Tue Feb 2 14:08:29 UTC 2010
To answer your last question first, even though #/
addItemWithTitle:action:keyEquivalent: doesn't let you specify an
argument that gets passed back when the action is invoked, you don't
need one. All controls also pass themselves as an argument when their
action selector is invoked. So you can specify the same action for
every menuitem and just look at the #/title of that menuitem argument
to find out which one was selected.
Let me start the rest of my answer by saying that I don't absolutely
KNOW how Apple implemented their "Recent" menu functionality and a
quick search through their documentation didn't help all that much.
But with that said I can make some educated guesses about what they did.
There is some old example code (titled "RecentItems") for a recent
menu that you can browse or download from the Apple Developer web
I didn't find that all that helpful since it seems to create menuitems
and add them to the menu for each document that opens. If you don't
need to update your menu more dynamically than that, then that
approach could work for you. Simply add or subtract menuitems from
your menu whenever it's appropriate.
There are a couple of reasons why you might want to make the
determination of menuitems more dynamic. If you open and close files
frequently so that the contents of the menu would be changing all the
time, then it might be beneficial to wait until just before the menu
is opened to decide what should be in it. Also if you don't expect the
menu to be used very often, then there isn't any point in updating it
all the time. I suspect that Apple dynamically determines the
menuitems for their recent menu for similar reasons.
One easy way to do that is to set a delegate object for the menu and
in that delegate implement the #/menuNeedsUpdate: method. This is
called immediately before displaying a menu. There you could implement
code to set up whatever menuitems are currently appropriate. Doing it
this way you wouldn't be constantly creating and destroying menuitems.
This would provide you with a hook to set them when needed.
But it seems to me that if Apple had implemented their code this way
that you would still see the most recent list of menuitems in the list
that you displayed in the listener (unless of course they immediately
remove all those menuitems as soon as the menu is no longer
displayed). So I'm betting that they are even a bit trickier than
this, but I'll refrain from speculating because I'm betting that you
don't need to do exactly what they did and some variation of the above
On Feb 1, 2010, at 7:44 PM, Ron Garret wrote:
> I'm trying to create a context menu that works kind of the the File-
> >Open Recent menu, that is, it has a dynamically changing list of
> selections. In trying to figure out how to implement this, I went
> poking around inside the Open Recent menu and discovered to my
> surprise that the file items don't actually seem to be there:
> ? (#/submenu (#/itemAtIndex: (#/submenu (#/itemAtIndex: (#/mainMenu
> #&NSApp) 1)) 3))
> #<NS-MENU <NSMenu: 0x5b5090>
> Title: Open Recent
> Supermenu: 0x5b50d0 (File), autoenable: YES
> Items: (
> "<NSMenuItem: 0x1285d0 Clear Menu>"
> ) (#x5B5090)>
> Where are the file items (and the separator for that matter)? Can
> someone point me to a description of how menus like this actually
> work? (In particular, what are the item actions on these
> dynamically generated menu items? #/
> addItemWithTitle:action:keyEquivalent: doesn't let you pass an
> argument to the selector, so to make something like Open Recent work
> using that method you'd need a separate selector for each item.
> Which is possible, but seems pretty ugly.
> Openmcl-devel mailing list
> Openmcl-devel at clozure.com
More information about the Openmcl-devel