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.

 1 @import "Volume.j"
 2 
 3 var VolumeIdentifier = "VolumeIdentifier";
 4 
 5 @implementation ToolbarDelegate : CPObject
 6 {
 7   CPToolbar toolbar;
 8 }
 9 
10 - (CPArray)toolbarAllowedItemIdentifiers:(CPToolbar)aToolbar
11 {
12   return [VolumeIdentifier];
13 }
14 
15 - (CPArray)toolbarDefaultItemIdentifiers:(CPToolbar)aToolbar
16 {
17   return [VolumeIdentifier];
18 }
19 
20 - (CPToolbarItem)toolbar:(CPToolbar)aToolbar 
21       itemForItemIdentifier:(CPString)anItemIdentifier 
22       willBeInsertedIntoToolbar:(BOOL)aFlag
23 {
24   toolbar = aToolbar;
25 
26   var toolbarItem = [[CPToolbarItem alloc] 
27                           initWithItemIdentifier:anItemIdentifier];
28   var mainBundle = [CPBundle mainBundle];
29 
30   if (anItemIdentifier == VolumeIdentifier) {
31     [toolbarItem setView:[[Volume alloc] 
32                        initWithFrame:CGRectMake(0, 0, 100, 60)]];
33     [toolbarItem setMinSize:CGSizeMake(100, 60)];
34     [toolbarItem setMaxSize:CGSizeMake(100, 60)];
35   }
36 
37   return toolbarItem;
38 }
39 @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