Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

mpemburn

macrumors member
Original poster
Jan 11, 2008
51
0
Bel Air, MD USA
Hi All,

I'm trying to implement a Toolbar in my app that will, among other things, allow the user to switch tabs in a TabView. I've been following sample code to implement this but have run into a wall: the 'action' that I set for the NSToolbarItem's don't get called when I click the item on the toolbar. Here's my code:

In the header:
Code:
#define MainToolbarIdentifier    @"Main Window Toolbar Identifier"
#define ScanOptionToolbarItemIdentifier    @"Scan Option Item Identifier"
#define OutputOptionToolbarItemIdentifier    @"Output Option Item Identifier"

@interface SANEDeviceController : NSWindowController {

	IBOutlet NSImageView * imageScanOptionsTab;
	IBOutlet NSImageView * imageOutputOptionsTab;
	IBOutlet NSToolbarItem * tbItemScanOptions;
	IBOutlet NSToolbarItem * tbItemOutputOptions;

	IBOutlet NSTabView * tabViewMain;
}

- (void) SetupToolbar;
- (void) ClickedToolbar: (NSToolbarItem *) sender;

Code:
- (void) SetupToolbar; {
    NSToolbar *toolbar = [[NSToolbar alloc] initWithIdentifier: MainToolbarIdentifier];

    [toolbar setAllowsUserCustomization: NO];
    [toolbar setAutosavesConfiguration: YES];
    [toolbar setDisplayMode:NSToolbarDisplayModeIconAndLabel];
    [toolbar setDelegate: self];
    [mainWindow setToolbar: [toolbar autorelease]];
}

//*** Delegate methods for toolbar **************************************************************

- (NSToolbarItem *) toolbar: (NSToolbar *) toolbar itemForItemIdentifier: (NSString *) itemIdent willBeInsertedIntoToolbar: (BOOL) willBeInserted {
	NSToolbarItem *toolbarItem = nil;
	NSString * labelString;
	NSImageView * itemImage;
	int itemTag;
	
	toolbarItem = [[[NSToolbarItem alloc] initWithItemIdentifier: itemIdent] autorelease];
    	
	if ([itemIdent isEqual: ScanOptionToolbarItemIdentifier]) {
  		labelString = @"Scanning";
		itemImage = imageScanOptionsTab;
		itemTag = 0;
	} else if ([itemIdent isEqual: OutputOptionToolbarItemIdentifier])  {
 		labelString = @"Output";
		itemImage = imageOutputOptionsTab;		
		itemTag = 1;
	} else {
		// Returning nil will inform the toolbar this kind of item is not supported 
		toolbarItem = nil;
	}
	if (toolbarItem != nil) {
 		[toolbarItem setLabel: labelString];
		[toolbarItem setToolTip: [NSString stringWithFormat: @"%@ options", labelString]];
		[toolbarItem setView: itemImage];
		[toolbarItem setTag: itemTag];
		[toolbarItem setTarget: self];
		[toolbarItem setAction: @selector(ClickedToolbar:)];
	}
	return [toolbarItem autorelease];
}

- (NSArray *) toolbarAllowedItemIdentifiers: (NSToolbar *) toolbar {
     return [NSArray arrayWithObjects: ScanOptionToolbarItemIdentifier,  OutputOptionToolbarItemIdentifier, nil];
}

- (NSArray *) toolbarDefaultItemIdentifiers: (NSToolbar *) toolbar {
	return [self toolbarAllowedItemIdentifiers:toolbar];
}

- (NSArray *) toolbarSelectableItemIdentifiers:(NSToolbar *) toolbar {
	return [self toolbarAllowedItemIdentifiers: toolbar];
}

- (void) ClickedToolbar: (NSToolbarItem *) sender {
	if (![sender isKindOfClass:[NSToolbarItem class]])
		return;
	int tabNum = [sender tag];
	NSLog(@"Tab button clicked");
	[tabViewMain selectTabViewItemAtIndex: tabNum];
}

Can anyone tell me what I'm doing wrong?

Thanks,

-- Mark
 
I believe that if you override the item's view with your own content view, then the action doesn't get called. It only works for the standard button styles. So either use setView: and handle the clicking inside that view, or just give it an image and title.
 
Well, I answered my own question -- I just needed to hammer on it a while longer ;-)

The problem was that I was trying to use "setView" with an NSImageView and the code was bombing before it got to "setAction".:

Code:
	[toolbarItem setView: itemImage];

. . . and what was need was to use "setImage":

Code:
	[toolbarItem setImage: [itemImage image]];

Doh!

-- Mark
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.