Question

I have built an NSDictionary containing several nested layers, and I want to replicate this as an NSMenu such that when my NSDictionary updates so does my NSMenu. For example, if I have an NSDictionary containing:

Item1
 |---Item 1.1
 |---Item 1.2

Item2
 |---Item 2.1
 |    |---Item 2.1.1
 |---Item 2.2
 |---Item 2.3 

Item3

This should result in my menu being built with three entries - Item 1, Item 2 and Item 3. Item 1 and Item 2 should be sub menus, as should Item 2.1 and so forth.

If I delete Item 2 then Item 2, and all its submenus, should be deleted also.

The problem is that I have no idea how to approach this. I know how to make an NSMenu programmatically, so I'm not approaching this with no knowledge whatsoever, but I haven't got the first idea how to simulate a binding in this manner.

Any help would be most gratefully received.

Was it helpful?

Solution

The way to do this is to set-up an object as a menu delegate (see NSMenuDelegate). I set the menu item's tag to a unique value and then find that menu item during startup. I use the App Delegate as the menu delegate and then build the menu by implementing the following delegate methods:

- (NSInteger)numberOfItemsInMenu:(NSMenu *)menu;

- (BOOL)menu:(NSMenu *)menu
  updateItem:(NSMenuItem *)item
     atIndex:(NSInteger)index
shouldCancel:(BOOL)shouldCancel;

You have the added complication of arbitrarily complex dictionary structure, so you need to create a custom class to store each menu item (the menu text and the selector, as a string, along with anything else you might need). Then store these items and any sub-dictionaries within the main dictionary.

When you come to enumerate the dictionary (in the menu:updateItem:atIndex:shouldCancel: delegate method) you will need test the type of the object (custom object or dictionary) using isKindOfClass and in order to deal with the arbitrary nesting, you probably want to use a private, recursive, method that deals with a single dictionary.

Good luck; it's not simple but certainly achievable.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top