Reputation: 9686
How can I make sure a method gets called each time I expand a NSMenu. I have tried connecting the action from storyboard but the action only seem to get fired when i click menu items, not the menu itself.
[item setAction: @selector(play:)]
I would like to run a method when for instance the help menu gets expanded, to update the enabled and disabled content of that menu, since it is supposed to be different for logged in and not logged in users..
Update:
I added the NSMenuDelegate protocol in brackets in my
@interface ClientAppDelegate : NSObject<NSApplicationDelegate,NSMenuDelegate>
Adding menu items work but the menu does not seem to affect the delegate methods.
// Create the application on the UI thread.
- (void)createApplication:(id)object {
NSApplication* application = [NSApplication sharedApplication];
[NSBundle loadNibNamed:@"MainMenu" owner:NSApp];
// Set the delegate for application events.
[application setDelegate:self];
// Add the Tests menu.
NSMenu* menubar = [application mainMenu];
[menubar setDelegate:self];
// TIDAL Create Controlls
NSMenuItem *controlsItem = [[[NSMenuItem alloc] initWithTitle:@"Controls"
action:nil
keyEquivalent:@""] autorelease];
NSMenu *controlsMenu = [[[NSMenu alloc] initWithTitle:@"Controls"] autorelease];
AddMenuItem(controlsMenu, @"Pl", ID_L_PL);
[controlsItem setSubmenu:controlsMenu];
[menubar addItem:controlsItem];
......
-(void) menuWillOpen:(NSMenu *)menu{
wprintf(L"ITEM CLICK CAN I UPDATE MENU VISIBILITY HERE?");
}
-(void) menuNeedsUpdate:(NSMenu *)menu{
wprintf(L"ITEM CLICK CAN I UPDATE MENU VISIBILITY HERE?");
}
Update2:
So I started over, imaginging that the problem had something to do with references and the fact that i was developing in objective-c++. However i can not get it to work in just a minimal Obj-C example either, below is my code. The only callback that seems to work is the one that handles item clicks. May the problem be present due to the fact that I am using :
_menubar = [application mainMenu];
[_menubar setDelegate:self];
To get my menubar and setup my menu delegate?
//
// AppDelegate.m
// menuTest
//
// Created by David Karlsson on 27/02/15.
// Copyright (c) 2015 David Karlsson. All rights reserved.
//
#import "AppDelegate.h"
void AddMenuItem(NSMenu *menu, NSString* label, int idval) {
NSMenuItem* item = [menu addItemWithTitle:label
action:@selector(menuItemSelected:)
keyEquivalent:@""];
[item setTag:idval];
}
@interface AppDelegate ()
@property (weak) IBOutlet NSWindow *window;
@property (strong) IBOutlet NSMenu * menubar;
@end
@implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
NSLog(@"Launched menu test");
// Insert code here to initialize your application
NSApplication* application = [NSApplication sharedApplication];
//[NSBundle loadNibNamed:@"MainMenu" owner:NSApp];
// Set the delegate for application events.
[application setDelegate:self];
// Add the Tests menu.
_menubar = [application mainMenu];
[_menubar setDelegate:self];
NSMenuItem *controlsItem = [[NSMenuItem alloc] initWithTitle:@"Controls"
action:nil
keyEquivalent:@""];
NSMenu *controlsMenu = [[NSMenu alloc] initWithTitle:@"Controls"];
AddMenuItem(controlsMenu, @"1", 123);
AddMenuItem(controlsMenu, @"2", 124);
AddMenuItem(controlsMenu, @"3", 154);
[controlsItem setSubmenu:controlsMenu];
[_menubar addItem:controlsItem];
}
-(void) menuWillOpen:(NSMenu *)menu{
NSLog(@"ITEM CLICK CAN I UPDATE MENU VISIBILITY HERE?");
}
-(void) menuNeedsUpdate:(NSMenu *)menu{
NSLog(@"ITEM CLICK CAN I UPDATE MENU VISIBILITY HERE?");
}
- (void)applicationWillTerminate:(NSNotification *)aNotification {
// Insert code here to tear down your application
NSLog(@"Teardown menu test");
}
- (IBAction)menuItemSelected:(id)sender {
// Retrieve the active RootWindow.
NSWindow* key_window = [[NSApplication sharedApplication] keyWindow];
if (!key_window){
return;
}
NSLog(@"CLICK");
}
@end
Upvotes: 0
Views: 963
Reputation: 12782
You want to implement parts of the NSMenu Delegate protocol and you might need an NSTimer that runs in modes that work during menu tracking in order to do live updates while the menu is visible.
Upvotes: 1
Reputation: 6918
Set the menu's delegate, then use this object to implement menuNeedsUpdate:
from the NSMenuDelegate
protocol. This method is called just before a menu is shown and is specifically provided to allow you to make changes to the menu in question before it arrives on screen.
Upvotes: 1