91: Resize an NSImage as we resize an NSWindow

Problem: we want to resize an NSImage at same time as user is resizing the NSWindow that contains it.

The content view of the NSWindow is initially to be the same size as the NSImage. As the user drags the window sizing handle so the window retains the NSImage proportions (aspect ratio) and the NSImage is drawn the same size as the window's content view.


Basic Approach

Make the view an NSWindowDelegate.

When passing the NSImage to the view set the window's aspect ratio using setContentAspectRatio:(NSRect)rect.

Override the delegate method windowDidResize to change the NSView rect to the new content size.

Tell the view to redraw itself.


Download

This XCode 3.2.6 project exists as a 4.5 MB download.


Coding

Create a new XCode Cocoa application project.
Call it Scale-window-image.
In the Groups and Files collumn select Scale-window-image and click Info.
Under the build tab scroll down to Objective-C Garbage Collection and make it Required.
In XCode choose File->New File.
Choose an Objective-C Class of type NSView.
Call it MyView.
Make Scale_window_imageAppDelegate.h and MyView.h look as follows:

// Scale_window_imageAppDelegate.h #import @class MyView; @interface Scale_window_imageAppDelegate : NSObject { IBOutlet NSWindow *window; IBOutlet MyView * myViewObj; NSImage * nsImageObj; } @property (assign) IBOutlet NSWindow *window; @property (assign) IBOutlet MyView * myViewObj; @property (assign) NSImage * nsImageObj; @end

// MyView.h #import @interface MyView : NSView { NSImage * nsImageObj; } @property (assign) NSImage * nsImageObj; @end

Make Scale_window_imageAppDelegate.m and MyView.m look as follows:

// Scale_window_imageAppDelegate.m #import "Scale_window_imageAppDelegate.h" #import "MyView.h" @implementation Scale_window_imageAppDelegate @synthesize window; @synthesize myViewObj; @synthesize nsImageObj; - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { NSString * zStrFilename = @"../../../palm-tree.jpg"; self.nsImageObj = [[NSImage alloc]initWithContentsOfFile:zStrFilename]; if(self.nsImageObj == nil) { NSLog(@"self.nsImageObj == nil"); exit(1); } // end if [self.myViewObj addImage:self.nsImageObj]; } // end applicationDidFinishLaunching @end

// MyView.m #import "MyView.h" @implementation MyView @synthesize nsImageObj; - (id)initWithFrame:(NSRect)frame { self = [super initWithFrame:frame]; if (self) { // Initialization code here. } return self; } // end initWithFrame - (void)windowDidResize:(NSNotification *)notification { // Delegate method NSRect zWindowRect = [[self window]frame]; NSRect zContentRect = [[self window]contentRectForFrameRect:zWindowRect]; NSRect zRectOfView = NSMakeRect(0.0,0.0,zContentRect.size.width, zContentRect.size.height); [self setFrame:zRectOfView]; [self setNeedsDisplay:YES]; } // end windowDidResize -(void)addImage:(NSImage *)pImage { self.nsImageObj = pImage; NSSize zSizeAspectRatio = NSMakeSize(pImage.size.width,pImage.size.height); [[self window]setContentAspectRatio:zSizeAspectRatio]; [[self window]setContentSize:zSizeAspectRatio]; [self setNeedsDisplay:YES]; } // end addImage - (void)drawRect:(NSRect)dirtyRect { if(self.nsImageObj == nil) { [[NSColor blueColor]set]; [NSBezierPath fillRect:[self bounds]]; return; } // end if [self.nsImageObj drawInRect:[self bounds] fromRect:NSZeroRect operation:NSCompositeCopy fraction:1.0]; } // end drawRect @end

Build and run.

NSImage in NSWindow before and after resize

NSImage in NSWindow before and after resize


Download

This XCode 3.2.6 project exists as a 4.5 MB download.



Please send me your comments

If you include your e-mail I may reply!  

Page last modified: 11:57 Monday 7th. November 2011