macdevcenter.com
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

Creating Toolbars for Mac OS X
Pages: 1, 2, 3, 4

Implementing the Delegate Methods

The Standard Items

Let’s go ahead and start implementing the toolbar delegate methods now. The first one we want to implement is -toolbarAllowedItemIdentifiers:. The purpose of this method is to return to the toolbar an array of strings containing the identifiers of all the toolbar items that will go in the toolbar. For now we’ll simply create an array of the four standard toolbar item identifiers we said our toolbar would have (we’ll add our custom items after we get everything working with the standard set of items). Note that the order of the identifiers in the array is the order that the toolbar items will appear in the customization palette. Here is the first method:


- (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar*)toolbar
{
    return [NSArray arrayWithObjects:NSToolbarSeparatorItemIdentifier,
				     NSToolbarSpaceItemIdentifier,
				     NSToolbarFlexibleSpaceItemIdentifier,
				     NSToolbarCustomizeToolbarItemIdentifier, nil];
}

All we did was use NSArray’s -arrayWithObjects: method to create the return array. When using this method, remember that the list of objects must be terminated by nil. That’s all there is to it.

The next method we want to implement is -toolbarDefaultItemIdentifiers:. This method is similar in function to the method above. The difference is that it returns an array of identifiers for items that make up the default toolbar. Our default toolbar will consist of the customize toolbar item placed on the far right, which is achieved by inserting a flexible space item before the customize toolbar item. Again, the order of the identifiers in the array defines the order of the items in the default toolbar.


- (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar*)toolbar
{
    return [NSArray arrayWithObjects:NSToolbarFlexibleSpaceItemIdentifier,
				     NSToolbarCustomizeToolbarItemIdentifier, nil];
}

The third and final method we are required to implement is -toolbar:itemForItemIdentifier:willBeInsertedIntoToolbar: (aka -toolbar). This method contains the meat of a toolbar implementation. Here is where we actually create the toolbar items.

Initializing an instance of NSToolbarItem is done using the -initWithIdentifier: method. In this method we supply the identifier of the toolbar item given by the argument of itemforItemIdentifier:. If the identifier is one for the standard toolbar items, then an instance of NSToolbarItem is initialized, fully configured to perform the specified standard function.

If the identifier is one other than the standard identifiers, then only the identifier is set. It is the duty of the programmer to perform further configuration for the item, which we will do soon for our custom items. For now, let's set things up to work with just the standard items:


- (NSToolbarItem *)toolbar:(NSToolbar *)toolbar
    itemForItemIdentifier:(NSString *)itemIdentifier
    willBeInsertedIntoToolbar:(BOOL)flag
{
    NSToolbarItem *item = [[NSToolbarItem alloc] initWithItemIdentifier:itemIdentifier];
    return [item autorelease];
}

We send the item an autorelease method since the toolbar retains the item that is returned by this method. We have no use for it otherwise, so we give up ownership of the object to the toolbar. The reason I used two lines of code here rather than one is that we’re going to sandwich some additional code between these two lines when we get to building our own toolbar items.

With the required delegate methods taken care of, there are a couple of other things we need to do before all is ready to go. One is to actually create the toolbar instance. We will do this in Controller’s -awakeFromNib method by calling a method called -setupToolbar, which we implement in our category in the following way:


- (void)setupToolbar
{
    NSToolbar *toolbar = [[NSToolbar alloc] initWithIdentifier:@"mainToolbar"];
    [toolbar autorelease];
    [toolbar setDelegate:self];
    [toolbar setAllowsUserCustomization:YES];
    [toolbar setAutosavesConfiguration:YES];
    [mainWindow setToolbar:[toolbar autorelease]];
}

What we did here was to create a new instance of NSToolbar and initialize it with initWithIdentifier:. The toolbar identifier can be anything you like. It is used internally by NSToolbar, and we won’t have any direct interaction with it.

Related Reading

Learning Cocoa
By Apple Computer, Inc.

In the next line we set the delegate object of the toolbar to self, and then set some options for the toolbar -- the toolbar lets the user customize it, and it will automatically save any changes the user makes. In the last line of code we send a setToolbar message to mainWindow with [toolbar autorelease] as the argument. The same thinking that was behind autoreleasing the toolbar items before returning them applies here -- we want to relinquish ownership of toolbar to mainWindow.

The final thing we have to do is set up a menu item that will allow the user to open the customization panel. NSWindow provides us with an action method for running the toolbar’s customization palette called -runToolbarCustomizationPalette:. What we’ll do in Interface Builder (IB) is make mainWindow the target of a -runToolbarCustomizationPalette: action message sent by a "Customize Toolbar" menu item that we’ll add to the Window menu.

Now then, in IB add a "Customize Toolbar" menu item to the Window menu (you can create your very own ellipsis with the key combo option-semicolon). Connect this menu item to the -runToolbarCustomizationPalette: action of your main window. Save your work, compile the project, and you’re set to go with the basics.

When the application first launches you should see the customization toolbar item on the far right. You should be able to run the customization palette by clicking this item or via our menu item. Let’s keep going and add those three custom items we mentioned earlier.

The Custom Toolbar Items

Implementing custom toolbar items is only slightly more involved than using standard toolbar items. All that is required is a bit of post-initialization configuration. Recall that the three toolbar items we are going to make are an Add control, a Remove control, and a Search field. These toolbar items will have the identifier AddItem, RemoveItem, and SearchItem. To support this, add these three strings to the arrays returned by -toolbarAllowedItemIdentifiers: and -toolbarDefaultItemIdentifiers:. The -toolbarAllowedItemIdentifiers: method should look like this:


- (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar*)toolbar
{
    return [NSArray arrayWithObjects:NSToolbarSeparatorItemIdentifier,
				     NSToolbarSpaceItemIdentifier,
				     NSToolbarFlexibleSpaceItemIdentifier,
				     NSToolbarCustomizeToolbarItemIdentifier, 
    @"AddItem", @"RemoveItem"
    @"SearchItem", nil];
}

And -toolbarDefaultItemIdentifiers: will look like:


- (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar*)toolbar
{
    return [NSArray arrayWithObjects:@"AddItem", @RemoveItem", @SearchItem", 
NSToolbarFlexibleSpaceItemIdentifier,
NSToolbarCustomizeToolbarItemIdentifier, nil];
}

Now, let’s go back to the method where we create the items and see what we have to do.

As we last left it, -toolbar:itemForIdentifier:willBeInsertedIntoToolbar: had the following implementation:


- (NSToolbarItem *)toolbar:(NSToolbar *)toolbar
    itemForItemIdentifier:(NSString *)itemIdentifier
    willBeInsertedIntoToolbar:(BOOL)flag
{
    NSToolbarItem *item = [[NSToolbarItem alloc] initWithItemIdentifier:itemIdentifier];
    return [item autorelease];
}

This worked fine for the standard items because to implement them all we had to do was initialize an instance of NSToolbarItem with the given identifier, and we got a complete toolbar item. Now we have some non-standard items which require more than a simple initialization.

To accomplish this we’ll add a chain of if-statements in which we will compare itemIdentifier to our three custom identifiers. Within each individual if-statement we’ll run the configuration code specific to the item whose identifier matches itemIdentifier. This chain of if-statements will be sandwiched between the two existing lines of code in -toolbar….

Let’s stay organized and first add the skeleton of the if-statement chain to this method:


- (NSToolbarItem *)toolbar:(NSToolbar *)toolbar
    itemForItemIdentifier:(NSString *)itemIdentifier
    willBeInsertedIntoToolbar:(BOOL)flag
{
    NSToolbarItem *item = [[NSToolbarItem alloc] initWithItemIdentifier:itemIdentifier];

    if ( [itemIdentifier isEqualToString:@"AddItem"] ) {
	// Configuration code for "AddItem"
    } else if ( [itemIdentifier isEqualToString:@"RemoveItem"] ) {
	// Configuration code for "RemoveItem"
    } else if ( [itemIdentifier isEqualToString:@"SearchItem"] ) {
	// Configuration code for "SearchItem"
    }

    return [item autorelease];
}

As I mentioned before, all configuration code unique to each of these three items will go in the corresponding if-statement. Implementing the first two of these three items will be done entirely in code, while implementing SearchItem will be done partially in Interface Builder. Let’s take a look at the first two now.

Pages: 1, 2, 3, 4

Next Pagearrow