What's new? | Help | Directory | Sign in
Google
             
Search
for
Updated Sep 10, 2007 by iamgnat
CreatePlugin  
How to create a CarFrontEnd plugin

Purpose

This section will show you how to setup and build a Xcode project to create a CarFrontEnd plugin, then install it.

The complete example project that is discussed here is available in the Plugins directory of the source tree as "SamplePlugin".

Prerequisites

You must have the CarFrontEndAPI framework installed on your development host. For the purposes of this discussion, it will be assumed that you have installed it as /Library/Frameworks/CarFrontEndAPI.framework.

You should also be using the latest version of Xcode which is available from Apple's developer website.

Project Creation

  1. Start XCode (/Developer/Applications/Xcode)
  2. Create a new Project (File->New Project...)
  3. Select Cocoa Bundle as the project type.
  4. Give your project a name and location.
  5. Edit the Project Settings (Project->Edit Project Settings...)
    • General Tab
      1. Set the Cross-Development Target to 10.4 (Universal).
  6. Edit the Active Target Settings (Project->Edit Active Target).
    • Build Tab
      1. Set the Configuration to "All Configurations".
      2. Set Show to "All Settings" if it is not already.
      3. Set the Architectures to "ppc i386". (Universal build)
      4. Set Mach-O Type to "Bundle".
      5. Set Wrapper Extension to "cfep".
  7. Add the CarFrontEndAPI framework to your project.
    1. Right click on Frameworks in the "Groups & Files".
    2. Select "Add->Existing Frameworks...".
    3. Navigate to where you installed CarFrontEndAPI (the default location is /Library/Frameworks/CarFrontEndAPI.framework) and select it.
    4. Click the "ADD" button with no other changes.
  8. Add your primary class to the Project
    1. Right click on Classes in the "Groups & Files" area.
    2. Select "Add->New File...".
    3. Select "Objective-C Class"
    4. Give the new class a name.
  9. Edit your header file.
    1. Add the import for <CarFrontEndAPI/CarFrontEndAPI.h>
    2. Update the @interface line to include the CarFrontEndProtocol_ designation.
    3. Add the required methods to conform to the protocol.
    4. Go ahead and add an action so we can add a button.
    • You header should look something like:
    • #import <Cocoa/Cocoa.h>
      #import <CarFrontEndAPI/CarFrontEndAPI.h>
      
      @interface SamplePlugin : NSObject <CarFrontEndProtocol> {
          id                  owner;
          IBOutlet NSView     *samplePluginView;
      }
      
      - (id) initWithPluginManager: (id) pluginManager;
      - (NSString *) name;
      - (void) initalize;
      - (NSImage *) pluginButtonImage;
      - (NSView *) contentViewForSize: (NSSize) size;
      - (void) removePluginFromView;
      
      - (IBAction) buttonClicked: (id) sender;
      
      @end
  10. Edit the class file
    1. Add a static variable outside the @implementation section.
      • This will allow you to apply the Singleton pattern to the object.
      • The init method will be called twice. Once when the plugin is loaded and once when you load your NIB file.
    2. Add an init method to setup your object.
      • Make sure to use your static variable so that there is only ever one instance of your object.
    3. Add the protocol methods to the @implementation.
    4. Add the code for your action method.
    • Your object file should look something like:
    • #import "SamplePlugin.h"
      
      static SamplePlugin *sharedSP = nil;
      
      @implementation SamplePlugin
      
      - (id) init {
          return([self initWithPluginManager:nil]);
      }
      
      - (id) initWithPluginManager: (id) pluginManager {
          if (sharedSP != nil) {
              [self release];
              return(sharedSP);
          }
          
          [super init];
          owner = [pluginManager retain];
          
          // Setup for a single instance.
          sharedSP = self;
          
          return(self);
      }
      
      - (NSString *) name {
          return(@"Sample Plugin");
      }
      
      - (void) initalize {
          // No-op for this example.
          //  Should generate the button image here rather than on demand.
      }
      
      - (NSImage *) pluginButtonImage {
      	NSMutableDictionary *attributes = [NSMutableDictionary dictionary];
          
          [attributes setObject:[NSFont fontWithName:@"Helvetica" size:26]
                         forKey:NSFontAttributeName];
      	[attributes setObject:[NSColor whiteColor]
                         forKey:NSForegroundColorAttributeName];
          
          NSSize          size = [[self name] sizeWithAttributes:attributes];
          NSImage         *image = [[[NSImage alloc] initWithSize:size] autorelease];
          
          [image lockFocus];
          [[self name] drawAtPoint:NSZeroPoint withAttributes:attributes];
          [image unlockFocus];
          
          return(image);
      }
      
      - (NSView *) contentViewForSize: (NSSize) size {
          // We are ignoring the size value, but it is there incase you have differnt
          //  views based on the size that CarFrontEnd sends you.
          if (samplePluginView == nil) {
              [NSBundle loadNibNamed:@"SamplePlugin" owner:self];
          }
          
          return(samplePluginView);
      }
      
      - (void) removePluginFromView {
          // No-op
          //  If you need to do something when your view is no longer displayed,
          //  add the code here.
      }
      
      - (IBAction) buttonClicked: (id) sender {
          if ([[sender stringValue] isEqualToString:@"Click"]) {
              [sender setStringValue:@"Clock"];
          } else if ([[sender stringValue] isEqualToString:@"Clock"]) {
              [sender setStringValue:@"Click"];
          }
      }
      
      @end
  11. Add a NIB file to your project and make sure that it uses the name that you used in your -contentViewForSize: method ("SamplePlugin" in the example).
    1. Read your object's header file into the NIB file.
    2. Instantiate your object.
    3. Add a NSView to your NIB file and link it to your NSView outlet.
    4. Add a NSButton to your NSView.
      1. Set it's string value to "Click".
      2. Set it's action to the -buttonClick: method of you object.
  12. Edit your project's Info.plist
    1. Set the "NSPrincipalClass" value to the name of your object.
  13. Build your project and fix any compiler errors.

Installation

Copy the built plugin to your ~/Library/Application Support/CarFrontEnd/Plugins directory and launch CarFrontEnd. If everything went according to plan, your new plugin should be available.


Sign in to add a comment