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.

XCode,Interface Builder - drag NSView Custom View onto the window

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.

XCode,Interface Builder, Running Custom NSView Quartz application

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.

Download 010-NSView.zip (2.3 MB)

Useful Links



Please send me your comments

If you include your e-mail I may reply!  

Page last modified: 18:58 Sunday 12th. May 2013

Julius Guzy

Paintings & Drawings

  • Wind in the trees at Roe Valley park

animatedPaint