1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/Source/GGBLayer.m Mon Mar 10 17:32:04 2008 -0700
1.3 @@ -0,0 +1,191 @@
1.4 +//
1.5 +// GGBLayer.m
1.6 +// GGB-iPhone
1.7 +//
1.8 +// Created by Jens Alfke on 3/7/08.
1.9 +// Copyright 2008 __MyCompanyName__. All rights reserved.
1.10 +//
1.11 +
1.12 +#import "GGBLayer.h"
1.13 +#import "QuartzUtils.h"
1.14 +
1.15 +
1.16 +@implementation GGBLayer
1.17 +
1.18 +
1.19 +- (NSString*) description
1.20 +{
1.21 + return [NSString stringWithFormat: @"%@[(%g,%g)]", self.class,self.position.x,self.position.y];
1.22 +}
1.23 +
1.24 +
1.25 +#if TARGET_OS_ASPEN
1.26 +
1.27 +#pragma mark -
1.28 +#pragma mark IPHONE VERSION:
1.29 +
1.30 +
1.31 +- (id) copyWithZone: (NSZone*)zone
1.32 +{
1.33 + GGBLayer *clone = [[[self class] alloc] init];
1.34 + clone.bounds = self.bounds;
1.35 + clone.position = self.position;
1.36 + clone.zPosition = self.zPosition;
1.37 + clone.anchorPoint = self.anchorPoint;
1.38 + clone.transform = self.transform;
1.39 + clone.hidden = self.hidden;
1.40 + clone.doubleSided = self.doubleSided;
1.41 + clone.sublayerTransform = self.sublayerTransform;
1.42 + clone.masksToBounds = self.masksToBounds;
1.43 + clone.contents = self.contents; // doesn't copy contents (shallow-copy)
1.44 + clone.contentsRect = self.contentsRect;
1.45 + clone.contentsGravity = self.contentsGravity;
1.46 + clone.minificationFilter = self.minificationFilter;
1.47 + clone.magnificationFilter = self.magnificationFilter;
1.48 + clone.opaque = self.opaque;
1.49 + clone.needsDisplayOnBoundsChange = self.needsDisplayOnBoundsChange;
1.50 + clone.edgeAntialiasingMask = self.edgeAntialiasingMask;
1.51 + clone.backgroundColor = self.backgroundColor;
1.52 + clone.opacity = self.opacity;
1.53 + clone.compositingFilter = self.compositingFilter;
1.54 + clone.filters = self.filters;
1.55 + clone.backgroundFilters = self.backgroundFilters;
1.56 + clone.actions = self.actions;
1.57 + clone.name = self.name;
1.58 + clone.style = self.style;
1.59 +
1.60 + clone.cornerRadius = self.cornerRadius;
1.61 + clone.borderWidth = self.borderWidth;
1.62 + clone.borderColor = self.borderColor;
1.63 + clone.autoresizingMask = self.autoresizingMask;
1.64 +
1.65 + for( GGBLayer *sublayer in self.sublayers ) {
1.66 + sublayer = [sublayer copyWithZone: zone];
1.67 + [clone addSublayer: sublayer];
1.68 + }
1.69 + return clone;
1.70 +}
1.71 +
1.72 +
1.73 +@synthesize autoresizingMask=_autoresizingMask;
1.74 +
1.75 +- (CGFloat) cornerRadius {return _cornerRadius;}
1.76 +- (CGFloat) borderWidth {return _borderWidth;}
1.77 +- (CGColorRef) borderColor {return _borderColor;}
1.78 +
1.79 +- (void) setCornerRadius: (CGFloat)r
1.80 +{
1.81 + if( r != _cornerRadius ) {
1.82 + _cornerRadius = r;
1.83 + [self setNeedsDisplay];
1.84 + }
1.85 +}
1.86 +
1.87 +
1.88 +- (void) setBorderWidth: (CGFloat)w
1.89 +{
1.90 + if( w != _borderWidth ) {
1.91 + _borderWidth = w;
1.92 + self.needsDisplayOnBoundsChange = (_borderWidth>0.0 && _borderColor!=NULL);
1.93 + [self setNeedsDisplay];
1.94 + }
1.95 +}
1.96 +
1.97 +
1.98 +- (void) setBackgroundColor: (CGColorRef)color
1.99 +{
1.100 + if( color != _realBGColor ) {
1.101 + CGColorRelease(_realBGColor);
1.102 + _realBGColor = CGColorRetain(color);
1.103 + [self setNeedsDisplay];
1.104 + }
1.105 +}
1.106 +
1.107 +
1.108 +- (void) setBorderColor: (CGColorRef)color
1.109 +{
1.110 + if( color != _borderColor ) {
1.111 + CGColorRelease(_borderColor);
1.112 + _borderColor = CGColorRetain(color);
1.113 + self.needsDisplayOnBoundsChange = (_borderWidth>0.0 && _borderColor!=NULL);
1.114 + [self setNeedsDisplay];
1.115 + }
1.116 +}
1.117 +
1.118 +
1.119 +- (void)drawInContext:(CGContextRef)ctx
1.120 +{
1.121 + CGContextSaveGState(ctx);
1.122 +
1.123 + if( _realBGColor ) {
1.124 + CGRect interior = CGRectInset(self.bounds, _borderWidth,_borderWidth);
1.125 + CGContextSetFillColorWithColor(ctx, _realBGColor);
1.126 + if( _cornerRadius <= 0.0 ) {
1.127 + CGContextFillRect(ctx,interior);
1.128 + } else {
1.129 + CGContextBeginPath(ctx);
1.130 + AddRoundRect(ctx,interior,_cornerRadius);
1.131 + CGContextFillPath(ctx);
1.132 + }
1.133 + }
1.134 +
1.135 + if( _borderWidth > 0.0 && _borderColor!=NULL ) {
1.136 + CGRect border = CGRectInset(self.bounds, _borderWidth/2.0, _borderWidth/2.0);
1.137 + CGContextSetStrokeColorWithColor(ctx, _borderColor);
1.138 + CGContextSetLineWidth(ctx, _borderWidth);
1.139 +
1.140 + if( _cornerRadius <= 0.0 ) {
1.141 + CGContextStrokeRect(ctx,border);
1.142 + } else {
1.143 + CGContextBeginPath(ctx);
1.144 + AddRoundRect(ctx,border,_cornerRadius);
1.145 + CGContextStrokePath(ctx);
1.146 + }
1.147 + }
1.148 +
1.149 + CGContextRestoreGState(ctx);
1.150 +}
1.151 +
1.152 +
1.153 +#else
1.154 +
1.155 +#pragma mark -
1.156 +#pragma mark MAC OS VERSION:
1.157 +
1.158 +
1.159 +- (id) copyWithZone: (NSZone*)zone
1.160 +{
1.161 + // NSLayer isn't copyable, but it is archivable. So create a copy by archiving to
1.162 + // a temporary data block, then unarchiving a new layer from that block.
1.163 +
1.164 + // One complication is that, due to a bug in Core Animation, CALayer can't archive
1.165 + // a pattern-based CGColor. So as a workaround, clear the background before archiving,
1.166 + // then restore it afterwards.
1.167 +
1.168 + // Also, archiving a CALayer with an image in it leaks memory. (Filed as rdar://5786865 )
1.169 + // As a workaround, clear the contents before archiving, then restore.
1.170 +
1.171 + CGColorRef bg = CGColorRetain(self.backgroundColor);
1.172 + self.backgroundColor = NULL;
1.173 + id contents = [self.contents retain];
1.174 + self.contents = nil;
1.175 +
1.176 + NSData *data = [NSKeyedArchiver archivedDataWithRootObject: self];
1.177 +
1.178 + self.backgroundColor = bg;
1.179 + self.contents = contents;
1.180 +
1.181 + GGBLayer *clone = [NSKeyedUnarchiver unarchiveObjectWithData: data];
1.182 + clone.backgroundColor = bg;
1.183 + clone.contents = contents;
1.184 + CGColorRelease(bg);
1.185 + [contents release];
1.186 +
1.187 + return [clone retain];
1.188 +}
1.189 +
1.190 +
1.191 +#endif
1.192 +
1.193 +
1.194 +@end