cocos2dx Tab选项卡控件的实现

时间:2022-05-17 20:00:43

选项卡控件在游戏和应用中很是常见,但是cocostudio里并没有实现好的选项卡控件,于是自己封装了 一个,效果如下:

cocos2dx Tab选项卡控件的实现

代码:

TabUiControl.h

 #pragma once

 //std
#include <string> //cocos
#include "cocos2d.h"
#include "cocostudio/CocoStudio.h"
#include "ui/CocosGUI.h" using namespace std; USING_NS_CC;
using namespace cocos2d::ui;
using namespace cocostudio;
using namespace cocostudio::timeline; typedef std::function<void(int)> OnTabActioveCallback; //tab控件数据
struct STabBtnData
{
STabBtnData()
{
_pTabBtn = nullptr;
_pBtnTxt = nullptr;
_pContentNode = nullptr;
}
ui::Button *_pTabBtn; //按钮
Text * _pBtnTxt; //按钮文字
Node *_pContentNode; //对应的内容node指针
}; //选项卡控件
class TabUiControl
{
public:
TabUiControl();
virtual ~TabUiControl();
//初始化tab
bool InitTab(Node *pRootNode, int tabCount, bool bHaveContenNode = true,const char *pTabBtnName = "tabBtn", const char *pTabTxtName = "btnTxt", const char *pContentName = "tabContent");
//tab单击事件
void OnTabClick(Ref *pSender);
//激活tab
void ActiveTab(int index);
//设置激活颜色
void SetActiveTxtColor(const Color4B &color){ _activeTxtColor = color; }
//设置未激活颜色
void SetUnActiveTxtColor(const Color4B &color){ _unActiveTxtColor = color; }
//设置选中回调
void SetActiveCallback(OnTabActioveCallback call){ _onActiveCallback = call; }
private:
//初始化静态数据
static void InitDefData();
protected:
static const int MaxTabCount=; //最大tab数量
static int TabValue[MaxTabCount]; //tab 值
int _tabCount; //tab数量
int _tabMaxZorder; //tabMaxZorder
STabBtnData *_pTabBtnData; //tab 数据
Color4B _activeTxtColor; //激活tabBtn文字颜色
Color4B _unActiveTxtColor; //未激活tabBtn文字颜色
OnTabActioveCallback _onActiveCallback; //tab被激活回调
bool _bHaveContenNode; //tab是否有对应的内容节点
private:
};

TabUiControl.cpp

 #include "TabUiControl.h"

 int TabUiControl::TabValue[MaxTabCount];

 TabUiControl::TabUiControl()
:_activeTxtColor(, , , ), _unActiveTxtColor(, , , )
{
InitDefData(); _tabMaxZorder = ;
_tabCount = ;
_pTabBtnData = nullptr;
_onActiveCallback = nullptr;
_bHaveContenNode = false; } TabUiControl::~TabUiControl()
{ CC_SAFE_DELETE_ARRAY(_pTabBtnData);
}
void TabUiControl::InitDefData()
{
static bool BInitOk = false;
if (!BInitOk)
{
for (int i = ; i < MaxTabCount; i++)
{
TabValue[i] = i;
} BInitOk = true;
} } bool TabUiControl::InitTab(Node *pRootNode, int tabCount, bool bHaveContenNode, const char *pTabBtnName, const char *pTabTxtName, const char *pContentName)
{
bool ret = false;
do
{
CC_BREAK_IF(!pTabBtnName || !pTabTxtName || !pRootNode || !pContentName);
CC_BREAK_IF(tabCount > MaxTabCount || tabCount <= ); //分配tab 数据
_pTabBtnData = new STabBtnData[tabCount];
_tabCount = tabCount;
_bHaveContenNode = bHaveContenNode; //临时变量
ui::Button *pTempBtn = nullptr;
Text *pTempTxt = nullptr;
Node *pNode = nullptr;
char tc[] = { };
int i = ;
Widget::ccWidgetClickCallback callback = CC_CALLBACK_1(TabUiControl::OnTabClick, this); for (i = ; i < tabCount; i++)
{
//内容节点指针
if (bHaveContenNode)
{
sprintf(tc, "%s%d", pContentName, i);
pNode = StudioUiBase::FindUiChildNode(pRootNode, tc);
CC_BREAK_IF(!pNode);
_pTabBtnData[i]._pContentNode = pNode;
} //tabBtn
sprintf(tc, "%s%d", pTabBtnName, i);
pNode = StudioUiBase::FindUiChildNode(pRootNode, tc);
pTempBtn = dynamic_cast<ui::Button*>(pNode);
CC_BREAK_IF(!pTempBtn);
//btnTxt
pNode = StudioUiBase::FindUiChildNode(pTempBtn, pTabTxtName);
pTempTxt = dynamic_cast<Text*>(pNode);
CC_BREAK_IF(!pTempTxt);
//tab 值
pTempBtn->setUserData(&(TabValue[i]));
//事件
pTempBtn->addClickEventListener(callback);
//保存
_pTabBtnData[i]._pTabBtn = pTempBtn;
_pTabBtnData[i]._pBtnTxt = pTempTxt; }
CC_BREAK_IF(i != tabCount); //获取最大的zorder-----------
int zoreder = ;
_tabMaxZorder = ;
for (i = ; i < tabCount; i++)
{
zoreder = _pTabBtnData[i]._pTabBtn->getLocalZOrder();
if (zoreder>_tabMaxZorder)
_tabMaxZorder = zoreder;
} ret = true;
} while (); return ret;
} void TabUiControl::ActiveTab(int index)
{
if (index >= && index < _tabCount)
{
int zorder = _tabMaxZorder; //选中设置
_pTabBtnData[index]._pTabBtn->setLocalZOrder(_tabMaxZorder);
_pTabBtnData[index]._pTabBtn->setBright(true);
_pTabBtnData[index]._pBtnTxt->setTextColor(_activeTxtColor); //内容可见性
if (_bHaveContenNode)
_pTabBtnData[index]._pContentNode->setVisible(true); //左边的tab
for (int i = index - ; i >= ; i--)
{
//未选中设置
zorder--;
_pTabBtnData[i]._pTabBtn->setLocalZOrder(zorder);
_pTabBtnData[i]._pTabBtn->setBright(false);
_pTabBtnData[i]._pBtnTxt->setTextColor(_unActiveTxtColor); //内容可见性
if (_bHaveContenNode)
_pTabBtnData[i]._pContentNode->setVisible(false);
} //右边的tab
for (int i = index + ; i < _tabCount; i++)
{
//未选中设置
zorder--;
_pTabBtnData[i]._pTabBtn->setLocalZOrder(zorder);
_pTabBtnData[i]._pTabBtn->setBright(false);
_pTabBtnData[i]._pBtnTxt->setTextColor(_unActiveTxtColor); //内容可见性
if (_bHaveContenNode)
_pTabBtnData[i]._pContentNode->setVisible(false);
} //回调
if (_onActiveCallback)
{
_onActiveCallback(index);
} }
} void TabUiControl::OnTabClick(Ref *pSender)
{
do
{
ui::Button *pBtn = dynamic_cast<ui::Button*>(pSender);
CC_BREAK_IF(!pBtn);
void *pUserData = pBtn->getUserData();
CC_BREAK_IF(!pUserData);
int *pValue = (int*)(pUserData);
//激活tab
ActiveTab(*pValue); } while ();
}

使用代码:

         //初始化tab
_tabControl.InitTab(pTabNode, );
//默认显示0
_tabControl.ActiveTab();

InitTab函数简要说明:

//pRootNode:tab 和内容节点的父节点 tabCount:tab总数,bHaveContenNode:tab是否有对应的内容节点,pTabBtnName:tab控件名前缀
//pTabTxtName:tab文本名称,pContentName:内容节点控件名前缀

在InitTab中根据pRootNode节点分别找出所有的tab按钮和对应的内容节点,最大的zorder等数据,在tab按钮响应函数里设置激活时的相关属性