Cocos2dx标签页(TabControl/TabView)的简单实现

标签页是经常用到的控件,但是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);


PS:加了Lua的PKG文件,有需要的可以联系


你可能感兴趣的:(Cocos2dx标签页(TabControl/TabView)的简单实现)