/Frameworks/CCControlExtension/CCControl/Utils/CCScale9Sprite.m

https://bitbucket.org/mfavis/fixierush · Objective C · 685 lines · 526 code · 117 blank · 42 comment · 34 complexity · 418e43efe0ad332d98e70cb4ee430a4e MD5 · raw file

  1. //
  2. // Scale9Sprite.m
  3. //
  4. // Creates a 9-slice sprite.
  5. //
  6. #import "CCScale9Sprite.h"
  7. #import "ARCMacro.h"
  8. enum positions
  9. {
  10. pCentre = 0,
  11. pTop,
  12. pLeft,
  13. pRight,
  14. pBottom,
  15. pTopRight,
  16. pTopLeft,
  17. pBottomRight,
  18. pBottomLeft
  19. };
  20. @interface CCScale9Sprite ()
  21. - (id)initWithBatchNode:(CCSpriteBatchNode *)batchnode rect:(CGRect)rect capInsets:(CGRect)capInsets;
  22. - (void)updateWithBatchNode:(CCSpriteBatchNode*)batchnode rect:(CGRect)rect rotated:(BOOL)rotated capInsets:(CGRect)capInsets;
  23. - (void)updatePosition;
  24. @end
  25. @implementation CCScale9Sprite
  26. @synthesize originalSize = _originalSize;
  27. @synthesize capInsets = _capInsets;
  28. @synthesize insetTop = _insetTop;
  29. @synthesize insetLeft = _insetLeft;
  30. @synthesize insetBottom = _insetBottom;
  31. @synthesize insetRight = _insetRight;
  32. @synthesize preferredSize = _preferredSize;
  33. // CCRGBAProtocol (v2.1)
  34. @synthesize opacity = _opacity;
  35. @synthesize displayedOpacity = _displayedOpacity;
  36. @synthesize color = _color;
  37. @synthesize displayedColor = _displayedColor;
  38. @synthesize opacityModifyRGB = _opacityModifyRGB;
  39. @synthesize cascadeColorEnabled = _cascadeColorEnabled;
  40. @synthesize cascadeOpacityEnabled = _cascadeOpacityEnabled;
  41. - (void)dealloc
  42. {
  43. SAFE_ARC_RELEASE(_topLeft);
  44. SAFE_ARC_RELEASE(_top);
  45. SAFE_ARC_RELEASE(_topRight);
  46. SAFE_ARC_RELEASE(_left);
  47. SAFE_ARC_RELEASE(_centre);
  48. SAFE_ARC_RELEASE(_right);
  49. SAFE_ARC_RELEASE(_bottomLeft);
  50. SAFE_ARC_RELEASE(_bottom);
  51. SAFE_ARC_RELEASE(_bottomRight);
  52. SAFE_ARC_RELEASE(_scale9Image);
  53. SAFE_ARC_SUPER_DEALLOC();
  54. }
  55. #pragma mark Constructor - Initializers
  56. - (id)initWithBatchNode:(CCSpriteBatchNode *)batchnode rect:(CGRect)rect rotated:(BOOL)rotated capInsets:(CGRect)capInsets
  57. {
  58. if ((self = [super init]))
  59. {
  60. if (batchnode)
  61. {
  62. [self updateWithBatchNode:batchnode rect:rect rotated:rotated capInsets:capInsets];
  63. self.anchorPoint = ccp(0.5f, 0.5f);
  64. }
  65. _positionsAreDirty = YES;
  66. }
  67. return self;
  68. }
  69. - (id)initWithBatchNode:(CCSpriteBatchNode *)batchnode rect:(CGRect)rect capInsets:(CGRect)capInsets
  70. {
  71. return [self initWithBatchNode:batchnode rect:rect rotated:NO capInsets:capInsets];
  72. }
  73. - (id)initWithFile:(NSString *)file rect:(CGRect)rect capInsets:(CGRect)capInsets
  74. {
  75. NSAssert(file != nil, @"Invalid file for sprite");
  76. CCSpriteBatchNode *batchnode = [CCSpriteBatchNode batchNodeWithFile:file capacity:9];
  77. return [self initWithBatchNode:batchnode rect:rect capInsets:capInsets];
  78. }
  79. + (id)spriteWithFile:(NSString *)file rect:(CGRect)rect capInsets:(CGRect)capInsets
  80. {
  81. return SAFE_ARC_AUTORELEASE([[self alloc] initWithFile:file rect:rect capInsets:capInsets]);
  82. }
  83. - (id)initWithFile:(NSString *)file rect:(CGRect)rect
  84. {
  85. NSAssert(file != nil, @"Invalid file for sprite");
  86. return [self initWithFile:file rect:rect capInsets:CGRectZero];
  87. }
  88. + (id)spriteWithFile:(NSString *)file rect:(CGRect)rect
  89. {
  90. return SAFE_ARC_AUTORELEASE([[self alloc] initWithFile:file rect:rect]);
  91. }
  92. - (id)initWithFile:(NSString *)file capInsets:(CGRect)capInsets
  93. {
  94. NSAssert(file != nil, @"Invalid file for sprite");
  95. return [self initWithFile:file rect:CGRectZero capInsets:capInsets];
  96. }
  97. + (id)spriteWithFile:(NSString *)file capInsets:(CGRect)capInsets
  98. {
  99. return SAFE_ARC_AUTORELEASE([[self alloc] initWithFile:file capInsets:capInsets]);
  100. }
  101. - (id)initWithFile:(NSString *)file
  102. {
  103. NSAssert(file != nil, @"Invalid file for sprite");
  104. return [self initWithFile:file rect:CGRectZero];
  105. }
  106. + (id)spriteWithFile:(NSString *)file
  107. {
  108. return SAFE_ARC_AUTORELEASE([[self alloc] initWithFile:file]);
  109. }
  110. - (id)initWithSpriteFrame:(CCSpriteFrame *)spriteFrame capInsets:(CGRect)capInsets
  111. {
  112. NSAssert(spriteFrame != nil, @"Sprite frame must be not nil");
  113. CCSpriteBatchNode *batchnode = [CCSpriteBatchNode batchNodeWithTexture:spriteFrame.texture capacity:9];
  114. return [self initWithBatchNode:batchnode rect:spriteFrame.rect rotated:spriteFrame.rotated capInsets:capInsets];
  115. }
  116. + (id)spriteWithSpriteFrame:(CCSpriteFrame *)spriteFrame capInsets:(CGRect)capInsets
  117. {
  118. return SAFE_ARC_AUTORELEASE([[self alloc] initWithSpriteFrame:spriteFrame capInsets:capInsets]);
  119. }
  120. - (id)initWithSpriteFrame:(CCSpriteFrame *)spriteFrame
  121. {
  122. NSAssert(spriteFrame != nil, @"Invalid spriteFrame for sprite");
  123. return [self initWithSpriteFrame:spriteFrame capInsets:CGRectZero];
  124. }
  125. + (id)spriteWithSpriteFrame:(CCSpriteFrame *)spriteFrame
  126. {
  127. return SAFE_ARC_AUTORELEASE([[self alloc] initWithSpriteFrame:spriteFrame]);
  128. }
  129. - (id)initWithSpriteFrameName:(NSString *)spriteFrameName capInsets:(CGRect)capInsets
  130. {
  131. NSAssert(spriteFrameName != nil, @"Invalid spriteFrameName for sprite");
  132. CCSpriteFrame *frame = [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:spriteFrameName];
  133. return [self initWithSpriteFrame:frame capInsets:capInsets];
  134. }
  135. + (id)spriteWithSpriteFrameName:(NSString *)spriteFrameName capInsets:(CGRect)capInsets
  136. {
  137. return SAFE_ARC_AUTORELEASE([[self alloc] initWithSpriteFrameName:spriteFrameName capInsets:capInsets]);
  138. }
  139. - (id)initWithSpriteFrameName:(NSString *)spriteFrameName
  140. {
  141. NSAssert(spriteFrameName != nil, @"Invalid spriteFrameName for sprite");
  142. return [self initWithSpriteFrameName:spriteFrameName capInsets:CGRectZero];
  143. }
  144. + (id)spriteWithSpriteFrameName:(NSString *)spriteFrameName
  145. {
  146. return SAFE_ARC_AUTORELEASE([[self alloc] initWithSpriteFrameName:spriteFrameName]);
  147. }
  148. - (id)init
  149. {
  150. return [self initWithBatchNode:NULL rect:CGRectZero capInsets:CGRectZero];
  151. }
  152. - (void) updateWithBatchNode:(CCSpriteBatchNode *)batchnode rect:(CGRect)rect rotated:(BOOL)rotated capInsets:(CGRect)capInsets
  153. {
  154. GLubyte opacity = opacity;
  155. ccColor3B color = _color;
  156. // Release old sprites
  157. [self removeAllChildrenWithCleanup:YES];
  158. SAFE_ARC_RELEASE(_centre);
  159. SAFE_ARC_RELEASE(_top);
  160. SAFE_ARC_RELEASE(_topLeft);
  161. SAFE_ARC_RELEASE(_topRight);
  162. SAFE_ARC_RELEASE(_left);
  163. SAFE_ARC_RELEASE(_right);
  164. SAFE_ARC_RELEASE(_bottomLeft);
  165. SAFE_ARC_RELEASE(_bottom);
  166. SAFE_ARC_RELEASE(_bottomRight);
  167. if (_scale9Image != batchnode)
  168. {
  169. SAFE_ARC_RELEASE(_scale9Image);
  170. _scale9Image = SAFE_ARC_RETAIN(batchnode);
  171. }
  172. [_scale9Image removeAllChildrenWithCleanup:YES];
  173. _capInsets = capInsets;
  174. _spriteFrameRotated = rotated;
  175. // If there is no given rect
  176. if (CGRectEqualToRect(rect, CGRectZero))
  177. {
  178. // Get the texture size as original
  179. CGSize textureSize = [[[_scale9Image textureAtlas] texture] contentSize];
  180. rect = CGRectMake(0, 0, textureSize.width, textureSize.height);
  181. }
  182. // Set the given rect's size as original size
  183. _spriteRect = rect;
  184. _originalSize = rect.size;
  185. _preferredSize = _originalSize;
  186. _capInsetsInternal = capInsets;
  187. // Get the image edges
  188. float l = rect.origin.x;
  189. float t = rect.origin.y;
  190. float h = rect.size.height;
  191. float w = rect.size.width;
  192. // If there is no specified center region
  193. if (CGRectEqualToRect(_capInsetsInternal, CGRectZero))
  194. {
  195. // Apply the 3x3 grid format
  196. if (rotated)
  197. {
  198. _capInsetsInternal = CGRectMake(l+h/3, t+w/3, w/3, h/3);
  199. }
  200. else
  201. {
  202. _capInsetsInternal = CGRectMake(l+w/3, t+h/3, w/3, h/3);
  203. }
  204. }
  205. //
  206. // Set up the image
  207. //
  208. if (rotated)
  209. {
  210. // Sprite frame is rotated
  211. // Centre
  212. _centre = [[CCSprite alloc] initWithTexture:_scale9Image.texture rect:_capInsetsInternal rotated:YES];
  213. [_scale9Image addChild:_centre z:0 tag:pCentre];
  214. // Bottom
  215. _bottom = [[CCSprite alloc]
  216. initWithTexture:_scale9Image.texture
  217. rect:CGRectMake(l,
  218. _capInsetsInternal.origin.y,
  219. _capInsetsInternal.size.width,
  220. _capInsetsInternal.origin.x - l)
  221. rotated:rotated];
  222. [_scale9Image addChild:_bottom z:1 tag:pBottom];
  223. // Top
  224. _top = [[CCSprite alloc]
  225. initWithTexture:_scale9Image.texture
  226. rect:CGRectMake(_capInsetsInternal.origin.x + _capInsetsInternal.size.height,
  227. _capInsetsInternal.origin.y,
  228. _capInsetsInternal.size.width,
  229. h - _capInsetsInternal.size.height - (_capInsetsInternal.origin.x - l))
  230. rotated:rotated];
  231. [_scale9Image addChild:_top z:1 tag:pTop];
  232. // Right
  233. _right = [[CCSprite alloc]
  234. initWithTexture:_scale9Image.texture
  235. rect:CGRectMake(_capInsetsInternal.origin.x,
  236. _capInsetsInternal.origin.y+_capInsetsInternal.size.width,
  237. w - (_capInsetsInternal.origin.y-t)-_capInsetsInternal.size.width,
  238. _capInsetsInternal.size.height)
  239. rotated:rotated];
  240. [_scale9Image addChild:_right z:1 tag:pRight];
  241. // Left
  242. _left = [[CCSprite alloc]
  243. initWithTexture:_scale9Image.texture
  244. rect:CGRectMake(_capInsetsInternal.origin.x,
  245. t,
  246. _capInsetsInternal.origin.y - t,
  247. _capInsetsInternal.size.height)
  248. rotated:rotated];
  249. [_scale9Image addChild:_left z:1 tag:pLeft];
  250. // Top right
  251. _topRight = [[CCSprite alloc]
  252. initWithTexture:_scale9Image.texture
  253. rect:CGRectMake(_capInsetsInternal.origin.x + _capInsetsInternal.size.height,
  254. _capInsetsInternal.origin.y + _capInsetsInternal.size.width,
  255. w - (_capInsetsInternal.origin.y-t)-_capInsetsInternal.size.width,
  256. h - _capInsetsInternal.size.height - (_capInsetsInternal.origin.x - l))
  257. rotated:rotated];
  258. [_scale9Image addChild:_topRight z:2 tag:pTopRight];
  259. // Top left
  260. _topLeft = [[CCSprite alloc]
  261. initWithTexture:_scale9Image.texture
  262. rect:CGRectMake(_capInsetsInternal.origin.x + _capInsetsInternal.size.height,
  263. t,
  264. _capInsetsInternal.origin.y - t,
  265. h - _capInsetsInternal.size.height - (_capInsetsInternal.origin.x - l))
  266. rotated:rotated];
  267. [_scale9Image addChild:_topLeft z:2 tag:pTopLeft];
  268. // Bottom right
  269. _bottomRight = [[CCSprite alloc]
  270. initWithTexture:_scale9Image.texture
  271. rect:CGRectMake(l,
  272. _capInsetsInternal.origin.y + _capInsetsInternal.size.width,
  273. w - (_capInsetsInternal.origin.y-t)-_capInsetsInternal.size.width,
  274. _capInsetsInternal.origin.x - l)
  275. rotated:rotated];
  276. [_scale9Image addChild:_bottomRight z:2 tag:pBottomRight];
  277. // Bottom left
  278. _bottomLeft = [[CCSprite alloc]
  279. initWithTexture:_scale9Image.texture
  280. rect:CGRectMake(l,
  281. t,
  282. _capInsetsInternal.origin.y - t,
  283. _capInsetsInternal.origin.x - l)
  284. rotated:rotated];
  285. [_scale9Image addChild:_bottomLeft z:2 tag:pBottomLeft];
  286. }
  287. else
  288. {
  289. // Sprite frame is not rotated
  290. // Centre
  291. _centre = [[CCSprite alloc] initWithTexture:_scale9Image.texture
  292. rect:_capInsetsInternal
  293. rotated:rotated];
  294. [_scale9Image addChild:_centre z:0 tag:pCentre];
  295. // Top
  296. _top = [[CCSprite alloc]
  297. initWithTexture:_scale9Image.texture
  298. rect:CGRectMake(_capInsetsInternal.origin.x,
  299. t,
  300. _capInsetsInternal.size.width,
  301. _capInsetsInternal.origin.y - t)
  302. rotated:rotated];
  303. [_scale9Image addChild:_top z:1 tag:pTop];
  304. // Bottom
  305. _bottom = [[CCSprite alloc]
  306. initWithTexture:_scale9Image.texture
  307. rect:CGRectMake(_capInsetsInternal.origin.x,
  308. _capInsetsInternal.origin.y + _capInsetsInternal.size.height,
  309. _capInsetsInternal.size.width,
  310. h - (_capInsetsInternal.origin.y - t + _capInsetsInternal.size.height))
  311. rotated:rotated];
  312. [_scale9Image addChild:_bottom z:1 tag:pBottom];
  313. // Left
  314. _left = [[CCSprite alloc]
  315. initWithTexture:_scale9Image.texture
  316. rect:CGRectMake(l,
  317. _capInsetsInternal.origin.y,
  318. _capInsetsInternal.origin.x - l,
  319. _capInsetsInternal.size.height)
  320. rotated:rotated
  321. ];
  322. [_scale9Image addChild:_left z:1 tag:pLeft];
  323. // Right
  324. _right = [[CCSprite alloc]
  325. initWithTexture:_scale9Image.texture
  326. rect:CGRectMake(_capInsetsInternal.origin.x + _capInsetsInternal.size.width,
  327. _capInsetsInternal.origin.y,
  328. w - (_capInsetsInternal.origin.x - l + _capInsetsInternal.size.width),
  329. _capInsetsInternal.size.height)
  330. rotated:rotated];
  331. [_scale9Image addChild:_right z:1 tag:pRight];
  332. // Top left
  333. _topLeft = [[CCSprite alloc]
  334. initWithTexture:_scale9Image.texture
  335. rect:CGRectMake(l,
  336. t,
  337. _capInsetsInternal.origin.x - l,
  338. _capInsetsInternal.origin.y - t)
  339. rotated:rotated];
  340. [_scale9Image addChild:_topLeft z:2 tag:pTopLeft];
  341. // Top right
  342. _topRight = [[CCSprite alloc]
  343. initWithTexture:_scale9Image.texture
  344. rect:CGRectMake(_capInsetsInternal.origin.x + _capInsetsInternal.size.width,
  345. t,
  346. w - (_capInsetsInternal.origin.x - l + _capInsetsInternal.size.width),
  347. _capInsetsInternal.origin.y - t)
  348. rotated:rotated];
  349. [_scale9Image addChild:_topRight z:2 tag:pTopRight];
  350. // Bottom left
  351. _bottomLeft = [[CCSprite alloc]
  352. initWithTexture:_scale9Image.texture
  353. rect:CGRectMake(l,
  354. _capInsetsInternal.origin.y + _capInsetsInternal.size.height,
  355. _capInsetsInternal.origin.x - l,
  356. h - (_capInsetsInternal.origin.y - t + _capInsetsInternal.size.height))
  357. rotated:rotated];
  358. [_scale9Image addChild:_bottomLeft z:2 tag:pBottomLeft];
  359. // Bottom right
  360. _bottomRight = [[CCSprite alloc]
  361. initWithTexture:_scale9Image.texture
  362. rect:CGRectMake(_capInsetsInternal.origin.x + _capInsetsInternal.size.width,
  363. _capInsetsInternal.origin.y + _capInsetsInternal.size.height,
  364. w - (_capInsetsInternal.origin.x - l + _capInsetsInternal.size.width),
  365. h - (_capInsetsInternal.origin.y - t + _capInsetsInternal.size.height))
  366. rotated:rotated];
  367. [_scale9Image addChild:_bottomRight z:2 tag:pBottomRight];
  368. }
  369. [self setContentSize:rect.size];
  370. [self addChild:_scale9Image];
  371. if (_spritesGenerated)
  372. {
  373. // Restore color and opacity
  374. self.opacity = opacity;
  375. self.color = color;
  376. }
  377. _spritesGenerated = YES;
  378. }
  379. #pragma mark Properties
  380. - (void)setContentSize:(CGSize)size
  381. {
  382. super.contentSize = size;
  383. _positionsAreDirty = YES;
  384. }
  385. - (void)updatePosition
  386. {
  387. CGSize size = self.contentSize;
  388. float sizableWidth = size.width - _topLeft.contentSize.width - _topRight.contentSize.width;
  389. float sizableHeight = size.height - _topLeft.contentSize.height - _bottomRight.contentSize.height;
  390. float horizontalScale = sizableWidth / _centre.contentSize.width;
  391. float verticalScale = sizableHeight / _centre.contentSize.height;
  392. _centre.scaleX = horizontalScale;
  393. _centre.scaleY = verticalScale;
  394. float rescaledWidth = _centre.contentSize.width * horizontalScale;
  395. float rescaledHeight = _centre.contentSize.height * verticalScale;
  396. float leftWidth = _bottomLeft.contentSize.width;
  397. float bottomHeight = _bottomLeft.contentSize.height;
  398. // Set anchor points
  399. _bottomLeft.anchorPoint = ccp(0,0);
  400. _bottomRight.anchorPoint = ccp(0,0);
  401. _topLeft.anchorPoint = ccp(0,0);
  402. _topRight.anchorPoint = ccp(0,0);
  403. _left.anchorPoint = ccp(0,0);
  404. _right.anchorPoint = ccp(0,0);
  405. _top.anchorPoint = ccp(0,0);
  406. _bottom.anchorPoint = ccp(0,0);
  407. _centre.anchorPoint = ccp(0,0);
  408. // Position corners
  409. _bottomLeft.position = ccp(0,0);
  410. _bottomRight.position = ccp(leftWidth+rescaledWidth,0);
  411. _topLeft.position = ccp(0, bottomHeight+rescaledHeight);
  412. _topRight.position = ccp(leftWidth+rescaledWidth, bottomHeight+rescaledHeight);
  413. // Scale and position borders
  414. _left.position = ccp(0, bottomHeight);
  415. _left.scaleY = verticalScale;
  416. _right.position = ccp(leftWidth+rescaledWidth,bottomHeight);
  417. _right.scaleY = verticalScale;
  418. _bottom.position = ccp(leftWidth,0);
  419. _bottom.scaleX = horizontalScale;
  420. _top.position = ccp(leftWidth,bottomHeight+rescaledHeight);
  421. _top.scaleX = horizontalScale;
  422. // Position centre
  423. _centre.position = ccp(leftWidth, bottomHeight);
  424. }
  425. - (void)setPreferredSize:(CGSize)preferredSize
  426. {
  427. self.contentSize = preferredSize;
  428. _preferredSize = preferredSize;
  429. }
  430. #pragma mark CCRGBAProtocol
  431. - (void)setColor:(ccColor3B)color
  432. {
  433. _color = color;
  434. for (CCNode<CCRGBAProtocol> *child in _scale9Image.children)
  435. {
  436. [child setColor:color];
  437. }
  438. }
  439. - (void)setOpacity:(GLubyte)opacity
  440. {
  441. _opacity = opacity;
  442. for (CCNode<CCRGBAProtocol> *child in _scale9Image.children)
  443. {
  444. [child setOpacity:opacity];
  445. }
  446. }
  447. - (void)setOpacityModifyRGB:(BOOL)boolean
  448. {
  449. _opacityModifyRGB = boolean;
  450. for (CCNode<CCRGBAProtocol> *child in _scale9Image.children)
  451. {
  452. [child setOpacityModifyRGB:boolean];
  453. }
  454. }
  455. #if COCOS2D_VERSION >= 0x00020100
  456. - (void)updateDisplayedOpacity:(GLubyte)parentOpacity
  457. {
  458. _displayedOpacity = _realOpacity * parentOpacity/255.0;
  459. if (_cascadeOpacityEnabled)
  460. {
  461. id<CCRGBAProtocol> item;
  462. CCARRAY_FOREACH(self.children, item)
  463. {
  464. if ([item conformsToProtocol:@protocol(CCRGBAProtocol)])
  465. {
  466. [item updateDisplayedOpacity:_displayedOpacity];
  467. }
  468. }
  469. }
  470. }
  471. - (void)updateDisplayedColor:(ccColor3B)parentColor
  472. {
  473. _displayedColor.r = _realColor.r * parentColor.r/255.0;
  474. _displayedColor.g = _realColor.g * parentColor.g/255.0;
  475. _displayedColor.b = _realColor.b * parentColor.b/255.0;
  476. if (_cascadeColorEnabled) {
  477. id<CCRGBAProtocol> item;
  478. CCARRAY_FOREACH(self.children, item)
  479. {
  480. if ([item conformsToProtocol:@protocol(CCRGBAProtocol)])
  481. {
  482. [item updateDisplayedColor:_displayedColor];
  483. }
  484. }
  485. }
  486. }
  487. #endif
  488. #pragma mark Properties
  489. - (void)setSpriteFrame:(CCSpriteFrame *)spriteFrame
  490. {
  491. CCSpriteBatchNode *batchnode = [CCSpriteBatchNode batchNodeWithTexture:spriteFrame.texture capacity:9];
  492. [self updateWithBatchNode:batchnode rect:spriteFrame.rect rotated:spriteFrame.rotated capInsets:CGRectZero];
  493. // Reset insets
  494. _insetLeft = 0;
  495. _insetTop = 0;
  496. _insetRight = 0;
  497. _insetBottom = 0;
  498. }
  499. - (void)setCapInsets:(CGRect)capInsets
  500. {
  501. CGSize contentSize = self.contentSize;
  502. [self updateWithBatchNode:_scale9Image rect:_spriteRect rotated:_spriteFrameRotated capInsets:capInsets];
  503. [self setContentSize:contentSize];
  504. }
  505. - (void) updateCapInset_
  506. {
  507. CGRect insets;
  508. if (_insetLeft == 0 && _insetTop == 0 && _insetRight == 0 && _insetBottom == 0)
  509. {
  510. insets = CGRectZero;
  511. }
  512. else
  513. {
  514. if (_spriteFrameRotated)
  515. {
  516. insets = CGRectMake(_spriteRect.origin.x + _insetBottom,
  517. _spriteRect.origin.y + _insetLeft,
  518. _spriteRect.size.width - _insetRight - _insetLeft,
  519. _spriteRect.size.height - _insetTop - _insetBottom);
  520. }
  521. else
  522. {
  523. insets = CGRectMake(_spriteRect.origin.x + _insetLeft,
  524. _spriteRect.origin.y + _insetTop,
  525. _spriteRect.size.width - _insetLeft - _insetRight,
  526. _spriteRect.size.height - _insetTop - _insetBottom);
  527. }
  528. }
  529. [self setCapInsets:insets];
  530. }
  531. - (void) setInsetLeft:(float)insetLeft
  532. {
  533. _insetLeft = insetLeft;
  534. [self updateCapInset_];
  535. }
  536. - (void) setInsetTop:(float)insetTop
  537. {
  538. _insetTop = insetTop;
  539. [self updateCapInset_];
  540. }
  541. - (void) setInsetRight:(float)insetRight
  542. {
  543. _insetRight = insetRight;
  544. [self updateCapInset_];
  545. }
  546. - (void) setInsetBottom:(float)insetBottom
  547. {
  548. _insetBottom = insetBottom;
  549. [self updateCapInset_];
  550. }
  551. #pragma mark -
  552. #pragma mark CCScale9Sprite Public Methods
  553. - (CCScale9Sprite *)resizableSpriteWithCapInsets:(CGRect)capInsets
  554. {
  555. return SAFE_ARC_AUTORELEASE([[CCScale9Sprite alloc] initWithBatchNode:_scale9Image rect:_spriteRect capInsets:capInsets]);
  556. }
  557. #pragma mark -
  558. #pragma mark Overridden
  559. - (void)visit
  560. {
  561. if (_positionsAreDirty)
  562. {
  563. [self updatePosition];
  564. _positionsAreDirty = NO;
  565. }
  566. [super visit];
  567. }
  568. @end