Source/GGBLayer.m
author Jens Alfke <jens@mooseyard.com>
Mon Mar 10 17:32:04 2008 -0700 (2008-03-10)
changeset 2 7b0441db81e5
child 4 d781b00f3ed4
permissions -rw-r--r--
Oops, needed to fix an #include
     1 //
     2 //  GGBLayer.m
     3 //  GGB-iPhone
     4 //
     5 //  Created by Jens Alfke on 3/7/08.
     6 //  Copyright 2008 __MyCompanyName__. All rights reserved.
     7 //
     8 
     9 #import "GGBLayer.h"
    10 #import "QuartzUtils.h"
    11 
    12 
    13 @implementation GGBLayer
    14 
    15 
    16 - (NSString*) description
    17 {
    18     return [NSString stringWithFormat: @"%@[(%g,%g)]", self.class,self.position.x,self.position.y];
    19 }
    20 
    21 
    22 #if TARGET_OS_ASPEN
    23 
    24 #pragma mark -
    25 #pragma mark IPHONE VERSION:
    26 
    27 
    28 - (id) copyWithZone: (NSZone*)zone
    29 {
    30     GGBLayer *clone = [[[self class] alloc] init];
    31     clone.bounds = self.bounds;
    32     clone.position = self.position;
    33     clone.zPosition = self.zPosition;
    34     clone.anchorPoint = self.anchorPoint;
    35     clone.transform = self.transform;
    36     clone.hidden = self.hidden;
    37     clone.doubleSided = self.doubleSided;
    38     clone.sublayerTransform = self.sublayerTransform;
    39     clone.masksToBounds = self.masksToBounds;
    40     clone.contents = self.contents;                 // doesn't copy contents (shallow-copy)
    41     clone.contentsRect = self.contentsRect;
    42     clone.contentsGravity = self.contentsGravity;
    43     clone.minificationFilter = self.minificationFilter;
    44     clone.magnificationFilter = self.magnificationFilter;
    45     clone.opaque = self.opaque;
    46     clone.needsDisplayOnBoundsChange = self.needsDisplayOnBoundsChange;
    47     clone.edgeAntialiasingMask = self.edgeAntialiasingMask;
    48     clone.backgroundColor = self.backgroundColor;
    49     clone.opacity = self.opacity;
    50     clone.compositingFilter = self.compositingFilter;
    51     clone.filters = self.filters;
    52     clone.backgroundFilters = self.backgroundFilters;
    53     clone.actions = self.actions;
    54     clone.name = self.name;
    55     clone.style = self.style;
    56     
    57     clone.cornerRadius = self.cornerRadius;
    58     clone.borderWidth = self.borderWidth;
    59     clone.borderColor = self.borderColor;
    60     clone.autoresizingMask = self.autoresizingMask;
    61     
    62     for( GGBLayer *sublayer in self.sublayers ) {
    63         sublayer = [sublayer copyWithZone: zone];
    64         [clone addSublayer: sublayer];
    65     }
    66     return clone;
    67 }
    68 
    69 
    70 @synthesize autoresizingMask=_autoresizingMask;
    71 
    72 - (CGFloat) cornerRadius    {return _cornerRadius;}
    73 - (CGFloat) borderWidth     {return _borderWidth;}
    74 - (CGColorRef) borderColor  {return _borderColor;}
    75 
    76 - (void) setCornerRadius: (CGFloat)r
    77 {
    78     if( r != _cornerRadius ) {
    79         _cornerRadius = r;
    80         [self setNeedsDisplay];
    81     }
    82 }
    83 
    84 
    85 - (void) setBorderWidth: (CGFloat)w
    86 {
    87     if( w != _borderWidth ) {
    88         _borderWidth = w;
    89         self.needsDisplayOnBoundsChange = (_borderWidth>0.0 && _borderColor!=NULL);
    90         [self setNeedsDisplay];
    91     }
    92 }
    93 
    94 
    95 - (void) setBackgroundColor: (CGColorRef)color
    96 {
    97     if( color != _realBGColor ) {
    98         CGColorRelease(_realBGColor);
    99         _realBGColor = CGColorRetain(color);
   100         [self setNeedsDisplay];
   101     }
   102 }
   103 
   104 
   105 - (void) setBorderColor: (CGColorRef)color
   106 {
   107     if( color != _borderColor ) {
   108         CGColorRelease(_borderColor);
   109         _borderColor = CGColorRetain(color);
   110         self.needsDisplayOnBoundsChange = (_borderWidth>0.0 && _borderColor!=NULL);
   111         [self setNeedsDisplay];
   112     }
   113 }
   114 
   115 
   116 - (void)drawInContext:(CGContextRef)ctx
   117 {
   118     CGContextSaveGState(ctx);
   119 
   120     if( _realBGColor ) {
   121         CGRect interior = CGRectInset(self.bounds, _borderWidth,_borderWidth);
   122         CGContextSetFillColorWithColor(ctx, _realBGColor);
   123         if( _cornerRadius <= 0.0 ) {
   124             CGContextFillRect(ctx,interior);
   125         } else {
   126             CGContextBeginPath(ctx);
   127             AddRoundRect(ctx,interior,_cornerRadius);
   128             CGContextFillPath(ctx);
   129         }
   130     }
   131     
   132     if( _borderWidth > 0.0 && _borderColor!=NULL ) {
   133         CGRect border = CGRectInset(self.bounds, _borderWidth/2.0, _borderWidth/2.0);
   134         CGContextSetStrokeColorWithColor(ctx, _borderColor);
   135         CGContextSetLineWidth(ctx, _borderWidth);
   136         
   137         if( _cornerRadius <= 0.0 ) {
   138             CGContextStrokeRect(ctx,border);
   139         } else {
   140             CGContextBeginPath(ctx);
   141             AddRoundRect(ctx,border,_cornerRadius);
   142             CGContextStrokePath(ctx);
   143         }
   144     }
   145     
   146     CGContextRestoreGState(ctx);
   147 }
   148 
   149 
   150 #else
   151 
   152 #pragma mark -
   153 #pragma mark MAC OS VERSION:
   154 
   155 
   156 - (id) copyWithZone: (NSZone*)zone
   157 {
   158     // NSLayer isn't copyable, but it is archivable. So create a copy by archiving to
   159     // a temporary data block, then unarchiving a new layer from that block.
   160     
   161     // One complication is that, due to a bug in Core Animation, CALayer can't archive
   162     // a pattern-based CGColor. So as a workaround, clear the background before archiving,
   163     // then restore it afterwards.
   164     
   165     // Also, archiving a CALayer with an image in it leaks memory. (Filed as rdar://5786865 )
   166     // As a workaround, clear the contents before archiving, then restore.
   167     
   168     CGColorRef bg = CGColorRetain(self.backgroundColor);
   169     self.backgroundColor = NULL;
   170     id contents = [self.contents retain];
   171     self.contents = nil;
   172     
   173     NSData *data = [NSKeyedArchiver archivedDataWithRootObject: self];
   174     
   175     self.backgroundColor = bg;
   176     self.contents = contents;
   177 
   178     GGBLayer *clone = [NSKeyedUnarchiver unarchiveObjectWithData: data];
   179     clone.backgroundColor = bg;
   180     clone.contents = contents;
   181     CGColorRelease(bg);
   182     [contents release];
   183 
   184     return [clone retain];
   185 }
   186 
   187 
   188 #endif
   189 
   190 
   191 @end