标签页是经常用到的控件,但是cocos2d-x并没有提供实现,我在cocos2d-x extension GUI的基础上实现了一份。
约束条件:
1. 整个TabControl的大小和背景的图片大小一样。
2. 标签不考虑超过TabControl大小的叠加情况,目前只提供三个控制参数(marginLeft, marginTop, space)。
3. Tab使用CCControlButton实现,点击后状态变为selected, 但是目前CCControlButton的selecte有点问题,所以稍微改了一下,后续会附上改动代码。
4. 需要设置Tab控制的显示区域的大小和位置,默认大小为0,默认位置为(0,0), 通常情况只用设置大小就可以了。
CCTabControl.h 代码
/***********************************************************
Write by wanghong.li
Any question please contacted [email protected]
************************************************************/
#ifndef __CCTABCONTROL_H__
#define __CCTABCONTROL_H__
#include "cocos2d.h"
#include "ExtensionMacros.h"
#include "CCControl.h"
NS_CC_EXT_BEGIN
class CCTabControl:public CCLayer
{
public:
CCTabControl();
virtual ~CCTabControl();
static CCTabControl* create(constchar* tabNormalImageFile,
const char* tabSelectedImageFile,
const char* fontName,
int fontSize,
const char* bgImage);
static CCTabControl* create(CCSpriteFrame* tabNormalFrame,
CCSpriteFrame* tabSelectedFrame,
const char* fontName,
int fontsize,
CCSpriteFrame* bgFrame);
bool initWithImageFile(constchar* tabNormalImageFile,
const char* tabSelectedImageFile,
const char* fontName,
int fontsize,
const char* bgImage);
bool initWithSpriteFrame(CCSpriteFrame* tabNormalFrame,
CCSpriteFrame* tabSelectedFrame,
const char* fontName,
int fontsize,
CCSpriteFrame* bgFrame);
void setTabMargin(float marginLeft,float marginTop);
CCNode* getContainer()
{
returnm_container;
}
CCSize getContainerContentSize()
{
return m_container->getContentSize();
}
void setContainerContentSize(constCCSize& size)
{
m_container->setContentSize(size);
}
CCPoint getContainerPosition()
{
return m_container->getPosition();
}
void setContainerPosition(constCCPoint& pos)
{
m_container->setPosition(pos);
}
unsigned int getTabCount()
{
return m_tabs->count();
}
bool addTab(constchar* label, CCNode* tabView);
bool switchToTab(int index);
public:
CC_PROPERTY(float, m_marginLeft, MarginLeft);
CC_PROPERTY(float, m_marginTop, MarginTop);
CC_PROPERTY(float, m_tabSpace, TabSpace);
protected:
void onTabControlEvent(CCObject* object,CCControlEvent event);
void refreshTabX();
void refreshTabY();
protected:
CCArray* m_tabs;
CCLayer* m_container;
CCSprite* m_bgSprite;
CCSpriteFrame* m_tabNormalFrame;
CCSpriteFrame* m_tabSelectedFrame;
std::string m_fontName;
int m_fontSize;
int m_currentTabIndex;
};
NS_CC_EXT_END
#endif /* __CCTABCONTROL_H__ */
CCTabControl.cpp代码
/***********************************************************
Write by wanghong.li
Any question please contacted [email protected]
************************************************************/
#include "CCTabControl.h"
#include "CCControlButton.h"
NS_CC_EXT_BEGIN
class CCTabControlItem:public CCObject
{
public:
CCTabControlItem():
m_tabButton(NULL),
m_tabView(NULL)
{
}
virtual ~CCTabControlItem()
{
CC_SAFE_RELEASE(m_tabButton);
CC_SAFE_RELEASE(m_tabView);
}
static CCTabControlItem* create(CCControlButton* tabButton,CCNode* tabView)
{
CCTabControlItem* item =new CCTabControlItem();
if (item && item->init(tabButton, tabView))
{
item->autorelease();
return item;
}
CC_SAFE_DELETE(item);
return NULL;
}
bool init(CCControlButton* tabButton,CCNode* tabView)
{
setTabButton(tabButton);
setTabView(tabView);
return true;
}
CCControlButton* getTabButton()
{
returnm_tabButton;
}
void setTabButton(CCControlButton* tabButton)
{
CC_SAFE_RELEASE_NULL(m_tabButton);
m_tabButton = tabButton;
m_tabButton->retain();
}
CCNode* getTabView()
{
return m_tabView;
}
void setTabView(CCNode* tabView)
{
CC_SAFE_RELEASE_NULL(m_tabView);
m_tabView = tabView;
m_tabView->retain();
}
protected:
CCControlButton* m_tabButton;
CCNode* m_tabView;
};
CCTabControl*CCTabControl::create(constchar* tabNormalImageFile,
const char* tabSelectedImageFile,
const char* fontName,
int fontSize,
const char* bgImage)
{
CCTabControl* tabControl =new CCTabControl();
if (tabControl && tabControl->initWithImageFile(tabNormalImageFile,
tabSelectedImageFile,
fontName,
fontSize,
bgImage))
{
tabControl->autorelease();
return tabControl;
}
CC_SAFE_RELEASE(tabControl);
return NULL;
}
CCTabControl* CCTabControl::create(CCSpriteFrame* tabNormalFrame,
CCSpriteFrame* tabSelectedFrame,
const char* fontName,
int fontsize,
CCSpriteFrame* bgFrame)
{
CCTabControl* tabControl =new CCTabControl();
if (tabControl && tabControl->initWithSpriteFrame(tabNormalFrame,
tabSelectedFrame,
fontName,
fontsize,
bgFrame))
{
tabControl->autorelease();
return tabControl;
}
CC_SAFE_RELEASE(tabControl);
return NULL;
}
CCTabControl::CCTabControl():
m_tabs(NULL),
m_container(NULL),
m_bgSprite(NULL),
m_tabNormalFrame(NULL),
m_tabSelectedFrame(NULL),
m_fontSize(0),
m_currentTabIndex(0),
m_marginLeft(16),
m_marginTop(16),
m_tabSpace(20)
{
}
CCTabControl::~CCTabControl()
{
CC_SAFE_RELEASE(m_tabs);
CC_SAFE_RELEASE(m_container);
CC_SAFE_RELEASE(m_bgSprite);
CC_SAFE_RELEASE(m_tabNormalFrame);
CC_SAFE_RELEASE(m_tabSelectedFrame);
}
boolCCTabControl::initWithImageFile(constchar* tabNormalImageFile,
const char* tabSelectedImageFile,
const char* fontName,
int fontsize,
const char* bgImage)
{
CCTexture2D* texture = CCTextureCache::sharedTextureCache()->addImage(tabNormalImageFile);
if (!texture)
{
return false;
}
CCSize textureSize = texture->getContentSize();
CCRect textureRect(0,0, textureSize.width, textureSize.height);
CCSpriteFrame* tabNormalFrame = CCSpriteFrame::create(tabNormalImageFile, textureRect);
CCSpriteFrame* tabSelectedFrame = CCSpriteFrame::create(tabSelectedImageFile, textureRect);
CCTexture2D* bgTexture = CCTextureCache::sharedTextureCache()->addImage(bgImage);
if (!bgTexture)
{
return false;
}
CCSize bgSize = bgTexture->getContentSize();
CCRect bgRect(0,0, bgSize.width, bgSize.height);
CCSpriteFrame* bgFrame = CCSpriteFrame::create(bgImage, bgRect);
return initWithSpriteFrame(tabNormalFrame,
tabSelectedFrame,
fontName,
fontsize,
bgFrame);
}
boolCCTabControl::initWithSpriteFrame(CCSpriteFrame* tabNormalFrame,
CCSpriteFrame* tabSelectedFrame,
const char* fontName,
int fontsize,
CCSpriteFrame* bgFrame)
{
m_tabNormalFrame = tabNormalFrame;
if (!m_tabNormalFrame)
{
return false;
}
m_tabNormalFrame->retain();
m_tabSelectedFrame = tabSelectedFrame;
if (!m_tabSelectedFrame)
{
return false;
}
m_tabSelectedFrame->retain();
m_fontName = fontName;
m_fontSize = fontsize;
m_bgSprite =CCSprite::createWithSpriteFrame(bgFrame);
if (!m_bgSprite)
{
return false;
}
m_bgSprite->retain();
CCSize bgSize = m_bgSprite->getContentSize();
setContentSize(m_bgSprite->getContentSize());
setAnchorPoint(CCPointZero);
m_bgSprite->CCNode::setPosition(bgSize.width /2.0f, bgSize.height /2.0f);
addChild(m_bgSprite);
m_container = CCLayer::create();
if (!m_container)
{
return false;
}
m_container->retain();
m_container->setAnchorPoint(CCPointZero);
addChild(m_container);
m_tabs =CCArray::createWithCapacity(2);
if (!m_tabs)
{
return false;
}
m_tabs->retain();
return true;
}
voidCCTabControl::setTabMargin(float marginLeft,float marginTop)
{
setMarginLeft(marginLeft);
setMarginTop(marginTop);
}
boolCCTabControl::addTab(constchar* label, CCNode* tabView)
{
CCScale9Sprite* normalSprite =CCScale9Sprite::createWithSpriteFrame(m_tabNormalFrame);
if (!normalSprite)
{
return false;
}
CCLabelTTF* labelTTF =CCLabelTTF::create(label,m_fontName.c_str(),m_fontSize);
CCControlButton* controlButton = CCControlButton::create(labelTTF, normalSprite);
if (!controlButton)
{
return false;
}
CCRect ctrlBtnRect = m_tabNormalFrame->getRect();
controlButton->setPreferredSize(ctrlBtnRect.size);
CCScale9Sprite* selectedSprite =CCScale9Sprite::createWithSpriteFrame(m_tabSelectedFrame);
controlButton->setBackgroundSpriteForState(selectedSprite,CCControlStateSelected);
CCScale9Sprite* highLightedSprite =CCScale9Sprite::createWithSpriteFrame(m_tabSelectedFrame);
controlButton->setBackgroundSpriteForState(highLightedSprite,CCControlStateHighlighted);
controlButton->setZoomOnTouchDown(false);
CCTabControlItem* controlItem = CCTabControlItem::create(controlButton, tabView);
if (!controlItem)
{
return false;
}
int index = m_tabs->count();
if (0 == index)
{
tabView->setVisible(true);
controlButton->setSelected(true);
}
else
{
tabView->setVisible(false);
}
m_tabs->addObject(controlItem);
controlButton->setTag(index);
controlButton->addTargetWithActionForControlEvents(this,
cccontrol_selector(CCTabControl::onTabControlEvent),
CCControlEventTouchDown |
CCControlEventTouchUpOutside |
CCControlEventTouchUpInside);
CCSize containerSize = m_container->getContentSize();
tabView->setPosition(containerSize.width /2.0f, containerSize.height /2.0f);
addChild(controlButton);
m_container->addChild(tabView);
refreshTabX();
refreshTabY();
return true;
}
boolCCTabControl::switchToTab(int index)
{
if (index >= m_tabs->count())
{
return false;
}
CCTabControlItem* newItem =dynamic_cast<CCTabControlItem*>(m_tabs->objectAtIndex(index));
if (!newItem)
{
return false;
}
if (m_currentTabIndex == index)
{
return true;
}
newItem->getTabView()->setVisible(true);
CCTabControlItem* item =dynamic_cast<CCTabControlItem*>(m_tabs->objectAtIndex(m_currentTabIndex));
if (!item)
{
return false;
}
item->getTabButton()->setSelected(false);
item->getTabView()->setVisible(false);
m_currentTabIndex = index;
return true;
}
voidCCTabControl::onTabControlEvent(CCObject* object,CCControlEvent event)
{
if (event ==CCControlEventTouchDown)
{
CCControlButton* controlButton = dynamic_cast<CCControlButton*>(object);
int index = controlButton->getTag();
switchToTab(index);
}
elseif (event ==CCControlEventTouchUpOutside ||
event == CCControlEventTouchUpInside)
{
CCControlButton* controlButton = dynamic_cast<CCControlButton*>(object);
controlButton->setSelected(true);
}
}
floatCCTabControl::getMarginLeft()
{
returnm_marginLeft;
}
voidCCTabControl::setMarginLeft(float marginLeft)
{
m_marginLeft = marginLeft;
refreshTabX();
}
floatCCTabControl::getMarginTop()
{
returnm_marginTop;
}
voidCCTabControl::setMarginTop(float marginTop)
{
m_marginTop = marginTop;
refreshTabY();
}
floatCCTabControl::getTabSpace()
{
returnm_tabSpace;
refreshTabX();
}
voidCCTabControl::setTabSpace(float tabSpace)
{
m_tabSpace = tabSpace;
}
voidCCTabControl::refreshTabX()
{
CCSize frameSize =m_tabNormalFrame->getRect().size;
for (int i =0; i < m_tabs->count(); i++)
{
CCTabControlItem* controlItem =dynamic_cast<CCTabControlItem*>(m_tabs->objectAtIndex(i));
float xPosition = m_marginLeft + m_tabSpace * i + (i + 0.5f) * frameSize.width;
controlItem->getTabButton()->setPositionX(xPosition);
}
}
voidCCTabControl::refreshTabY()
{
CCSize size = getContentSize();
CCSize frameSize =m_tabNormalFrame->getRect().size;
float yPosition = size.height - frameSize.height /2 - m_marginTop;
for (int i =0; i < m_tabs->count(); i++)
{
CCTabControlItem* controlItem =dynamic_cast<CCTabControlItem*>(m_tabs->objectAtIndex(i));
controlItem->getTabButton()->setPositionY(yPosition);
}
}
NS_CC_EXT_END
CCControlButton.cpp修改:
voidCCControlButton::setSelected(bool enabled)
{
/* Add by wanghong.li to set seleceted state*/
if (enabled == true)
{
m_eState =CCControlStateSelected;
}
else
{
m_eState =CCControlStateNormal;
}
CCControl::setSelected(enabled);
needsLayout();
}
实例代码:
CCLayer::init();
CCTabControl* tabCtrl =CCTabControl::create("Resources/ccbResources/clubManager/tabNormal.png",
"Resources/ccbResources/clubManager/tabSelected.png",
"Helvetica",
12,
"Resources/ccbResources/clubManager/tabBg.png");
CCSize containerSize = CCSizeMake(480.0f, 240.0f);
tabCtrl->setContainerContentSize(containerSize);
tabCtrl->setContainerPosition(ccp(0.0f,20.0f));
tabCtrl->setTabMargin(40.0f,8.0f);
CCSprite* sprite1 =CCSprite::create("Resources/ccbResources/clubManager/tabNormal.png");
CCSprite* sprite2 =CCSprite::create("Resources/ccbResources/clubManager/tabSelected.png");
tabCtrl->addTab("Tab1", sprite1);
tabCtrl->addTab("Tab2", sprite2);
addChild(tabCtrl);