Register FAQ / Rules Forum Spy Search Today's Posts Mark Forums Read
Go Back   MacRumors Forums > Apple Systems and Services > Programming > Mac Programming

Reply
 
Thread Tools Search this Thread Display Modes
Old Aug 1, 2007, 07:41 AM   #1
Littleodie914
macrumors 68000
 
Littleodie914's Avatar
 
Join Date: Jun 2004
Location: Rochester, NY
Working with NSMenu and NSMenuItem

Hey guys, I'm having trouble coming up with a solution for an NSMenu. To spill the beans, I've got an NSMenu that contains a list of subjects, based on the data of an NSArrayController. No problem there.

The problem, however, is setting the actions for the items. Say, for example, I have menu items "Biology," "Chemistry," and "Math." I want to set their actions to something like:

Code:
- (bool)moveToSubject:(NSString *)newSubject;
So that the action of, say, biology, would be:

Code:
performAction:@selector(moveToSubject:) withArgument:[self title]
So then it would essentially call

Code:
moveToSubject:@"Biology"
Problem is, I can only seem to link the action of a NSMenuItem to a single selector, which doesn't make the method calls specific enough to perform the necessary action. I could only perform something like "moveToSubject:" without the arguments. Any ideas?
Littleodie914 is offline   0 Reply With Quote
Old Aug 1, 2007, 08:33 AM   #2
Eraserhead
macrumors G4
 
Eraserhead's Avatar
 
Join Date: Nov 2005
Location: UK
Can't you call a general method which then calls the specific method you want?
Eraserhead is online now   0 Reply With Quote
Old Aug 1, 2007, 08:51 AM   #3
Littleodie914
Thread Starter
macrumors 68000
 
Littleodie914's Avatar
 
Join Date: Jun 2004
Location: Rochester, NY
Quote:
Originally Posted by Eraserhead View Post
Can't you call a general method which then calls the specific method you want?
I could, but the general method still isn't aware of which MenuItem was selected. That's the problem I keep running into.
Littleodie914 is offline   0 Reply With Quote
Old Aug 1, 2007, 08:55 AM   #4
Eraserhead
macrumors G4
 
Eraserhead's Avatar
 
Join Date: Nov 2005
Location: UK
can't you find that out from the sender? i.e. get the NSMMenuItem to call the method -(IBAction)myMethod:(id)sender; and then use [sender title] to get the title of the menu item pressed.
Eraserhead is online now   0 Reply With Quote
Old Aug 1, 2007, 09:34 AM   #5
lucasgladding
macrumors 6502
 
Join Date: Feb 2007
Location: Waterloo, Ontario
 
Quote:
Originally Posted by Eraserhead View Post
can't you find that out from the sender? i.e. get the NSMMenuItem to call the method -(IBAction)myMethod:(id)sender; and then use [sender title] to get the title of the menu item pressed.
Using represented objects is probably the best route in the long run (IMHO). The object is taken from the content binding or set via the setRepresentedObject: method.


- (IBAction)myMethod:sender {
[sender representedObject];
}


If you're using the NSMenu within an NSPopUpButton, you can also call one action for the button rather than setting actions for each NSMenuItem:


- (IBAction)myMethod:sender {
[[sender selectedItem] representedObject];
}


Bindings allow this to be done very easily if you're using the content (NSArrayController1.@arrangedObjects), contentValues (NSArrayController1.@arrangedObjects.keyPath), and selectedObject (NSArrayController2.@selection.relationshipKeyPath) bindings.

Luke Gladding

www.hourlyapp.com
lucasgladding is offline   0 Reply With Quote
Old Aug 1, 2007, 01:59 PM   #6
kainjow
Moderator emeritus
 
kainjow's Avatar
 
Join Date: Jun 2000
Quote:
Originally Posted by Eraserhead View Post
can't you find that out from the sender? i.e. get the NSMMenuItem to call the method -(IBAction)myMethod:(id)sender; and then use [sender title] to get the title of the menu item pressed.
I would not do this. The title is really a localized string, not some data. Use representedObject like lucasgladding said. That is what it is for.
kainjow is offline   0 Reply With Quote
Old Aug 4, 2007, 12:11 PM   #7
Littleodie914
Thread Starter
macrumors 68000
 
Littleodie914's Avatar
 
Join Date: Jun 2004
Location: Rochester, NY
Alright, thanks for the replies, that seemed to work! One more question though.

I have a menu extra, an NSMenu inserted into the NSStatusBar's systemStatusBar. This extra is created (and added to the menu) upon the creation of each new MyDocument.

Problem is, I can't find a way to get rid of it. What types of methods should I use to remove the extra? I've tried putting a simple "removeStatusItem" in my NSWindow subclass's dealloc() method, and passing it the menu, but I get an "EXC_BAD_ACCESS" error every time. TIA!
Littleodie914 is offline   0 Reply With Quote
Old Jan 23, 2008, 08:24 PM   #8
Littleodie914
Thread Starter
macrumors 68000
 
Littleodie914's Avatar
 
Join Date: Jun 2004
Location: Rochester, NY
Hate to revive a dead thread, but the title still applies to my issue.

Very simple, I've got an NSMenu with manually added NSMenuItems, but they aren't validating at all. It's currently a subclass of NSPopUpButton, but I think it will be easier to just use the default NSPopUpButton and add the items.

Anyway, no matter what I do (autoEnabling, setting each item enabled, etc.) none of the menu items are selectable. I'm thinking my problem is with the selector/action portion, but I've never been good with that topic.

Code:
@implementation IPCalendarButton
-(void)awakeFromNib {
	
	NSMenu *listOfCalendars = [[NSMenu alloc] initWithTitle:@"Calendar List"];
	
	CalCalendarStore *myStore = [CalCalendarStore defaultCalendarStore];
	NSArray *calendars = [myStore calendars];
	
	int i;
	
	for (i = 0; i < [calendars count]; i++)
	{
		NSMenuItem *currentItem = [[NSMenuItem alloc] initWithTitle:[[calendars objectAtIndex:i] title] action:@selector(setNewDefaultCalendar) keyEquivalent:@""];
		[listOfCalendars addItem:currentItem];		
	}

	[self setMenu:listOfCalendars];
}

- (void)setNewDefaultCalendar {
	NSLog(@"Setting Default Calendar!");
}
@end
Littleodie914 is offline   0 Reply With Quote
Old Jan 23, 2008, 09:43 PM   #9
kainjow
Moderator emeritus
 
kainjow's Avatar
 
Join Date: Jun 2000
Try adding:
Code:
[currentItem setTarget:self];
kainjow is offline   0 Reply With Quote
Old Jan 24, 2008, 07:24 AM   #10
Littleodie914
Thread Starter
macrumors 68000
 
Littleodie914's Avatar
 
Join Date: Jun 2004
Location: Rochester, NY
Quote:
Originally Posted by kainjow View Post
Try adding:
Code:
[currentItem setTarget:self];
Ah, that did it! Thanks! I had no idea you had to do that.
Littleodie914 is offline   0 Reply With Quote
Old Jan 24, 2008, 07:30 AM   #11
kainjow
Moderator emeritus
 
kainjow's Avatar
 
Join Date: Jun 2000
Quote:
Originally Posted by Littleodie914 View Post
Ah, that did it! Thanks! I had no idea you had to do that.
Well anytime you're assigning an action via a @selector to an object, you have to think about how it knows which object to call that selector on. Usually there are two methods. setAction: and setTarget: but you already set the action in the initWith.. function so you just needed to set the target to self.

Also as an alternative, you could give your popup button a target and action in the same way (as you do a normal button) and then use the normal popup button methods to access the selected item. The same thing can be done in many ways
kainjow is offline   0 Reply With Quote
Old Jan 24, 2008, 07:32 AM   #12
Littleodie914
Thread Starter
macrumors 68000
 
Littleodie914's Avatar
 
Join Date: Jun 2004
Location: Rochester, NY
Quote:
Originally Posted by kainjow View Post
Well anytime you're assigning an action via a @selector to an object, you have to think about how it knows which object to call that selector on. Usually there are two methods. setAction: and setTarget: but you already set the action in the initWith.. function so you just needed to set the target to self.

Also as an alternative, you could give your popup button a target and action in the same way (as you do a normal button) and then use the normal popup button methods to access the selected item. The same thing can be done in many ways
Ah thank you! That totally makes sense, I always wondered how it knew where to find the specified method. Thanks much.
Littleodie914 is offline   0 Reply With Quote
Old Jan 28, 2011, 01:56 PM   #13
joraff
macrumors newbie
 
Join Date: Jul 2010
Hate to bring up an old thread, but its very relevant to an app I'm working on.

I'm working on a small utility for my organization for internal-use only. Possibly open sourced in the future. It's to help quickly install/uninstall local printers through a Status Item. I've never done and Mac programming before, so I'm learning as I go..

So Far I have a PrinterController and Printer class (in addition to the appdelegate class):

Code:
@interface PrinterController : NSObject {
	NSMutableArray * printers;
}

- (PrinterController*) init;
- (void) drawFavorites: (NSMenu*)statusMenu;
- (NSArray*) favorites;

@end
Code:
@interface Printer : NSObject {
	NSString *displayName;
	NSString *queueName;
	NSString *locationName;
	NSString *lpURI;
	BOOL favorite;
}

@property (retain) NSString* displayName;
@property (retain) NSString* queueName;
@property (retain) NSString* locationName;
@property (retain) NSString* lpURI;
@property BOOL favorite;

- (id)   initWithDisplayName: (NSString*)d
				   queueName: (NSString*)q
				locationName: (NSString*)l
						 uri: (NSString*)u
					favorite: (BOOL)f;

- (void) install;
The app reads printers from a property list file and adds the "favorited" printers to the NSMenu, and links them to the printer object directly. However, I think I'm supposed to link them to a controller method instead? But I can't figure out how to tell which object in the menu was clicked to handle the install or uninstall of the printer. Another plus to linking to the controller is I'd have access to the state and setState methods of the NSMenuItem.

Code:
- (PrinterController *) init
{
	[super init];
	
	printers = [[NSMutableArray alloc] init];
	
	NSString *nodePath = [[NSBundle mainBundle] pathForResource:@"Printers" ofType:@"plist"];
	NSDictionary *printerDict = [NSDictionary dictionaryWithContentsOfFile:nodePath];
	
	if (printerDict) {
		for (id key in printerDict) {
			NSDictionary *p = [printerDict objectForKey:key];
			Printer *p1 = [[Printer alloc] initWithDisplayName:[p valueForKey:@"displayName"]
													 queueName:[p valueForKey:@"queueName"]
												  locationName:[p valueForKey:@"locationName"]
														   uri:[p valueForKey:@"lpURI"]
													  favorite:[[p valueForKey:@"favorite"] boolValue]];
			[printers addObject:p1];
			[p1 release];
		}
	}
	return self;
}
Any suggestions?
joraff is offline   0 Reply With Quote
Old Jan 28, 2011, 03:36 PM   #14
Sydde
macrumors 68000
 
Sydde's Avatar
 
Join Date: Aug 2009
Quote:
Originally Posted by joraff View Post
Any suggestions?
I think the simplest approach would be to give the printer controller an instance variable that points either to the NSStatusItem or its menu. Then the controller can build the menu alongside the array of printers.

After that, you need an action method (probably once again in the controller object) to point each menu item to. The action method is defined in the form

Code:
-(void)actionMethodName:(id)sender;
This method will be called when a menu item is selected, with sender = menuItem. Look through some of the above post for clues how to set up each menu item and retrieve which printer it represents.
__________________
You got to be a spirit. You can't be no ghost.
Sydde is offline   0 Reply With Quote

Reply
MacRumors Forums > Apple Systems and Services > Programming > Mac Programming

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Similar Threads
thread Thread Starter Forum Replies Last Post
External HDD not working on Mac, but working on Windows BlaXpirit Mac Basics and Help 8 Jan 22, 2014 11:07 AM
WiFi Sync Not Working iOS7, Working iOS6 kramden88 iOS 7 0 Jan 2, 2014 02:45 PM
iPhone: iPhone 5 / iPad 3 with Airport Extreme and WPA2 not working, WPA working ManuCH iOS 6 7 Aug 13, 2013 08:20 PM
General: The List of iOS 6 Compatible Jailbreak Tweaks (Working/Non Working) HeyGreggie Jailbreaks and iOS Hacks 363 Feb 26, 2013 06:43 PM
Resolved: Change image when NSMenuItem highlights? ArtOfWarfare Mac Programming 0 Jun 9, 2012 05:41 PM

Forum Jump

All times are GMT -5. The time now is 01:06 AM.

Mac Rumors | Mac | iPhone | iPhone Game Reviews | iPhone Apps

Mobile Version | Fixed | Fluid | Fluid HD
Copyright 2002-2013, MacRumors.com, LLC