/ QuartzCore / CALayer.m
CALayer.m
1 #import <Foundation/NSDictionary.h> 2 #import <QuartzCore/CAAnimation.h> 3 #import <QuartzCore/CALayer.h> 4 #import <QuartzCore/CALayerContext.h> 5 #import <QuartzCore/CATransaction.h> 6 7 NSString *const kCAFilterLinear = @"linear"; 8 NSString *const kCAFilterNearest = @"nearest"; 9 NSString *const kCAFilterTrilinear = @"trilinear"; 10 11 NSString *const kCAGravityResizeAspect = @"resizeAspect"; 12 NSString *const kCAGravityResizeAspectFill = @"resizeAspectFill"; 13 14 NSString *const kCAGravityCenter = @"center"; 15 NSString *const kCAGravityTop = @"top"; 16 NSString *const kCAGravityBottom = @"bottom"; 17 NSString *const kCAGravityLeft = @"left"; 18 NSString *const kCAGravityRight = @"right"; 19 NSString *const kCAGravityTopLeft = @"topLeft"; 20 NSString *const kCAGravityTopRight = @"topRight"; 21 NSString *const kCAGravityBottomLeft = @"bottomLeft"; 22 NSString *const kCAGravityBottomRight = @"bottomRight"; 23 NSString *const kCAGravityResize = @"resize"; 24 25 NSString *const kCAOnOrderIn = @"onOrderIn"; 26 NSString *const kCAOnOrderOut = @"onOrderOut"; 27 NSString *const kCATransition = @"transition"; 28 29 NSString *const kCAContentsFormatRGBA8Uint = @"RGBA8"; 30 NSString *const kCAContentsFormatRGBA16Float = @"RGBAh"; 31 NSString *const kCAContentsFormatGray8Uint = @"Gray8"; 32 33 @implementation CALayer 34 35 + layer { 36 return [[[self alloc] init] autorelease]; 37 } 38 39 - (CALayerContext *) _context { 40 return _context; 41 } 42 43 - (void) _setContext: (CALayerContext *) context { 44 if (_context != context) { 45 [_context deleteTextureId: _textureId]; 46 [_textureId release]; 47 _textureId = nil; 48 } 49 50 _context = context; 51 [_sublayers makeObjectsPerformSelector: @selector(_setContext:) 52 withObject: context]; 53 } 54 55 - (CALayer *) superlayer { 56 return _superlayer; 57 } 58 59 - (NSArray *) sublayers { 60 return _sublayers; 61 } 62 63 - (void) setSublayers: (NSArray *) sublayers { 64 sublayers = [sublayers copy]; 65 [_sublayers release]; 66 _sublayers = sublayers; 67 [_sublayers makeObjectsPerformSelector: @selector(_setSuperLayer:) 68 withObject: self]; 69 [_sublayers makeObjectsPerformSelector: @selector(_setContext:) 70 withObject: _context]; 71 } 72 73 - (id<CALayerDelegate>) delegate { 74 return _delegate; 75 } 76 77 - (void) setDelegate: (id<CALayerDelegate>)value { 78 _delegate = value; 79 } 80 81 - (CGPoint) anchorPoint { 82 return _anchorPoint; 83 } 84 85 - (void) setAnchorPoint: (CGPoint) value { 86 _anchorPoint = value; 87 } 88 89 - (CGPoint) position { 90 return _position; 91 } 92 93 - (void) setPosition: (CGPoint) value { 94 CAAnimation *animation = [self animationForKey: @"position"]; 95 96 if (animation == nil && ![CATransaction disableActions]) { 97 id action = [self actionForKey: @"position"]; 98 99 if (action != nil) 100 [self addAnimation: action forKey: @"position"]; 101 } 102 103 _position = value; 104 } 105 106 - (CGRect) bounds { 107 return _bounds; 108 } 109 110 - (void) setBounds: (CGRect) value { 111 CAAnimation *animation = [self animationForKey: @"bounds"]; 112 113 if (animation == nil && ![CATransaction disableActions]) { 114 id action = [self actionForKey: @"bounds"]; 115 116 if (action != nil) 117 [self addAnimation: action forKey: @"bounds"]; 118 } 119 120 _bounds = value; 121 } 122 123 - (CGRect) frame { 124 CGRect result; 125 126 result.size = _bounds.size; 127 result.origin.x = _position.x - result.size.width * _anchorPoint.x; 128 result.origin.y = _position.y - result.size.height * _anchorPoint.y; 129 130 return result; 131 } 132 133 - (void) setFrame: (CGRect) value { 134 135 CGPoint position; 136 137 position.x = value.origin.x + value.size.width * _anchorPoint.x; 138 position.y = value.origin.y + value.size.height * _anchorPoint.y; 139 140 [self setPosition: position]; 141 142 CGRect bounds = _bounds; 143 144 bounds.size = value.size; 145 146 [self setBounds: bounds]; 147 } 148 149 - (CGFloat) opacity { 150 return _opacity; 151 } 152 153 - (void) setOpacity: (CGFloat) value { 154 CAAnimation *animation = [self animationForKey: @"opacity"]; 155 156 if (animation == nil && ![CATransaction disableActions]) { 157 id action = [self actionForKey: @"opacity"]; 158 159 if (action != nil) 160 [self addAnimation: action forKey: @"opacity"]; 161 } 162 163 _opacity = value; 164 } 165 166 - (BOOL) opaque { 167 return _opaque; 168 } 169 170 - (void) setOpaque: (BOOL) value { 171 _opaque = value; 172 } 173 174 - (id) contents { 175 return _contents; 176 } 177 178 - (void) setContents: (id) value { 179 value = [value retain]; 180 [_contents release]; 181 _contents = value; 182 } 183 184 - (CATransform3D) transform { 185 return _transform; 186 } 187 188 - (void) setTransform: (CATransform3D) value { 189 _transform = value; 190 } 191 192 - (CATransform3D) sublayerTransform { 193 return _sublayerTransform; 194 } 195 196 - (void) setSublayerTransform: (CATransform3D) value { 197 _sublayerTransform = value; 198 } 199 200 - (NSString *) minificationFilter { 201 return _minificationFilter; 202 } 203 204 - (void) setMinificationFilter: (NSString *) value { 205 value = [value copy]; 206 [_minificationFilter release]; 207 _minificationFilter = value; 208 } 209 210 - (NSString *) magnificationFilter { 211 return _magnificationFilter; 212 } 213 214 - (void) setMagnificationFilter: (NSString *) value { 215 value = [value copy]; 216 [_magnificationFilter release]; 217 _magnificationFilter = value; 218 } 219 220 - init { 221 _superlayer = nil; 222 _sublayers = [NSArray new]; 223 _delegate = nil; 224 _anchorPoint = CGPointMake(0.5, 0.5); 225 _position = CGPointZero; 226 _bounds = CGRectZero; 227 _opacity = 1.0; 228 _opaque = YES; 229 _contents = nil; 230 _transform = CATransform3DIdentity; 231 _sublayerTransform = CATransform3DIdentity; 232 _minificationFilter = kCAFilterLinear; 233 _magnificationFilter = kCAFilterLinear; 234 _animations = [[NSMutableDictionary alloc] init]; 235 return self; 236 } 237 238 - (void) dealloc { 239 [_sublayers release]; 240 [_animations release]; 241 [_minificationFilter release]; 242 [_magnificationFilter release]; 243 [super dealloc]; 244 } 245 246 - (void) _setSuperLayer: (CALayer *) parent { 247 _superlayer = parent; 248 } 249 250 - (void) _removeSublayer: (CALayer *) child { 251 NSMutableArray *layers = [_sublayers mutableCopy]; 252 [layers removeObjectIdenticalTo: child]; 253 [self setSublayers: layers]; 254 [layers release]; 255 } 256 257 - (void) addSublayer: (CALayer *) layer { 258 [self setSublayers: [_sublayers arrayByAddingObject: layer]]; 259 } 260 261 - (void) replaceSublayer: (CALayer *) layer with: (CALayer *) other { 262 NSMutableArray *layers = [_sublayers mutableCopy]; 263 NSUInteger index = [_sublayers indexOfObjectIdenticalTo: layer]; 264 265 [layers replaceObjectAtIndex: index withObject: other]; 266 267 [self setSublayers: layers]; 268 [layers release]; 269 270 layer->_superlayer = nil; 271 } 272 273 - (void) display { 274 if ([_delegate respondsToSelector: @selector(displayLayer:)]) 275 [_delegate displayLayer: self]; 276 else { 277 #if 0 278 279 #warning create bitmap context 280 281 [self drawInContext:context]; 282 _contents=image; 283 [self setContents:image]; 284 #endif 285 } 286 } 287 288 - (void) displayIfNeeded { 289 } 290 291 - (void) drawInContext: (CGContextRef) context { 292 if ([_delegate respondsToSelector: @selector(drawLayer:inContext:)]) 293 [_delegate drawLayer: self inContext: context]; 294 } 295 296 - (BOOL) needsDisplay { 297 return _needsDisplay; 298 } 299 300 - (void) removeFromSuperlayer { 301 [_superlayer _removeSublayer: self]; 302 _superlayer = nil; 303 [self _setContext: nil]; 304 } 305 306 - (void) setNeedsDisplay { 307 _needsDisplay = YES; 308 } 309 310 - (void) setNeedsDisplayInRect: (CGRect) rect { 311 _needsDisplay = YES; 312 } 313 314 - (void) addAnimation: (CAAnimation *) animation forKey: (NSString *) key { 315 if (_context == nil) 316 return; 317 318 [_animations setObject: animation forKey: key]; 319 [_context startTimerIfNeeded]; 320 } 321 322 - (CAAnimation *) animationForKey: (NSString *) key { 323 return [_animations objectForKey: key]; 324 } 325 326 - (void) removeAllAnimations { 327 [_animations removeAllObjects]; 328 } 329 330 - (void) removeAnimationForKey: (NSString *) key { 331 [_animations removeObjectForKey: key]; 332 } 333 334 - (NSArray *) animationKeys { 335 return [_animations allKeys]; 336 } 337 338 - valueForKey: (NSString *) key { 339 // FIXME: KVC appears broken for structs 340 341 if ([key isEqualToString: @"bounds"]) 342 return [NSValue valueWithRect: _bounds]; 343 if ([key isEqualToString: @"frame"]) 344 return [NSValue valueWithRect: [self frame]]; 345 346 return [super valueForKey: key]; 347 } 348 349 - (id<CAAction>) actionForKey: (NSString *) key { 350 CABasicAnimation *basic = [CABasicAnimation animationWithKeyPath: key]; 351 352 [basic setFromValue: [self valueForKey: key]]; 353 354 return basic; 355 } 356 357 - (NSNumber *) _textureId { 358 return _textureId; 359 } 360 361 - (void) _setTextureId: (NSNumber *) value { 362 value = [value copy]; 363 [_textureId release]; 364 _textureId = value; 365 } 366 367 @end