Introduction To Cocoa Programming For Macosx: Arthur Clemens
Introduction To Cocoa Programming For Macosx: Arthur Clemens
Cocoa
Programming for
Mac OS X
Arthur Clemens
27 May 2008 - Amsterdam
What we are going to create
What are
we going
to make?
What will you learn?
XCode Tools
Interface Builder
Objective-C
How to open and process files:
open dialog, drag on icon, drag on app
Extending classes
Image resizing
Messaging
Saving
http://developer.apple.com/
“AppController”
ctrl-drag
AppController.m
- (IBAction)exportImage:(id)sender
{
NSLog(@"export:%@", sender);
}
- (IBAction)updateSliderValue:(id)sender
{
NSLog(@"updateSliderValue:%f", [sender floatValue]);
}
AppController.m
- (id)init
{
self = [super init];
if (self) {
NSLog(@"exportButton=%@", exportButton);
}
return self;
}
- (void)awakeFromNib
{
NSLog(@"exportButton=%@", exportButton);
}
AppController.m
- (void)awakeFromNib
{
[imageSizeText setStringValue:@""];
}
- (IBAction)updateSliderValue:(id)sender
{
[imageSizeText setStringValue:[sender
stringValue]];
}
pointer to object:
NSMutableArray* list;
list = [NSMutableArray alloc];
initialize object:
NSMutableArray* list;
list = [NSMutableArray alloc];
[list init];
shorthand:
NSMutableArray* list = [[NSMutableArray alloc] init];
destroy:
[list release];
multiple arguments:
[list insertObject:foo atIndex:5];
selector = insertObject:atIndex:
return values:
int x = [list count];
NSMutableArray* list =
[[[NSMutableArray alloc] init] autorelease];
or:
[NSNumber numberWithInt:5];
convenience constructor, see:
+ (NSNumber *)numberWithInt:(int)value
Cocoa class methods return autoreleased objects
AppController.m
- (void)setImageFilePath:(NSString*)newFilePath
{
[newFilePath retain];
[imageFilePath release];
imageFilePath = newFilePath;
}
- (NSString*)imageFilePath
{
return imageFilePath;
}
- (void)dealloc
{
[self setImageFilePath:nil];
[super dealloc];
}
Very simple rules for memory management in Cocoa
http://www.stepwise.com/Articles/Technical/2001-03-11.01.html
27 May 2008 | Introduction to Cocoa | 22
Opening an image file in a dialog window
AppController.m
- (IBAction)showOpenPanel:(id)sender
{
NSOpenPanel *op = [NSOpenPanel openPanel];
[op beginSheetForDirectory:nil
file:nil
types:[NSImage imageFileTypes]
modalForWindow:[NSApp mainWindow]
modalDelegate:self
didEndSelector:@selector(openPanelDidEnd:returnCode:contextInfo:)
contextInfo:nil];
}
- (void)openPanelDidEnd:(NSOpenPanel *)op only PNG:
returnCode:(int)returnCode
[NSArray arrayWithObject:@"png"]
contextInfo:(void *)ci
PNG and GIF:
{
[NSArray
if (returnCode != NSOKButton) return;
arrayWithObjects:@"png",@"gif",nil]
NSString *path = [op filename];
}
AppController.h
- (BOOL)importImageFromPath:(NSString*)path
{
NSImage *image = [[[NSImage alloc] initWithContentsOfFile:path] autorelease];
if (!image) return NO;
[imageView setImage:image];
return YES;
}
Update:
- (void)openPanelDidEnd:(NSOpenPanel *)op
returnCode:(int)returnCode
contextInfo:(void *)ci
{
if (returnCode != NSOKButton) return;
NSString *path = [op filename];
[self importImageFromPath:path];
[self setImageFilePath:path];
}
AppController.m
- (BOOL)application:(NSApplication *)theApplication
openFile:(NSString *)path
{
// do a check on filetype here...
BOOL result = [self importImageFromPath:path];
if (!result) return NO;
[self setImageFilePath:path];
return YES;
}
Command-i
Step 3: drag new .h file onto IB and set view to new subclass...
@implementation ImageView
- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
{
return NSDragOperationLink;
}
- (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender
{
return YES;
}
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
{
return YES;
}
- (void)concludeDragOperation:(id <NSDraggingInfo>)sender
{
[super concludeDragOperation:sender];
}
@end
AppController.m
- (void)awakeFromNib
{
[imageSizeText setStringValue:@""];
NSString* path = [[NSBundle mainBundle]
pathForImageResource:@"anteprima.com.png"];
[self importImageFromPath:path];
}
ImageView.m
- (void)drawRect:(NSRect)rect
{
if ([self image]) {
NSRect imageRect;
imageRect.origin = NSZeroPoint;
imageRect.size = [[self image] size];
ImageView.m
- (BOOL)isFlipped
{
return YES;
}
- (void)drawRect:(NSRect)rect
{
if ([self image]) {
NSRect imageRect;
imageRect.origin = NSZeroPoint;
imageRect.size = [[self image] size];
ImageView.m
- (void)setZoomFactor:(NSNumber*)newZoomFactor
{
[newZoomFactor retain];
[zoomFactor release];
zoomFactor = newZoomFactor;
[self setNeedsDisplay:YES];
}
- (void)dealloc
{
[self setZoomFactor:nil];
[super dealloc];
}
- (id)initWithFrame:(NSRect)frame {
if (![super initWithFrame:frame]) {
return nil;
}
[self setZoomFactor:[NSNumber numberWithFloat:1]];
return self;
}
- (IBAction)updateSliderValue:(id)sender
{
[imageView setZoomFactor:[sender objectValue]];
}
[transform translateXBy:0.0
yBy:[zoomFactor floatValue] * imageRect.size.height];
ImageView.m
- (void)notifyImageUpdated
{
[[NSNotificationCenter defaultCenter] postNotificationName:@"imageUpdated"
object:[self
imageSize]];
}
- (NSValue*)imageSize
{
NSSize imageSize = [[self image] size];
imageSize.width *= [zoomFactor floatValue];
imageSize.height *= [zoomFactor floatValue];
return [NSValue valueWithSize:imageSize];
}
Add to setZoomFactor:
[self notifyImageUpdated];
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[self setImageFilePath:nil];
[super dealloc];
}
- (void)handleImageUpdated:(NSNotification*)note
{
NSSize size = [[note object] sizeValue];
[imageSizeText setStringValue:[NSString stringWithFormat:@"%.0f x %.0f",
size.width, size.height]];
}
- (void)handleImageDragged:(NSNotification*)note
{
NSString* imagePath = [note object];
[self setImageFilePath:imagePath];
}
PrettyPrintCategory.m
#import "PrettyPrintCategory.h"
@end
ImageViewAdditions.m
- (NSImage*)imageOfSize:(NSSize)size
{
NSImage* sourceImage = [self image];
NSRect scaledRect;
scaledRect.origin = NSZeroPoint;
scaledRect.size.width = size.width;
scaledRect.size.height = size.height;
NSImage* copyOfImage = [[[NSImage alloc] initWithSize:size] autorelease];
[copyOfImage lockFocus];
[[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationHigh];
[sourceImage drawInRect:scaledRect
fromRect:NSZeroRect
operation:NSCompositeSourceOver
fraction:1.0];
[copyOfImage unlockFocus];
return copyOfImage;
}
@end
- (NSString*)createFilePath:(NSString*)imageFilePath size:(NSSize)size
{
NSString *pathExtension = [imageFilePath pathExtension];
NSString* barePath = [imageFilePath stringByDeletingPathExtension];
return [NSString stringWithFormat:@"%@_%.0fx%.0f.png", barePath, size.width, size.height];
}
- (BOOL)saveImage:(NSImage*)image toPath:(NSString*)path
{
NSData *imageAsData = [image TIFFRepresentation];
NSBitmapImageRep *imageRep = [NSBitmapImageRep imageRepWithData:imageAsData];
NSData* fileData = [imageRep representationUsingType:NSPNGFileType properties:nil];
NSString* filePath = [path stringByExpandingTildeInPath];
BOOL success = [fileData writeToFile:[path stringByExpandingTildeInPath] atomically:YES];
return YES;
}