Source/GGBLayer.m
changeset 2 7b0441db81e5
child 4 d781b00f3ed4
     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