Example code programming Objective-C with Cocoa in Xcode and Interface Builder (Leopard)
10: Drawing using Quartz and a mouse
Custom NSView with simple painting system implemented using Quartz graphics routines.
Create a new project in XCode: File->New Project->Cocoa Application
Call it: 010-NSView
Now create the classes: MyViewController of type NSView and MyPoint of type NSObject.
Code these as shown below and save.
// MyViewController.h // 010-NSView // #import <Cocoa/Cocoa.h> #import "MyPoint.h" @interface MyViewController : NSView { NSMutableArray * myMutaryOfBrushStrokes; NSMutableArray * myMutaryOfPoints; } - (float)randVar; @end // MyViewController.m // 010-NSView // #import "MyViewController.h" @implementation MyViewController - (id)initWithFrame:(NSRect)pNsrectFrameRect { if ((self = [super initWithFrame:pNsrectFrameRect]) == nil) { return self; } // end if myMutaryOfBrushStrokes = [[NSMutableArray alloc]init]; // initialise random numebr generator used in drawRect for creating colours etc. srand(time(NULL)); return self; } // end initWithFrame
-(void)mouseDown:(NSEvent *)pTheEvent { myMutaryOfPoints = [[NSMutableArray alloc]init]; [myMutaryOfBrushStrokes addObject:myMutaryOfPoints]; NSPoint tvarMousePointInWindow = [pTheEvent locationInWindow]; NSPoint tvarMousePointInView = [self convertPoint:tvarMousePointInWindow fromView:nil]; MyPoint * tvarMyPointObj = [[MyPoint alloc]initWithNSPoint:tvarMousePointInView]; [myMutaryOfPoints addObject:tvarMyPointObj]; } // end mouseDown
-(void)mouseDragged:(NSEvent *)pTheEvent { NSPoint tvarMousePointInWindow = [pTheEvent locationInWindow]; NSPoint tvarMousePointInView = [self convertPoint:tvarMousePointInWindow fromView:nil]; MyPoint * tvarMyPointObj = [[MyPoint alloc]initWithNSPoint:tvarMousePointInView]; [myMutaryOfPoints addObject:tvarMyPointObj]; [self setNeedsDisplay:YES]; } // end mouseDragged
-(void)mouseUp:(NSEvent *)pTheEvent { NSPoint tvarMousePointInWindow = [pTheEvent locationInWindow]; NSPoint tvarMousePointInView = [self convertPoint:tvarMousePointInWindow fromView:nil]; MyPoint * tvarMyPointObj = [[MyPoint alloc]initWithNSPoint:tvarMousePointInView]; [myMutaryOfPoints addObject:tvarMyPointObj]; [self setNeedsDisplay:YES]; } // end mouseUp - (float)randVar; { return ( (float)(rand() % 10000 ) / 10000.0); } // end randVar
- (void)drawRect:(NSRect)pNSRect { // colour the background white [[NSColor whiteColor] set]; // this is Cocoa NSRectFill( pNSRect ); if ([myMutaryOfBrushStrokes count] == 0) { return; } // end if // This is Quartz NSGraphicsContext * tvarNSGraphicsContext = [NSGraphicsContext currentContext]; CGContextRef tvarCGContextRef = (CGContextRef) [tvarNSGraphicsContext graphicsPort]; NSUInteger tvarIntNumberOfStrokes = [myMutaryOfBrushStrokes count]; NSUInteger i; for (i = 0; i < tvarIntNumberOfStrokes; i++) { CGContextSetRGBStrokeColor(tvarCGContextRef,[self randVar],[self randVar],[self randVar],[self randVar]); CGContextSetLineWidth(tvarCGContextRef, (1.0 + ([self randVar] * 10.0)) ); myMutaryOfPoints = [myMutaryOfBrushStrokes objectAtIndex:i]; NSUInteger tvarIntNumberOfPoints = [myMutaryOfPoints count]; // always >= 2 MyPoint * tvarLastPointObj = [myMutaryOfPoints objectAtIndex:0]; CGContextBeginPath(tvarCGContextRef); CGContextMoveToPoint(tvarCGContextRef,[tvarLastPointObj x],[tvarLastPointObj y]); NSUInteger j; for (j = 1; j < tvarIntNumberOfPoints; j++) { // note the index starts at 1 MyPoint * tvarCurPointObj = [myMutaryOfPoints objectAtIndex:j]; CGContextAddLineToPoint(tvarCGContextRef,[tvarCurPointObj x],[tvarCurPointObj y]); } // end for CGContextDrawPath(tvarCGContextRef,kCGPathStroke); } // end for } // end drawRect @end
// MyPoint.h // 010-NSView // // wrapper for NSPoint #import <Cocoa/Cocoa.h> @interface MyPoint : NSObject { NSPoint myNSPoint; } - (id) initWithNSPoint:(NSPoint)pNSPoint; - (NSPoint) myNSPoint; - (float)x; - (float)y; @end // MyPoint.m // 010-NSView // #import "MyPoint.h" @implementation MyPoint - (id) initWithNSPoint:(NSPoint)pNSPoint; { if ((self = [super init]) == nil) { return self; } // end if myNSPoint.x = pNSPoint.x; myNSPoint.y = pNSPoint.y; return self; } // end initWithNSPoint - (NSPoint) myNSPoint; { return myNSPoint; } // end myNSPoint - (float)x; { return myNSPoint.x; } // end x - (float)y; { return myNSPoint.y; } // end y @end
Bring up Interface Builder by double clicking on MainMenu.nib.
Drag a Custom View from the Library onto the Window.
Inside the Class menu of the Identity panel of the inspector choose MyViewController.
Interface Builder: drag Custom NSView onto the window, and set its class
Save Interface Builder and return to XCode and Run. Paint by dragging the mouse over the Custom View.
Running Custom NSView Quartz application
If you want to download the code
Click the Download Link to obtain 010-NSView.zip file of this whole OS X 10.5 Leopard program.