cocos2dx Tab选项卡控件的实现
选项卡控件在游戏和应用中很是常见,但是cocostudio里并没有实现好的选项卡控件,于是自己封装了 一个,效果如下:
代码:
TabUiControl.h
1 #pragma once 2 3 //std 4 #include <string> 5 6 //cocos 7 #include "cocos2d.h" 8 #include "cocostudio/CocoStudio.h" 9 #include "ui/CocosGUI.h" 10 11 12 using namespace std; 13 14 USING_NS_CC; 15 using namespace cocos2d::ui; 16 using namespace cocostudio; 17 using namespace cocostudio::timeline; 18 19 20 21 typedef std::function<void(int)> OnTabActioveCallback; 22 23 //tab控件数据 24 struct STabBtnData 25 { 26 STabBtnData() 27 { 28 _pTabBtn = nullptr; 29 _pBtnTxt = nullptr; 30 _pContentNode = nullptr; 31 } 32 ui::Button *_pTabBtn; //按钮 33 Text * _pBtnTxt; //按钮文字 34 Node *_pContentNode; //对应的内容node指针 35 }; 36 37 38 //选项卡控件 39 class TabUiControl 40 { 41 public: 42 TabUiControl(); 43 virtual ~TabUiControl(); 44 //初始化tab 45 bool InitTab(Node *pRootNode, int tabCount, bool bHaveContenNode = true,const char *pTabBtnName = "tabBtn", const char *pTabTxtName = "btnTxt", const char *pContentName = "tabContent"); 46 //tab单击事件 47 void OnTabClick(Ref *pSender); 48 //激活tab 49 void ActiveTab(int index); 50 //设置激活颜色 51 void SetActiveTxtColor(const Color4B &color){ _activeTxtColor = color; } 52 //设置未激活颜色 53 void SetUnActiveTxtColor(const Color4B &color){ _unActiveTxtColor = color; } 54 //设置选中回调 55 void SetActiveCallback(OnTabActioveCallback call){ _onActiveCallback = call; } 56 private: 57 //初始化静态数据 58 static void InitDefData(); 59 protected: 60 static const int MaxTabCount=12; //最大tab数量 61 static int TabValue[MaxTabCount]; //tab 值 62 int _tabCount; //tab数量 63 int _tabMaxZorder; //tabMaxZorder 64 STabBtnData *_pTabBtnData; //tab 数据 65 Color4B _activeTxtColor; //激活tabBtn文字颜色 66 Color4B _unActiveTxtColor; //未激活tabBtn文字颜色 67 OnTabActioveCallback _onActiveCallback; //tab被激活回调 68 bool _bHaveContenNode; //tab是否有对应的内容节点 69 private: 70 };
TabUiControl.cpp
1 #include "TabUiControl.h" 2 3 4 int TabUiControl::TabValue[MaxTabCount]; 5 6 TabUiControl::TabUiControl() 7 :_activeTxtColor(241, 255, 223, 255), _unActiveTxtColor(182, 167, 166, 255) 8 { 9 InitDefData(); 10 11 12 _tabMaxZorder = 0; 13 _tabCount = 0; 14 _pTabBtnData = nullptr; 15 _onActiveCallback = nullptr; 16 _bHaveContenNode = false; 17 18 19 } 20 21 TabUiControl::~TabUiControl() 22 { 23 24 CC_SAFE_DELETE_ARRAY(_pTabBtnData); 25 } 26 void TabUiControl::InitDefData() 27 { 28 static bool BInitOk = false; 29 if (!BInitOk) 30 { 31 for (int i = 0; i < MaxTabCount; i++) 32 { 33 TabValue[i] = i; 34 } 35 36 BInitOk = true; 37 } 38 39 } 40 41 bool TabUiControl::InitTab(Node *pRootNode, int tabCount, bool bHaveContenNode, const char *pTabBtnName, const char *pTabTxtName, const char *pContentName) 42 { 43 bool ret = false; 44 do 45 { 46 CC_BREAK_IF(!pTabBtnName || !pTabTxtName || !pRootNode || !pContentName); 47 CC_BREAK_IF(tabCount > MaxTabCount || tabCount <= 0); 48 49 50 //分配tab 数据 51 _pTabBtnData = new STabBtnData[tabCount]; 52 _tabCount = tabCount; 53 _bHaveContenNode = bHaveContenNode; 54 55 //临时变量 56 ui::Button *pTempBtn = nullptr; 57 Text *pTempTxt = nullptr; 58 Node *pNode = nullptr; 59 char tc[128] = { 0 }; 60 int i = 0; 61 Widget::ccWidgetClickCallback callback = CC_CALLBACK_1(TabUiControl::OnTabClick, this); 62 63 for (i = 0; i < tabCount; i++) 64 { 65 //内容节点指针 66 if (bHaveContenNode) 67 { 68 sprintf(tc, "%s%d", pContentName, i); 69 pNode = StudioUiBase::FindUiChildNode(pRootNode, tc); 70 CC_BREAK_IF(!pNode); 71 _pTabBtnData[i]._pContentNode = pNode; 72 } 73 74 75 //tabBtn 76 sprintf(tc, "%s%d", pTabBtnName, i); 77 pNode = StudioUiBase::FindUiChildNode(pRootNode, tc); 78 pTempBtn = dynamic_cast<ui::Button*>(pNode); 79 CC_BREAK_IF(!pTempBtn); 80 //btnTxt 81 pNode = StudioUiBase::FindUiChildNode(pTempBtn, pTabTxtName); 82 pTempTxt = dynamic_cast<Text*>(pNode); 83 CC_BREAK_IF(!pTempTxt); 84 //tab 值 85 pTempBtn->setUserData(&(TabValue[i])); 86 //事件 87 pTempBtn->addClickEventListener(callback); 88 //保存 89 _pTabBtnData[i]._pTabBtn = pTempBtn; 90 _pTabBtnData[i]._pBtnTxt = pTempTxt; 91 92 } 93 CC_BREAK_IF(i != tabCount); 94 95 //获取最大的zorder----------- 96 int zoreder = 0; 97 _tabMaxZorder = 0; 98 for (i = 0; i < tabCount; i++) 99 { 100 zoreder = _pTabBtnData[i]._pTabBtn->getLocalZOrder(); 101 if (zoreder>_tabMaxZorder) 102 _tabMaxZorder = zoreder; 103 } 104 105 ret = true; 106 } while (0); 107 108 return ret; 109 } 110 111 void TabUiControl::ActiveTab(int index) 112 { 113 if (index >= 0 && index < _tabCount) 114 { 115 int zorder = _tabMaxZorder; 116 117 //选中设置 118 _pTabBtnData[index]._pTabBtn->setLocalZOrder(_tabMaxZorder); 119 _pTabBtnData[index]._pTabBtn->setBright(true); 120 _pTabBtnData[index]._pBtnTxt->setTextColor(_activeTxtColor); 121 122 //内容可见性 123 if (_bHaveContenNode) 124 _pTabBtnData[index]._pContentNode->setVisible(true); 125 126 //左边的tab 127 for (int i = index - 1; i >= 0; i--) 128 { 129 //未选中设置 130 zorder--; 131 _pTabBtnData[i]._pTabBtn->setLocalZOrder(zorder); 132 _pTabBtnData[i]._pTabBtn->setBright(false); 133 _pTabBtnData[i]._pBtnTxt->setTextColor(_unActiveTxtColor); 134 135 //内容可见性 136 if (_bHaveContenNode) 137 _pTabBtnData[i]._pContentNode->setVisible(false); 138 } 139 140 //右边的tab 141 for (int i = index + 1; i < _tabCount; i++) 142 { 143 //未选中设置 144 zorder--; 145 _pTabBtnData[i]._pTabBtn->setLocalZOrder(zorder); 146 _pTabBtnData[i]._pTabBtn->setBright(false); 147 _pTabBtnData[i]._pBtnTxt->setTextColor(_unActiveTxtColor); 148 149 //内容可见性 150 if (_bHaveContenNode) 151 _pTabBtnData[i]._pContentNode->setVisible(false); 152 } 153 154 155 //回调 156 if (_onActiveCallback) 157 { 158 _onActiveCallback(index); 159 } 160 161 } 162 } 163 164 void TabUiControl::OnTabClick(Ref *pSender) 165 { 166 do 167 { 168 ui::Button *pBtn = dynamic_cast<ui::Button*>(pSender); 169 CC_BREAK_IF(!pBtn); 170 void *pUserData = pBtn->getUserData(); 171 CC_BREAK_IF(!pUserData); 172 int *pValue = (int*)(pUserData); 173 //激活tab 174 ActiveTab(*pValue); 175 176 177 } while (0); 178 }
使用代码:
1 //初始化tab 2 _tabControl.InitTab(pTabNode, 3); 3 //默认显示0 4 _tabControl.ActiveTab(0);
InitTab函数简要说明:
//pRootNode:tab 和内容节点的父节点 tabCount:tab总数,bHaveContenNode:tab是否有对应的内容节点,pTabBtnName:tab控件名前缀
//pTabTxtName:tab文本名称,pContentName:内容节点控件名前缀
在InitTab中根据pRootNode节点分别找出所有的tab按钮和对应的内容节点,最大的zorder等数据,在tab按钮响应函数里设置激活时的相关属性