UKToolbarFactory
Language: Objective-C, Author: Uli Kusterer
License: MIT/X11
A simple delegate class that you can drop into a NIB file to add a simple toolbar to your application. You specify the list of allowed items and the default list of items in a .plist file, hook it up to the window and it will automatically be configurable and save automatically.
It also supports simple view-based and selectable items.
UKToolbarFactory source preview
// // UKToolbarFactory.m // UKToolbarFactory // // Created by Uli Kusterer on Sat Jan 17 2004. // Copyright (c) 2004 M. Uli Kusterer. All rights reserved. // // ----------------------------------------------------------------------------- // Headers: // ----------------------------------------------------------------------------- #import "UKToolbarFactory.h" #import "UKFirstResponder.h" @interface UKToolbarFactory (UKToolbarFactoryPrivateMethods) -(void) setupToolbar: (id)sender; -(void) itemClicked: (NSToolbarItem*)sender; //-(BOOL) tryToPerform: (SEL)itemAction with: (id)sender onObject: (NSResponder*)resp; @end @implementation UKToolbarFactory // ----------------------------------------------------------------------------- // * DESTRUCTOR: // Get rid of the objects we created. // // REVISIONS: // 2004-01-19 witness Documented. // ----------------------------------------------------------------------------- -(void) dealloc { [toolbarItems release]; [toolbarIdentifier release]; [super dealloc]; } // ----------------------------------------------------------------------------- // awakeFromNib: // We were created from a NIB file. Add the toolbar to our window. // // REVISIONS: // 2004-01-19 witness Documented. // ----------------------------------------------------------------------------- -(void) awakeFromNib { [self setupToolbar: self]; // Create toolbar. } // ----------------------------------------------------------------------------- // setToolbarIdentifier: // Lets you change the toolbar identifier at runtime. This will recreate // the toolbar from the item definition .plist file for that identifier. // // REVISIONS: // 2004-01-19 witness Documented. // ----------------------------------------------------------------------------- -(void) setToolbarIdentifier: (NSString*)str { [str retain]; [toolbarIdentifier release]; toolbarIdentifier = str; [self setupToolbar: nil]; // Recreate toolbar. } // ----------------------------------------------------------------------------- // toolbarIdentifier: // Returns the toolbar identifier this object manages. Defaults to the // application's bundle identifier with the autosave name of the owning // window appended to it. // // REVISIONS: // 2004-01-19 witness Documented. // ----------------------------------------------------------------------------- -(NSString*) toolbarIdentifier { if( !toolbarIdentifier ) toolbarIdentifier = [[NSString stringWithFormat: @"%@.%@", [[NSBundle mainBundle] bundleIdentifier], [owner frameAutosaveName]] retain]; return toolbarIdentifier; } // ----------------------------------------------------------------------------- // toolbar:itemForItemIdentifier:willBeInsertedIntoToolbar: // Creates the appropriate toolbar item for the specified identifier. // This simply lets NSToolbarItem handle system-defined toolbar items, // while setting up all others according to the dictionaries from the // .plist file. // // REVISIONS: // 2004-01-19 witness Documented. // ----------------------------------------------------------------------------- -(NSToolbarItem*) toolbar: (NSToolbar*)toolbar itemForItemIdentifier: (NSString*)itemIdentifier willBeInsertedIntoToolbar: (BOOL)flag; { NSDictionary* allItems = [toolbarItems objectForKey: @"Items"]; NSDictionary* currItem; NSToolbarItem* tbi = nil; // One of the system-provided items? if( [itemIdentifier isEqualToString: NSToolbarSeparatorItemIdentifier] || [itemIdentifier isEqualToString: NSToolbarSpaceItemIdentifier] || [itemIdentifier isEqualToString: NSToolbarFlexibleSpaceItemIdentifier] || [itemIdentifier isEqualToString: NSToolbarShowColorsItemIdentifier] || [itemIdentifier isEqualToString: NSToolbarShowFontsItemIdentifier] || [itemIdentifier isEqualToString: NSToolbarPrintItemIdentifier] || [itemIdentifier isEqualToString: NSToolbarCustomizeToolbarItemIdentifier] ) return [[[NSToolbarItem alloc] initWithItemIdentifier: itemIdentifier] autorelease]; // Otherwise, look it up in our list of custom items: currItem = [allItems objectForKey: itemIdentifier]; if( currItem ) { NSString* theActionStr = [currItem objectForKey: @"Action"]; NSString* viewClassStr = [currItem objectForKey: @"ViewClass"]; SEL itemAction = @selector(itemClicked:); if( theActionStr && (viewClassStr || ![self isSelectable]) ) itemAction = NSSelectorFromString(theActionStr); NSNumber* maxw = [currItem objectForKey: @"MaxWidth"]; NSNumber* minw = [currItem objectForKey: @"MinWidth"]; NSString* itemLabel = [currItem objectForKey: @"Label"]; NSString* itemCustomLabel = [currItem objectForKey: @"CustomizationLabel"]; NSString* itemTooltip = [currItem objectForKey: @"ToolTip"]; Class viewClass = nil; if( viewClassStr ) viewClass = NSClassFromString(viewClassStr); NSImage* itemImage = [NSImage imageNamed: itemIdentifier]; // ... and create an NSToolbarItem for it and set that up: tbi = [[[NSToolbarItem alloc] initWithItemIdentifier: itemIdentifier] autorelease]; [tbi setAction: itemAction]; if( !viewClassStr && [self isSelectable] ) [tbi setTarget: self]; if( viewClassStr ) // This isn't a regular item? It's a view? { NSView* theView = (NSView*) [[[viewClass alloc] init] autorelease]; [tbi setView: theView]; if( theActionStr && [theView respondsToSelector: @selector(setAction:)] ) [(id)theView setAction: itemAction]; if( itemLabel && [theView respondsToSelector: @selector(cell)] ) { NSCell* theCell = [(id)theView cell]; if( [theCell respondsToSelector: @selector(setPlaceholderString:)] ) [(id)theCell setPlaceholderString: itemLabel]; } } if( minw ) [tbi setMinSize: NSMakeSize([minw floatValue], 32)]; if( maxw ) [tbi setMaxSize: NSMakeSize([maxw floatValue], 32)]; [tbi setLabel: itemLabel]; [tbi setImage: itemImage]; if( itemCustomLabel ) [tbi setPaletteLabel: itemCustomLabel]; else [tbi setPaletteLabel: itemLabel]; if( itemTooltip ) [tbi setToolTip: itemTooltip]; } return tbi; } // ----------------------------------------------------------------------------- // toolbarDefaultItemIdentifiers: // Returns the list of item identifiers we want to be in this toolbar by // default. The list is loaded from the .plist file's "DefaultItems" array. // // REVISIONS: // 2004-01-19 witness Documented. // ----------------------------------------------------------------------------- -(NSArray*) toolbarDefaultItemIdentifiers: (NSToolbar*)toolbar { return [toolbarItems objectForKey: @"DefaultItems"]; } // ----------------------------------------------------------------------------- // toolbarAllowedItemIdentifiers: // Returns the list of item identifiers that may be in the toolbar. This // simply returns the identifiers of all the items in our "Items" // dictionary, plus a few sensible defaults like separators and spacer // items the user may want to add as well. // // If this function doesn't return the item identifier, it *can't* be in // the toolbar. Though if this returns it, that doesn't mean it currently // is in the toolbar. // // REVISIONS: // 2004-01-19 witness Documented. // ----------------------------------------------------------------------------- -(NSArray*) toolbarAllowedItemIdentifiers: (NSToolbar*)toolbar { NSDictionary* allItems = [toolbarItems objectForKey: @"Items"]; int icount = [allItems count]; NSMutableArray* allowedItems = [NSMutableArray arrayWithCapacity: icount +4]; NSEnumerator* allItemItty; NSString* currItem; for( allItemItty = [allItems keyEnumerator]; currItem = [allItemItty nextObject]; ) [allowedItems addObject: currItem]; [allowedItems addObject: NSToolbarSeparatorItemIdentifier]; [allowedItems addObject: NSToolbarSpaceItemIdentifier]; [allowedItems addObject: NSToolbarFlexibleSpaceItemIdentifier]; [allowedItems addObject: NSToolbarCustomizeToolbarItemIdentifier]; return allowedItems; } -(NSArray*) toolbarSelectableItemIdentifiers: (NSToolbar*)toolbar { if( [self isSelectable] ) { NSDictionary* allItems = [toolbarItems objectForKey: @"Items"]; int icount = [allItems count]; NSMutableArray* allowedItems = [NSMutableArray arrayWithCapacity: icount]; NSEnumerator* allItemItty; NSString* currItem; for( allItemItty = [allItems keyEnumerator]; currItem = [allItemItty nextObject]; ) { // View items aren't selectable, but make all others selectable: if( [[allItems objectForKey: currItem] objectForKey: @"ViewClass"] == nil ) [allowedItems addObject: currItem]; } return allowedItems; } else return [NSArray array]; } -(BOOL) isSelectable { NSNumber* n = [[toolbarItems objectForKey: @"Options"] objectForKey: @"Selectable"]; return n && [n boolValue]; } -(NSString*) selectedItemIdentifier { return [[owner toolbar] selectedItemIdentifier]; } -(void) setSelectedItemIdentifier: (NSString*)str { [[owner toolbar] setSelectedItemIdentifier: str]; } @end @implementation UKToolbarFactory (UKToolbarFactoryPrivateMethods) // ----------------------------------------------------------------------------- // setupToolbar: // (Re)create our toolbar. This loads the .plist file whose name is the // toolbar identifier and loads it. Then it adds the toolbar to our // window. // // REVISIONS: // 2004-01-19 witness Documented. // ----------------------------------------------------------------------------- -(void) setupToolbar: (id)sender { // Load list of items: NSString* toolbarItemsPlistPath = [[NSBundle mainBundle] pathForResource: [self toolbarIdentifier] ofType: @"plist"]; if( toolbarItems ) [toolbarItems release]; toolbarItems = [[NSDictionary dictionaryWithContentsOfFile: toolbarItemsPlistPath] retain]; // (Re-) create toolbar: NSToolbar* tb = [[[NSToolbar alloc] initWithIdentifier: [self toolbarIdentifier]] autorelease]; [tb setDelegate: self]; [tb setAllowsUserCustomization: YES]; [tb setAutosavesConfiguration: YES]; [owner setToolbar: tb]; if( [self isSelectable] ) [self setSelectedItemIdentifier: [[toolbarItems objectForKey: @"DefaultItems"] objectAtIndex: 0]]; } // ----------------------------------------------------------------------------- // itemClicked: // Toolbar action if we have selectable items. This selects the item, then // sends the actual action that the item has. // // REVISIONS: // 2004-10-03 witness Documented. // ----------------------------------------------------------------------------- -(void) itemClicked: (NSToolbarItem*)sender { [self setSelectedItemIdentifier: [sender itemIdentifier]]; NSDictionary* dict = [[toolbarItems objectForKey: @"Items"] objectForKey: [sender itemIdentifier]]; NSString* theActionStr = [dict objectForKey: @"Action"]; if( theActionStr ) { SEL itemAction = NSSelectorFromString(theActionStr); [[UKFirstResponder firstResponder] performSelector: itemAction withObject: sender]; } } @end
UKToolbarFactory header preview
// // UKToolbarFactory.h // UKToolbarFactory // // Created by Uli Kusterer on Sat Jan 17 2004. // Copyright (c) 2004 M. Uli Kusterer. All rights reserved. // /* PURPOSE: Easily add toolbars to windows in your application. DIRECTIONS: To use UKToolbarFactory, drag this header file into your NIB file's window. Now you'll be able to instantiate a UKToolbarFactory object in your NIB. Hook up the UKToolbarFactory's "owner" outlet with the NSWindow on which you want a toolbar. Make sure you have specified an "Autosave name" for the NSWindow (e.g. "MainWindow"). Now create a file that is named with your application's bundle identifier (e.g. "com.mycompany.myapplication"), followed by a period, the autosave name of the NSWindow and ".plist" (e.g. "com.mycompany.myapplication.MainWindow.plist"). In this file you can now define the toolbar items that will be available in your window's toolbar. The file must contain a dictionary of item definition dictionaries under the key "Items". These item definition dictionaries are stored under the item identifier as the key. The actual item definition dictionary contains the following keys (all strings): Action - The selector to call on the first responder when this item is clicked, e.g. "close:" or "print:" or "myCustomIBAction:". Label - The label to display under the toolbar item in the toolbar. CustomizationLabel - An alternate label to be displayed in the "Customize toolbar" window for this item. This can be more detailed. If this isn't present, the "Label" will be used here as well. ToolTip - The tool tip to display when the mouse is over this item in the toolbar. If this isn't specified, no tooltip is shown. ViewClass - If specified, this is the name of an NSView subclass from which an object will be created and shown instead of an icon. If the view is an NSSearchField or similar class, this will also set its placeholder string to the label of the item. MaxWidth - The maximum width for a view-based item. Must be provided if ViewClass is specified. MinWidth - The minimum width for a view-based item. Must be provided if ViewClass is specified. The image to be used for the toolbar item must have the item identifier as its name (plus any filename extension needed to indicate the image file's type, e.g. ".tiff"). The file must also contain an array under the key "DefaultItems", which contains the list of item identifiers to be displayed in this toolbar by default. Apart from the identifiers in this file, you can also specify the identifiers defined by Apple, i.e. NSToolbarSeparatorItem, NSToolbarSpaceItem, NSToolbarFlexibleSpaceItem, or NSToolbarCustomizeToolbar, which are automatically added to the list of allowed items. If you want to allow NSToolbarShowColorsItem, NSToolbarShowFontsItem, or NSToolbarPrintItem, you have to explicitly add them to the "Items" dictionary or they won't show up in the customization sheet. You needn't specify any actions, labels or tool tips for them, though. To support selectable items, you have to provide an "Options" dictionary and provide a "Selectable" entry, which should be an NSBoolean set to YES. This will make all non-view items in the toolbar selectable, and will make sure the last one clicked is selected. To enable/disable toolbar items as needed, implement -(BOOL) validateToolbarItem: (NSToolbarItem*)item; on the owning NSWindow. This works analogous to validateMenuItem:. */ // ----------------------------------------------------------------------------- // Headers: // ----------------------------------------------------------------------------- #import <AppKit/AppKit.h> // ----------------------------------------------------------------------------- // UKToolbarFactory: // ----------------------------------------------------------------------------- @interface UKToolbarFactory : NSObject { IBOutlet NSWindow* owner; // Window to put the toolbar on. NSDictionary* toolbarItems; // List of possible items in the toolbar. NSString* toolbarIdentifier; // The toolbar identifier and base file name. NSString* selectedItem; // The currently selected item, if this allows selections. } -(void) setToolbarIdentifier: (NSString*)str; -(NSString*) toolbarIdentifier; // Defaults to the application's bundle identifier with a period and the autosave name of the owning window. -(NSString*) selectedItemIdentifier; -(void) setSelectedItemIdentifier: (NSString*)str; -(BOOL) isSelectable; @endDownload Archive
Compatible with:
- Mac OS X 10.3
- Mac OS X 10.4 PPC
- Mac OS X 10.4 Intel
- Mac OS X 10.5 PPC
- Mac OS X 10.5 Intel
Comments
Comment feed
