/core/externals/google-toolbox-for-mac/AppKit/GTMNSAnimatablePropertyContainer.m

http://macfuse.googlecode.com/ · Objective C · 124 lines · 71 code · 21 blank · 32 comment · 9 complexity · 1cdbf3ca56da792d281516d08117d816 MD5 · raw file

  1. //
  2. // GTMNSAnimatablePropertyContainer.m
  3. //
  4. // Copyright (c) 2010 Google Inc. All rights reserved.
  5. //
  6. // Licensed under the Apache License, Version 2.0 (the "License"); you may not
  7. // use this file except in compliance with the License. You may obtain a copy
  8. // of the License at
  9. //
  10. // http://www.apache.org/licenses/LICENSE-2.0
  11. //
  12. // Unless required by applicable law or agreed to in writing, software
  13. // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  14. // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  15. // License for the specific language governing permissions and limitations under
  16. // the License.
  17. //
  18. #import "GTMNSAnimatablePropertyContainer.h"
  19. #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
  20. @interface GTMAnimatorStopper : NSObject {
  21. @private
  22. NSObject<NSAnimatablePropertyContainer> *container_;
  23. }
  24. @end
  25. @implementation GTMAnimatorStopper
  26. - (id)initWithAnimatablePropertyContainer:(NSObject<NSAnimatablePropertyContainer>*) container {
  27. if ((self = [super init])) {
  28. container_ = [container retain];
  29. }
  30. return self;
  31. }
  32. - (void)dealloc {
  33. [container_ release];
  34. [super dealloc];
  35. }
  36. - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
  37. return [container_ methodSignatureForSelector:aSelector];
  38. }
  39. - (void)forwardInvocation:(NSInvocation *)anInvocation {
  40. SEL selector = [anInvocation selector];
  41. NSString *selectorName = NSStringFromSelector(selector);
  42. // NSWindow animator handles setFrame:display: which is an odd case
  43. // for animator. All other methods take just a key value, so we convert
  44. // this to it's equivalent key value.
  45. if ([selectorName isEqual:@"setFrame:display:"]) {
  46. selectorName = @"setFrame:";
  47. }
  48. // Check to make sure our selector is valid (starts with set and has a
  49. // single : at the end.
  50. NSRange colonRange = [selectorName rangeOfString:@":"];
  51. NSUInteger selectorLength = [selectorName length];
  52. if ([selectorName hasPrefix:@"set"]
  53. && colonRange.location == selectorLength - 1
  54. && selectorLength > 4) {
  55. // transform our selector into a keyValue by removing the set
  56. // and the colon and converting the first char down to lowercase.
  57. NSString *keyValue = [selectorName substringFromIndex:3];
  58. NSString *firstChar = [[keyValue substringToIndex:1] lowercaseString];
  59. NSRange rest = NSMakeRange(1, [keyValue length] - 2);
  60. NSString *restOfKey = [keyValue substringWithRange:rest];
  61. keyValue = [firstChar stringByAppendingString:restOfKey];
  62. // Save a copy of our old animations.
  63. NSDictionary *oldAnimations
  64. = [[[container_ animations] copy] autorelease];
  65. // For frame the animator doesn't actually animate the rect but gets
  66. // animators for the size and the origin independently. In case this changes
  67. // in the future (similar to bounds), we will stop the animations for the
  68. // frame as well as the frameSize and frameOrigin.
  69. NSDictionary *animations = nil;
  70. NSNull *null = [NSNull null];
  71. if ([keyValue isEqual:@"frame"]) {
  72. animations = [NSDictionary dictionaryWithObjectsAndKeys:
  73. null, @"frame",
  74. null, @"frameSize",
  75. null, @"frameOrigin", nil];
  76. } else {
  77. animations = [NSDictionary dictionaryWithObject:null forKey:keyValue];
  78. }
  79. // Set our animations to NULL which will force them to stop.
  80. [container_ setAnimations:animations];
  81. // Call our original invocation on our animator.
  82. [anInvocation setTarget:[container_ animator]];
  83. [anInvocation invoke];
  84. // Reset the animations.
  85. [container_ setAnimations:oldAnimations];
  86. } else {
  87. [self doesNotRecognizeSelector:selector];
  88. }
  89. }
  90. @end
  91. @implementation NSView(GTMNSAnimatablePropertyContainer)
  92. - (id)gtm_animatorStopper {
  93. return [[[GTMAnimatorStopper alloc] initWithAnimatablePropertyContainer:self]
  94. autorelease];
  95. }
  96. @end
  97. @implementation NSWindow(GTMNSAnimatablePropertyContainer)
  98. - (id)gtm_animatorStopper {
  99. return [[[GTMAnimatorStopper alloc] initWithAnimatablePropertyContainer:self]
  100. autorelease];
  101. }
  102. @end
  103. #endif // MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5