TileView.h
#import <Cocoa/Cocoa.h>
@interface TileView : NSMatrix { NSSize minSize; NSImage *image; }
@interface Tile : NSActionCell @end
TileView.m
#import “TileView.h”
static unsigned TileCount(float dim, float min, float gap, float *cellDim) { unsigned cnt = (unsigned)(dim / (min + gap)); if (!cnt) cnt++; *cellDim = (dim / (float)cnt) - gap; return cnt; }
@implementation TileView // NSMatrix
(void)setImage:(NSImage *)img { [img retain]; [image release]; [(image = img) setFlipped:YES]; }
(void)dealloc { [image release]; [super dealloc]; }
}
(void)drawRect:(NSRect)rect {
// asking super to drawRect here will tile the background with the image [super drawRect:rect];
// your custom drawing code here [[NSColor colorWithCalibratedRed:0.0f green:1.0f blue:0.0f alpha:0.5f] set]; NSRect greenRect = NSInsetRect(rect, NSWidth(rect) / 4.0f, NSHeight(rect) / 4.0f); NSRectFillListUsingOperation(&greenRect, 1, NSCompositeSourceOver); }
(NSRect)boundsForFrame:(NSRect)fr size:(NSSize)size { NSSize spacing = [self intercellSpacing]; float srcRatio = size.width / size.height; NSRect bounds = (srcRatio > NSWidth(fr) / NSHeight(fr)) ? NSInsetRect(fr, 0.0f, (NSHeight(fr) - NSWidth(fr) / srcRatio) / 2.0f) : NSInsetRect(fr, (NSWidth(fr) - NSHeight(fr) * srcRatio) / 2.0f, 0.0f); return NSOffsetRect(bounds, spacing.width / 2.0f, spacing.height / 2.0f); }
@end
@implementation Tile
@end
–zootbobbalu
I haven’t tried it, but wouldn’t this be a lot easier by using + (NSColor )colorWithPatternImage:(NSImage)image; and then just filling the whole view, forgetting about NSMatrix?
Hey that’s pretty cool. Never noticed that method before. You can draw different images for each cell in the matrix, but colorWithPatternImage is really nice because you can fill shapes. I also noticed that the pattern will start at the bottom left corner of the window, so if you want to have the tile conform to a view you can’t use colorWithPatternImage. –zootbobbalu
Interesting point about starting in the corner of the window, I guess it wouldn’t work too well for this view, then.
You can constrain any arbitrary drawing to fill a shape by doing [shape addClip] before drawing, assuming shape is an NSBezierPath. This will clip all future drawing to be inside the given path, which comes in handy sometimes.