/ 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