Beginner's Cocoa question: acting on dynamically added menubar items

Discussion in 'Mac Programming' started by Thomas Harte, Nov 17, 2006.

  1. Thomas Harte macrumors 6502

    Nov 30, 2005
    Hi, although I have a few years experience with C, C++ and the Mac, I'm a real beginner with Objective-C and Cocoa. I actively maintain a cross-platform emulator which is at heart an SDL application sitting behind a Mac-specific menubar and preferences dialogue. The port was initially done by someone else, but I've subsequently been maintaining it and I'm 100% confident with Interface Builder, interfacing that with Xcode and using the controller model view paradigm. In fact what I effectively have is a nib based view, an Objective-C controller and a C++ model with the model being platform independent.

    Anyway, what I want to do now is add a dynamic menu bar entry. The machine my emulator emulates supports plug-in ROM cartridges, and it supports (in my implementation) up to 8 of them simultaneously. So what I want is a "ROMs" entry on the menu bar, with the top entry being "Insert ROM..." leading to a standard file dialogue, then a separator bar and a separate entry "Remove <ROM name>" for every currently inserted ROM. So you add a ROM with Insert ROM... then it appears in the emulated machine and gets a remove entry on the list on the ROMs menu. You click remove and the ROM is removed.

    I've added a ROMs entry on the menu bar in Interface Builder with an "Insert ROM..." option, set up a suitable NSMenu outlet and action and can add ROMs to the menu using the addItemWithTitle: method on the NSMenu outlet.

    My only problem is how to react to the dynamically added "remove ROM" entries. At the minute I'm using a single method named removeROM: as the action for all remove ROM menu entries. So my dilemma is: how can I find out which entry called removeROM? This is where my chronic lack of Objective-C knowledge trips me up. I'm guessing the answer is in the (id)sender that every method seems to take as an argument but I'm not even really sure what that is.

    As a hack I could implement multiple removeROM functions and keep an internal note of which one is used by what, but that wouldn't be a very neat solution. So can anybody point me in the direction of some help? I have the "Cocoa for Dummies" book but it doesn't really cover anything like this — which isn't that surprising really.
  2. kpua macrumors 6502

    Jul 25, 2006
    The sender in
    - (IBAction)someAction:(id)sender
    is the UI element that sent the action. So in your case, it would be the NSMenuItem itself.

    Here's a possible solution to your problem:
    1. Set unique tags for each menu item you add to the menu.
    2. Get the tag in your removeRom: method with [sender tag];
    3. Map the tag to an index in your model's list of ROMs.
    4. Remove the ROM from the list, and update the UI.
    Does this correctly solve your problem? Is it understandable?
  3. Thomas Harte thread starter macrumors 6502

    Nov 30, 2005
    That solves my problem perfectly. I'm such a Cocoa know nothing that I hadn't even heard of tags. But that's everything I needed — it means my removeROM can easily figure out which menu entry called it, so thanks!

Share This Page