Adding arbitrary controls to CPToolbar

The CPToolbar class allows for easy setup of button controls. In order to add other type of controls, those need to be sub-classes of CPView. Here is an example of how to add a slider control to a toolbar.

The following class implements a volume control and inherits from CPView:

@implementation Volume : CPView
{
  CPSlider slider;
}
- (id) initWithFrame:(CGRect)aFrame
{
  self = [super initWithFrame:aFrame];
  if (self)
  {
    slider = [[CPSlider alloc]
      initWithFrame:CGRectMake(
        5,
        CGRectGetHeight(aFrame)/2.0-10,
        CGRectGetWidth(aFrame)-10,
        20)];

    [slider setMinValue:0.0];
    [slider setMaxValue:1.0];
    [slider setTarget:self];
    [slider setAction:@selector(sliderChangedValue:)];

    [self addSubview:slider];

    [slider setValue:0.5];
  }

  return self;
}
- (void)sliderChangedValue:(id)sender
{
  [[CPNotificationCenter defaultCenter]
      postNotificationName:@"VolumeChanged" object:sender];
}
@end

As the slider value changes, a notification is posted to the default notification center and the slider object is being sent along. Let's look at how the slider can be added to a toolbar.

@import "Volume.j"

var VolumeIdentifier = "VolumeIdentifier";

@implementation ToolbarDelegate : CPObject
{
  CPToolbar toolbar;
}

- (CPArray)toolbarAllowedItemIdentifiers:(CPToolbar)aToolbar
{
  return [VolumeIdentifier];
}

- (CPArray)toolbarDefaultItemIdentifiers:(CPToolbar)aToolbar
{
  return [VolumeIdentifier];
}

- (CPToolbarItem)toolbar:(CPToolbar)aToolbar 
      itemForItemIdentifier:(CPString)anItemIdentifier 
      willBeInsertedIntoToolbar:(BOOL)aFlag
{
  toolbar = aToolbar;

  var toolbarItem = [[CPToolbarItem alloc] 
                          initWithItemIdentifier:anItemIdentifier];
  var mainBundle = [CPBundle mainBundle];

  if (anItemIdentifier == VolumeIdentifier) {
    [toolbarItem setView:[[Volume alloc] 
                       initWithFrame:CGRectMake(0, 0, 100, 60)]];
    [toolbarItem setMinSize:CGSizeMake(100, 60)];
    [toolbarItem setMaxSize:CGSizeMake(100, 60)];
  }

  return toolbarItem;
}
@end

If you've created a toolbar already, this code should look very familiar. On line 31, an instance of the volume object is simply set as a view on the CPToobarItem.

Now we're almost done. In order to be notified of volume changes, we need to register a method to listen to the notification. Here is how it's done

[[CPNotificationCenter defaultCenter ]
    addObserver:self
    selector:@selector(volumeChanged:)
    name:@"VolumeChanged" 
    object:nil];

and then the following method will read the value of the slider and can act accordingly.

- (void)volumeChanged:(CPNotification)aNotification 
{
  var volume = [CPNumber numberWithDouble:[[aNotification object] value]];
}

That's all there is to it.

Talk Back