In this article we'll look a little at how you draw into a CPView object. We won't build anything quite as complicated as the Nice Drawing Tutorial, but rather we'll try to show a few of the tools you have available.
Just for grins well draw a nice little smiley-face. We'll build it with a few different shapes, colors, ald alpha values so you get a feeling for how to work with them.
What we'll be doing is defining our own class called "DrawnView" which we'll derive from a CPView. This lets us position the view in all the nice ways we handle any other view. The trick is that we'll override the drawRect" method. This method gets called whenever the view needs to be drawn.
Let's jump right into the code. You can grab the whole thing from the zip file attached here (both the AppController.j and the DrawnView.j files), or just copy the AppController.j code below:
@import <Foundation/CPObject.j>
@import "DrawnView.j"
@implementation AppController : CPObject
{
}
- (void)applicationDidFinishLaunching:(CPNotification)aNotification
{
var theWindow = [[CPWindow alloc] initWithContentRect:CGRectMakeZero()
styleMask:CPBorderlessBridgeWindowMask];
var contentView = [theWindow contentView];
var bounds = [contentView bounds];
var view = [[DrawnView alloc] initWithFrame:CGRectMake(0, 0, 400, 400)];
[view setBackgroundColor:[CPColor colorWithRed:0.9 green:0.9 blue:0.9 alpha:1.0]];
[contentView addSubview:view];
[theWindow orderFront:self];
}
@end
The DrawnView code is also shown:
@import <Foundation/CPObject.j>
@implementation DrawnView : CPView
{
}
- (void)drawRect:(CPRect)aRect
{
var bounds = [self bounds];
var context = [[CPGraphicsContext currentContext] graphicsPort];
CGContextSetFillColor(context, [CPColor yellowColor]);
CGContextFillEllipseInRect(context, CGRectMake(100, 100, 200, 200));
CGContextSetStrokeColor(context, [CPColor blackColor]);
CGContextSetLineWidth(context, 1);
CGContextStrokeEllipseInRect(context, CGRectMake(100, 100, 200, 200));
CGContextSetFillColor(context, [CPColor blackColor]);
CGContextFillRect(context, CGRectMake(153, 160, 14, 14));
CGContextFillRect(context, CGRectMake(233, 160, 14, 14));
CGContextBeginPath(context);
CGContextSetStrokeColor(context, [CPColor blackColor]);
CGContextSetLineWidth(context, 3);
CGContextAddCurveToPoint(context, 140, 220, 200, 270, 260, 220);
CGContextStrokePath(context);
CGContextSetFillColor(context, [CPColor colorWithRed:0 green:0.9 blue:0 alpha:0.75]);
CGContextSetStrokeColor(context, [CPColor colorWithRed:0 green:0.5 blue:0 alpha:0.75]);
CGContextSetLineWidth(context, 3);
CGContextBeginPath(context);
CGContextMoveToPoint(context, 200, 305);
CGContextAddLineToPoint(context, 270, 280);
CGContextAddLineToPoint(context, 260, 305);
CGContextAddLineToPoint(context, 270, 330);
CGContextClosePath(context);
CGContextFillPath(context);
CGContextStrokePath(context);
CGContextBeginPath(context);
CGContextMoveToPoint(context, 200, 305);
CGContextAddLineToPoint(context, 130, 280);
CGContextAddLineToPoint(context, 140, 305);
CGContextAddLineToPoint(context, 130, 330);
CGContextClosePath(context);
CGContextFillPath(context);
CGContextStrokePath(context);
CGContextFillRect(context, CGRectMake(185, 290, 30, 30));
CGContextStrokeRect(context, CGRectMake(185, 290, 30, 30));
}
end
There's a lot of lines of code here, but we'll take it a piece at a time. Quite possibly the most important line is line 10. In order to do any drawing we need the graphics context. This is essentially the "address" of the drawable region. Line 10 is how we get that context. OK, so now we have the graphics context so we can start drawing. First, let's draw the yellow circle. This we do in lines 12 through 16. This 5 lines set the fill color to yellow, draws a filled circle (a special ellipse), then draws the outline in a 1 pixel black line. The eyes are drawn next as two black-filled rectangles. Finally the mouth is drawn as a 3-pixel wide cubic curve.
The bow tie is drawn in lines 28 through 51. The first few (28-30) set the color to a semi-transparent green. Then the "bows" are drawn in 32 through 39 (right-hand bow) and 41 through 48 (left hand bow). Finally the "knot" is drawn over the bows as another rectangle (lines 50 and 51).
This simple applications just highlights a few of the Cappuccino drawing capabilities including
- Drawing circles/ellipses
- Drawing rectangles/squares
- Drawing lines and curves
- Setting line width
- Setting fill and stroke color including alpha
- Defining and closing a path