Example code programming Objective-C with Cocoa in Xcode and Interface Builder (Leopard)
31: Simple drawing using quartz
Problem: To draw a number of shapes onto a screen window using Quartz.
Solution: Use Interface Builder to define a NSWindow and a custom NSView. In the NSView drawRect method obtain a CGContextRef from the NSGraphicsContext currentContext, and then use the basic Quartz drawing functions to produce the picture.
Start by defining the CGContextSetStrokeColorSpace and CGContextSetFillColorSpace(s). Use CGContextSetFillColor from a CGFloat array of colour values and then draw a rectangle of the same size as the custom view rect.
Use paths to define a number of curves then use CGContextDrawPath to display them on-screen.
The finished Quartz drawing
Implementation.
Create a new project in XCode: File->New Project->Cocoa Application
Call it: 031_CGContext
Now create the class: MyNSView of type NSView.
Code it as shown below and save.
// MyNSView.h // Created by julius on 10/11/2008. #import <Cocoa/Cocoa.h> @interface MyNSView : NSView { CGColorSpaceRef cgColourSpaceRef; } - (CGColorSpaceRef) obtainTheRGBColorSpace; @end // MyNSView.m #import "MyNSView.h" @implementation MyNSView - (id)initWithFrame:(NSRect)frame { if ( !(self = [super initWithFrame:frame]) ) { return self; } // end if return self; } - (void)awakeFromNib { cgColourSpaceRef = [self obtainTheRGBColorSpace]; } // end awakeFromNib - (CGColorSpaceRef) obtainTheRGBColorSpace { // pp 159 Programming with Quartz, Celphman and Laden CMProfileRef zGenericRGBProfile = NULL; OSStatus zOSStatusError = noErr; CMProfileLocation zLoc; // build up a profile location for ColorSync zLoc.locType = cmPathBasedProfile; //strcpy(zLoc.u.pathLoc.path, kGenericRGBProfilePathStr); // did not spend time making it work strcpy(zLoc.u.pathLoc.path, "/System/Library/ColorSync/Profiles/Generic RGB Profile.icc"); // Open the profile with ColourSync zOSStatusError = CMOpenProfile(&zGenericRGBProfile, &zLoc); if( !(zOSStatusError == noErr) ) { NSLog(@"MyPictureView *** ERROR *** getTheDisplayColorSpace CMOpenProfile"); exit(1); } // CGColorSpaceRef zCgColorSpaceRefDisplay = CGColorSpaceCreateWithPlatformColorSpace(zGenericRGBProfile); if(zCgColorSpaceRefDisplay == NULL) { NSLog(@"MyPictureView *** ERROR *** getTheDisplayColorSpace zCgColorSpaceRefDisplay"); exit(1); } // end if return zCgColorSpaceRefDisplay; } // end obtainTheRGBColorSpace - (void)drawRect:(NSRect)rect { NSGraphicsContext * nsGraphicsContext = [NSGraphicsContext currentContext]; CGContextRef zCgContextRef = (CGContextRef) [nsGraphicsContext graphicsPort]; CGContextSetFillColorSpace(zCgContextRef,cgColourSpaceRef); CGContextSetStrokeColorSpace(zCgContextRef,cgColourSpaceRef); CGFloat zFillColour1[4] = {0.98,0.9,0.88,1.0}; CGContextSetFillColor (zCgContextRef,zFillColour1); CGContextFillRect (zCgContextRef, CGRectMake (0.0, 0.0, rect.size.width, rect.size.height )); CGContextBeginPath(zCgContextRef); CGFloat zStrokeColour1[4] = {0.0,0.0,1.0,1.0}; CGContextSetStrokeColor(zCgContextRef,zStrokeColour1); CGContextSetLineWidth(zCgContextRef,2.0); CGContextAddArc (zCgContextRef, 50.0, 150.0, 10.0, 0.0, 2.0 * 3.142,YES); CGContextDrawPath(zCgContextRef,kCGPathStroke); // another way of specifying the colour CGContextSetRGBStrokeColor(zCgContextRef,0.0,0.0,0.6,1.0); CGContextBeginPath(zCgContextRef); CGContextMoveToPoint(zCgContextRef,180.0,180.0); CGContextAddCurveToPoint(zCgContextRef, 60.0, 180, 50.0, 170.0, 100.0, 100.0); CGContextAddCurveToPoint(zCgContextRef, 130.0, 80.0, 120.0, 60.0, 80.0, 80.0); CGContextDrawPath(zCgContextRef,kCGPathStroke); CGContextBeginPath(zCgContextRef); CGContextMoveToPoint(zCgContextRef,170.0,150.0); CGContextAddQuadCurveToPoint(zCgContextRef, 145.0, 110.0, 120.0, 150.0); CGFloat zStrokeColour2[] = {0.0,0.0,0.4,1.0}; CGContextSetStrokeColor(zCgContextRef,zStrokeColour2); CGContextDrawPath(zCgContextRef,kCGPathStroke); CGContextBeginPath(zCgContextRef); CGContextMoveToPoint(zCgContextRef,40.0,100.0); CGContextAddQuadCurveToPoint(zCgContextRef, 30.0, 10.0, 170.0, 60.0); CGFloat zStrokeColour3[] = {1.0,0.0,0.0,1.0}; CGContextSetStrokeColor(zCgContextRef,zStrokeColour3); CGContextSetLineWidth(zCgContextRef,3.0); CGContextDrawPath(zCgContextRef,kCGPathStroke); } @end
Define the Custom View to display the Quartz drawing
Double click MainMenu.xib to bring it up.
Customise the view as shown above.
Select the custom view and in the Identity pane of the Inspector set its class to MyNSView.
Save and Run.
The finished Quartz drawing
If you want to download the code
Click the Download Link to obtain 031_CGContext.zip file of this whole OS X 10.5 Leopard program.