Porting DotView from cocoa to cappuccino

Porting the DotView example from cocoa to cappuccino was an easy task. The only part of code I had to modify is the one used to draw the dot in the CPView.

You will be able to reuse your knowledge to create the toolbar (see the tutorial on toolbar if you need to refresh your mind). I have created a class "DotColorView" to be able to change the dot color. It is working the same way than the "DotResizeView". They will trigger the setColor: or setRadius: methods of the application delegate (since CApplication is not able to handle these mehods and try to have them handled by it's delegate). Since we have set the application delagate to be the "AppController" controller, we can see that this will just forward the call to the dotview instance.

@implementation AppController : CPObject { DotView dotView; } - (void)setRadius:(id)sender { [dotView setRadius:sender]; } - (void)setColor:(id)sender { [dotView setColor:sender]; }

All the interresting code is located in the "DotView" class. We have instance variable to draw the circle in the view (center of circle, color and radius).

@implementation DotView : CPView { CPPoint center; CPColor color; float radius; } - (id)initWithFrame:(CGRect)aFrame { if (self = [super initWithFrame:aFrame]) { center = CPPointMake(50.0, 50.0); radius = 10.0; color = [CPColor redColor]; } return self; } @end

Since the drawing is simple, we will implement the drawRect: method. You can refer to the tutorial on drawing to know other way to implement the drawing. We first erase the old circle by filling the whole view with white. We then have to draw the circle at the last position cliked with the mouse.

- (void)drawRect:(CPRect)aRect { var context = [[CPGraphicsContext currentContext] graphicsPort]; CGContextSetFillColor(context, [CPColor whiteColor]); CGContextFillRect(context, [self bounds]); var dotRect = CPRectMake(center.x - radius, center.y - radius, 2 * radius, 2 * radius); CGContextSetFillColor(context, color); CGContextFillEllipseInRect(context, dotRect) }

Since we have decided to fill the whole CPView in white, we can not see throught the view (the subviews that may be positionned below the DotView instance in the window). We can use isOpaque to optimize the drawing.

- (BOOL)isOpaque { return YES; }

We get the position cliked by the mouse. Since the location is in window coordinates, we first have to convert the coordinate system from the window to the view. By using nil for the fromView parameter, we just indicate to convert from the CPWindow to DotView. We then tell the view to redraw itself (by using setNeedsDisplay:). We don't have to draw the CPView ourself.

- (void)mouseUp:(CPEvent *)event { var eventLocation = [event locationInWindow]; center = [self convertPoint:eventLocation fromView:nil]; [self setNeedsDisplay:YES]; }

As you can see the "sender" is either the CPSlider instance or the CPColorWell instance in the toolbar. We can send this instance a message (doubleValue or color) to get the current value.

- (void)setRadius:(id)sender { radius = [sender doubleValue]; [self setNeedsDisplay:YES]; } - (void)setColor:(id)sender { color = [sender color]; [self setNeedsDisplay:YES]; }

Download code example

If you'd like to see the complete code from the tutorial, you can download it in a single file: Tutorial-DotView.zip. The web application is available online: Tutorial DotView.

Copyright © 2009 - Philippe Laval. Cappuccino and Objective-J are registered Trademarks of 280 North.