CCScale9Sprite: Added support for insets by floats and CCRect. Fixed bug for positioning for uneven insets. Changing texture no longer affects the anchor point. Made it possible to set the SpriteFrame. (Changes according to https://github.com/YannickL/CCControlExtension/commits/gles20: d00c4f90ab53d5295bce03123ddbccc4fa0acf58, ed56cb1558c755748437d152f2f7a4bb5a1455ba, c4bbcb9beb2febfb4b55323709e30082af902c90, 5da062de92d39d91b014f87809fc30ba501538fc)

This commit is contained in:
Nicolas Gramlich 2012-05-31 11:47:16 -07:00
parent b7130c3d63
commit fe9fb347aa
2 changed files with 228 additions and 66 deletions

View File

@ -25,12 +25,50 @@ CCScale9Sprite::~CCScale9Sprite()
}
bool CCScale9Sprite::init()
{
return this->initWithBatchNode(NULL, CCRectZero, CCRectZero);
}
bool CCScale9Sprite::initWithBatchNode(CCSpriteBatchNode* batchnode, CCRect rect, CCRect capInsets)
{
if(batchnode)
{
this->updateWithBatchNode(batchnode, rect, capInsets);
this->setAnchorPoint(ccp(0.5f,0.5f));
}
this->m_positionsAreDirty = true;
CCAssert(batchnode != NULL, "The batchnode must be not nil.");
return this;
}
scale9Image = batchnode;
bool CCScale9Sprite::updateWithBatchNode(CCSpriteBatchNode* batchnode, CCRect rect, CCRect capInsets)
{
// Release old sprites
this->removeAllChildrenWithCleanup(true);
if(this->topLeft)
{
CC_SAFE_RELEASE(this->topLeft);
CC_SAFE_RELEASE(this->top);
CC_SAFE_RELEASE(this->topRight);
CC_SAFE_RELEASE(this->left);
CC_SAFE_RELEASE(this->centre);
CC_SAFE_RELEASE(this->right);
CC_SAFE_RELEASE(this->bottomLeft);
CC_SAFE_RELEASE(this->bottom);
CC_SAFE_RELEASE(this->bottomRight);
}
if(this->scale9Image != batchnode)
{
CC_SAFE_RELEASE(this->scale9Image);
scale9Image = batchnode; // TODO No retain on purpose?
}
scale9Image->removeAllChildrenWithCleanup(true);
m_capInsets = capInsets;
// If there is no given rect
if ( CCRect::CCRectEqualToRect(rect, CCRectZero) )
@ -45,14 +83,14 @@ bool CCScale9Sprite::initWithBatchNode(CCSpriteBatchNode* batchnode, CCRect rect
m_spriteRect = rect;
m_originalSize = rect.size;
m_preferredSize = m_originalSize;
m_capInsets = capInsets;
m_capInsetsInternal = capInsets;
this->setAnchorPoint(ccp(0.5f, 0.5f));
// If there is no specified center region
if ( CCRect::CCRectEqualToRect(m_capInsets, CCRectZero) )
if ( CCRect::CCRectEqualToRect(m_capInsetsInternal, CCRectZero) )
{
// Apply the 3x3 grid format
m_capInsets = CCRectMake(
m_capInsetsInternal = CCRectMake(
rect.origin.x + m_originalSize.width / 3,
rect.origin.y + m_originalSize.height / 3,
m_originalSize.width / 3,
@ -70,71 +108,71 @@ bool CCScale9Sprite::initWithBatchNode(CCSpriteBatchNode* batchnode, CCRect rect
//
// Centre
centre = CCSprite::spriteWithTexture(scale9Image->getTexture(), m_capInsets);
centre = CCSprite::spriteWithTexture(scale9Image->getTexture(), m_capInsetsInternal);
scale9Image->addChild(centre ,0 ,pCentre);
// Top
top = CCSprite::spriteWithTexture(scale9Image->getTexture(), CCRectMake(m_capInsets.origin.x,
top = CCSprite::spriteWithTexture(scale9Image->getTexture(), CCRectMake(m_capInsetsInternal.origin.x,
t,
m_capInsets.size.width,
m_capInsets.origin.y - t));
m_capInsetsInternal.size.width,
m_capInsetsInternal.origin.y - t));
scale9Image->addChild(top, 1, pTop);
// Bottom
bottom = CCSprite::spriteWithTexture(scale9Image->getTexture(), CCRectMake( m_capInsets.origin.x,
m_capInsets.origin.y + m_capInsets.size.height,
m_capInsets.size.width,
h - (m_capInsets.origin.y - t + m_capInsets.size.height) ));
bottom = CCSprite::spriteWithTexture(scale9Image->getTexture(), CCRectMake( m_capInsetsInternal.origin.x,
m_capInsetsInternal.origin.y + m_capInsetsInternal.size.height,
m_capInsetsInternal.size.width,
h - (m_capInsetsInternal.origin.y - t + m_capInsetsInternal.size.height) ));
scale9Image->addChild(bottom, 1, pBottom);
// Left
left = CCSprite::spriteWithTexture(scale9Image->getTexture(), CCRectMake(
l,
m_capInsets.origin.y,
m_capInsets.origin.x - l,
m_capInsets.size.height) );
m_capInsetsInternal.origin.y,
m_capInsetsInternal.origin.x - l,
m_capInsetsInternal.size.height) );
scale9Image->addChild(left, 1, pLeft);
// Right
right = CCSprite::spriteWithTexture(scale9Image->getTexture(), CCRectMake(
m_capInsets.origin.x + m_capInsets.size.width,
m_capInsets.origin.y,
w - (m_capInsets.origin.x - l + m_capInsets.size.width),
m_capInsets.size.height));
m_capInsetsInternal.origin.x + m_capInsetsInternal.size.width,
m_capInsetsInternal.origin.y,
w - (m_capInsetsInternal.origin.x - l + m_capInsetsInternal.size.width),
m_capInsetsInternal.size.height));
scale9Image->addChild(right, 1, pRight);
// Top left
topLeft = CCSprite::spriteWithTexture(scale9Image->getTexture(), CCRectMake(
l,
t,
m_capInsets.origin.x - l,
m_capInsets.origin.y - t));
m_capInsetsInternal.origin.x - l,
m_capInsetsInternal.origin.y - t));
scale9Image->addChild(topLeft, 2, pTopLeft);
// Top right
topRight = CCSprite::spriteWithTexture(scale9Image->getTexture(), CCRectMake(
m_capInsets.origin.x + m_capInsets.size.width,
m_capInsetsInternal.origin.x + m_capInsetsInternal.size.width,
t,
w - (m_capInsets.origin.x - l + m_capInsets.size.width),
m_capInsets.origin.y - t));
w - (m_capInsetsInternal.origin.x - l + m_capInsetsInternal.size.width),
m_capInsetsInternal.origin.y - t));
scale9Image->addChild(topRight, 2, pTopRight);
// Bottom left
bottomLeft = CCSprite::spriteWithTexture(scale9Image->getTexture(), CCRectMake(
l,
m_capInsets.origin.y + m_capInsets.size.height,
m_capInsets.origin.x - l,
h - (m_capInsets.origin.y - t + m_capInsets.size.height)) );
m_capInsetsInternal.origin.y + m_capInsetsInternal.size.height,
m_capInsetsInternal.origin.x - l,
h - (m_capInsetsInternal.origin.y - t + m_capInsetsInternal.size.height)) );
scale9Image->addChild(bottomLeft, 2, pBottomLeft);
// Bottom right
bottomRight = CCSprite::spriteWithTexture(scale9Image->getTexture(), CCRectMake(
m_capInsets.origin.x + m_capInsets.size.width,
m_capInsets.origin.y + m_capInsets.size.height,
w - (m_capInsets.origin.x - l + m_capInsets.size.width),
h - (m_capInsets.origin.y - t + m_capInsets.size.height)) );
m_capInsetsInternal.origin.x + m_capInsetsInternal.size.width,
m_capInsetsInternal.origin.y + m_capInsetsInternal.size.height,
w - (m_capInsetsInternal.origin.x - l + m_capInsetsInternal.size.width),
h - (m_capInsetsInternal.origin.y - t + m_capInsetsInternal.size.height)) );
scale9Image->addChild(bottomRight, 2, pBottomRight);
@ -146,9 +184,13 @@ bool CCScale9Sprite::initWithBatchNode(CCSpriteBatchNode* batchnode, CCRect rect
void CCScale9Sprite::setContentSize(const CCSize &size)
{
CCNode::setContentSize(size);
setAnchorPoint(ccp(0.5f,0.5f));
this->m_positionsAreDirty = true;
}
void CCScale9Sprite::updatePositions()
{
CCSize size = this->m_tContentSize;
CCLOG("scale9 set content size %0.2f %0.2f",size.width,size.height);
CCLOG("leftCap %0.2f rightCap %0.2f",topLeft->getContentSize().width,topRight->getContentSize().width);
@ -162,25 +204,37 @@ void CCScale9Sprite::setContentSize(const CCSize &size)
float rescaledWidth = centre->getContentSize().width * horizontalScale;
float rescaledHeight = centre->getContentSize().height * verticalScale;
float despx = size.width*0.5f;
float despy = size.height*0.5f;
float leftWidth = bottomLeft->getContentSize().width;
float bottomHeight = bottomLeft->getContentSize().height;
//Position corners
topLeft->setPosition(ccp(-rescaledWidth/2 - topLeft->getContentSize().width/2 +despx, rescaledHeight/2 + topLeft->getContentSize().height*0.5f +despy) );
topRight->setPosition(ccp(rescaledWidth/2 + topRight->getContentSize().width/2 +despx, rescaledHeight/2 + topRight->getContentSize().height*0.5f +despy));
bottomLeft->setPosition(ccp(-rescaledWidth/2 - bottomLeft->getContentSize().width/2 +despx, -rescaledHeight/2 - bottomLeft->getContentSize().height*0.5f +despy));
bottomRight->setPosition(ccp(rescaledWidth/2 + bottomRight->getContentSize().width/2 +despx, -rescaledHeight/2 + -bottomRight->getContentSize().height*0.5f +despy));
bottomLeft->setAnchorPoint(ccp(0,0));
bottomRight->setAnchorPoint(ccp(0,0));
topLeft->setAnchorPoint(ccp(0,0));
topRight->setAnchorPoint(ccp(0,0));
left->setAnchorPoint(ccp(0,0));
right->setAnchorPoint(ccp(0,0));
top->setAnchorPoint(ccp(0,0));
bottom->setAnchorPoint(ccp(0,0));
centre->setAnchorPoint(ccp(0,0));
// Position corners
bottomLeft->setPosition(ccp(0,0));
bottomRight->setPosition(ccp(leftWidth+rescaledWidth,0));
topLeft->setPosition(ccp(0, bottomHeight+rescaledHeight));
topRight->setPosition(ccp(leftWidth+rescaledWidth, bottomHeight+rescaledHeight));
// Scale and position borders
left->setPosition(ccp(0, bottomHeight));
left->setScaleY(verticalScale);
right->setPosition(ccp(leftWidth+rescaledWidth,bottomHeight));
right->setScaleY(verticalScale);
bottom->setPosition(ccp(leftWidth,0));
bottom->setScaleX(horizontalScale);
top->setPosition(ccp(leftWidth,bottomHeight+rescaledHeight));
top->setScaleX(horizontalScale);
top->setPosition(ccp(0+despx,rescaledHeight/2 + topLeft->getContentSize().height*0.5f +despy));
bottom->setScaleX (horizontalScale);
bottom->setPosition(ccp(0+despx,-rescaledHeight/2 - bottomLeft->getContentSize().height*0.5f +despy));
left->setScaleY (verticalScale);
left->setPosition(ccp(-rescaledWidth/2 - topLeft->getContentSize().width/2 +despx, 0+despy));
right->setScaleY (verticalScale);
right->setPosition(ccp(rescaledWidth/2 + topRight->getContentSize().width/2 +despx, 0+despy));
centre->setPosition(ccp(despx, despy));
// Position centre
centre->setPosition(ccp(leftWidth, bottomHeight));
CCLOG("Scale9 setContentSize %02.f x %02.f <%0.2f x %0.2f>",sizableWidth,sizableHeight,horizontalScale,verticalScale);
}
@ -317,7 +371,6 @@ CCScale9Sprite* CCScale9Sprite::spriteWithSpriteFrameName(const char* spriteFram
}
CC_SAFE_DELETE(pReturn);
return NULL;
}
bool CCScale9Sprite::initWithSpriteFrameName(const char* spriteFrameName)
@ -420,10 +473,22 @@ GLubyte CCScale9Sprite::getOpacity()
return m_cOpacity;
}
void CCScale9Sprite::setPreferredSize(CCSize preferedSize)
{
this->setContentSize(preferedSize);
this->m_preferredSize = preferedSize;
}
CCSize CCScale9Sprite::getPreferredSize()
{
return this->m_preferredSize;
}
void CCScale9Sprite::setCapInsets(CCRect capInsets)
{
m_capInsets = capInsets;
CCSize contentSize = this->m_tContentSize;
this->updateWithBatchNode(this->scale9Image, this->m_spriteRect, capInsets);
this->setContentSize(contentSize);
}
CCRect CCScale9Sprite::getCapInsets()
@ -431,6 +496,23 @@ CCRect CCScale9Sprite::getCapInsets()
return m_capInsets;
}
void CCScale9Sprite::updateCapInset()
{
CCRect insets;
if (this->m_insetLeft == 0 && this->m_insetTop == 0 && this->m_insetRight == 0 && this->m_insetBottom == 0)
{
insets = CCRectZero;
}
else
{
insets = CCRectMake(this->m_insetLeft,
this->m_insetTop,
this->m_spriteRect.size.width-this->m_insetLeft-this->m_insetRight,
this->m_spriteRect.size.height-this->m_insetTop-this->m_insetBottom);
}
this->setCapInsets(insets);
}
void CCScale9Sprite::setIsOpacityModifyRGB(bool var)
{
m_bIsOpacityModifyRGB = var;
@ -461,4 +543,70 @@ bool CCScale9Sprite::getIsOpacityModifyRGB()
return m_bIsOpacityModifyRGB;
}
void CCScale9Sprite::setSpriteFrame(CCSpriteFrame * spriteFrame)
{
CCSpriteBatchNode * batchnode = CCSpriteBatchNode::batchNodeWithTexture(spriteFrame->getTexture(), 9);
this->updateWithBatchNode(batchnode, spriteFrame->getRect(), CCRectZero);
// Reset insets
this->m_insetLeft = 0;
this->m_insetTop = 0;
this->m_insetRight = 0;
this->m_insetBottom = 0;
}
float CCScale9Sprite::getInsetLeft()
{
return this->m_insetLeft;
}
float CCScale9Sprite::getInsetTop()
{
return this->m_insetTop;
}
float CCScale9Sprite::getInsetRight()
{
return this->m_insetRight;
}
float CCScale9Sprite::getInsetBottom()
{
return this->m_insetBottom;
}
void CCScale9Sprite::setInsetLeft(float insetLeft)
{
this->m_insetLeft = insetLeft;
this->updateCapInset();
}
void CCScale9Sprite::setInsetTop(float insetTop)
{
this->m_insetTop = insetTop;
this->updateCapInset();
}
void CCScale9Sprite::setInsetRight(float insetRight)
{
this->m_insetRight = insetRight;
this->updateCapInset();
}
void CCScale9Sprite::setInsetBottom(float insetBottom)
{
this->m_insetBottom = insetBottom;
this->updateCapInset();
}
void CCScale9Sprite::visit()
{
if(this->m_positionsAreDirty)
{
this->updatePositions();
this->m_positionsAreDirty = false;
}
CCNode::visit();
}
NS_CC_EXT_END

View File

@ -44,7 +44,7 @@ public:
/** Prefered sprite's size. By default the prefered size is the original size. */
//if the preferredSize component is given as -1, it is ignored
CC_SYNTHESIZE(CCSize, m_preferredSize, PreferredSize);
CC_PROPERTY(CCSize, m_preferredSize, PreferredSize);
/**
* The end-cap insets.
* On a non-resizeable sprite, this property is set to CGRectZero; the sprite
@ -56,10 +56,15 @@ public:
/** Color: conforms to CCRGBAProtocol protocol */
CC_PROPERTY_PASS_BY_REF(ccColor3B, m_tColor, Color)
CC_PROPERTY(CCRect, m_capInsets, CapInsets);
CC_PROPERTY(float, m_insetLeft, InsetLeft);
CC_PROPERTY(float, m_insetTop, InsetTop);
CC_PROPERTY(float, m_insetRight, InsetRight);
CC_PROPERTY(float, m_insetBottom, InsetBottom);
protected:
CCRect m_spriteRect;
CCRect m_capInsetsInternal;
bool m_positionsAreDirty;
CCSpriteBatchNode* scale9Image;
CCSprite* topLeft;
@ -76,9 +81,15 @@ protected:
ccColor3B m_sColorUnmodified;
bool m_bIsOpacityModifyRGB;
void updateCapInset();
void updatePositions();
public:
void virtual setContentSize(const CCSize &size);
virtual void setContentSize(const CCSize &size);
virtual void visit();
virtual bool init();
virtual bool initWithBatchNode(CCSpriteBatchNode* batchnode, CCRect rect, CCRect capInsets);
/**
@ -274,6 +285,9 @@ public:
*/
virtual bool getIsOpacityModifyRGB(void);
virtual bool updateWithBatchNode(CCSpriteBatchNode* batchnode, CCRect rect, CCRect capInsets);
virtual void setSpriteFrame(CCSpriteFrame * spriteFrame);
};
NS_CC_EXT_END