Open Shelf…

Creating Custom Controls

This article presents the first of what I hope will be a growing number of more in-depth tutorials on the Back Row system, gleaned through lots of repetitive experimentation. I will be specifically concentrating on the creation of custom control and controllers, and a look at the layer and animation systems. In doing so, we will learn some of the internals of the system itself, such as the use of the BRImageManager class and some less-used BRControllerStack functions.

Prerequisites

  • Mac OS X 10.4
  • Latest version of Xcode
  • The BackRow and QuartzComposer private headers.1
  • Familiarity with Mac OS X programming using Objective-C.
  • Familiarity with FRAppliance 101 and its contents, and the ability to build projects using BackRow.framework

Note: In my setup, I have BackRow.framework and iPhoto.framework installed in their native locations, within /System/Library/PrivateFrameworks/, and I have symlinked to their private header folders within the 10.4 Universal SDK itself. I can’t provide guidance for people who don’t want to modify those directories directly, although it might be possible to simply add the frameworks to your home folder, in ~/Library/Frameworks.

The base class: BRControl

The BRControl class is the basis for all controls. It doesn’t implement any functionality itself, but it does provide a skeleton which uses the functionality added in subclasses. For instance, the -frame method calls [self layer] to fetch the layer’s frame, although the base BRControl class does not provide a layer.

The Class Header


@interface BRControl : NSObject 
{
    BRRenderScene *_scene;  // 4 = 0x4
}

+ (BRControl *)controlWithScene: (BRRenderScene *) scene;
- (id)initWithScene: (BRRenderScene *) scene;
- (BRRenderScene *) scene;
- (void) dealloc;
- (BRRenderLayer *) layer;
- (BOOL) brEventAction: (BREvent *) event;
- (void) setFrame: (NSRect) frameRect;
- (NSRect) frame;
- (void)setAlphaValue: (float) alpha;
- (float) alphaValue;
- (void) setHidden: (BOOL) hidden;
- (BOOL) hidden;

@end

Deconstructing The Class

The BRControl class mostly serves as a wrapper around a BRRenderLayer. Generally, the layer objects contain all the OpenGL code, and are the targets for animations. The control objects are higher-level, mostly providing either an abstraction from the raw layer code (as in the BRTextControl and BRTextLayer) or they make use of more than one layer in their creation — BRButtonControl uses a BRTextLayer and a BRSelectionLozengeLayer to draw itself.

The most important routines here are:

-(BRRenderLayer *) layer;
-(BOOL) brEventAction: (BREvent *) event;
-(void) setFrame: (NSRect) frameRect;

The -layer routine is most important, because each control must have a single layer containing any others, and it is the subclasses’ responsibility to provide that by implementing this routine. If this is not implemented, then the layer will never be put on screen.

The -brEventAction: routine handles events, which will be the focus of a later tutorial. At this point, the control can analyse the event to find out which button was pressed, and can return YES if it handled the event, or NO if it did not.

The -setFrame: routine is important because it can be overridden by subclasses to lay out their own layers within their new frame.


  1. I will build an OS X Installer package for these header files soon, which will put them all in the right place, including symlinks within the OS X 10.4u SDK. You’ll need to get the BackRow framework yourself, however. 

No Responses

Note that comments are displayed in reverse chronological order with topmost comments being freshest. Subscribe | Comment

Leave a Reply

You must be logged in to post a comment.