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按钮响应函数里设置激活时的相关属性

 

posted @ 2016-01-15 17:37  冷夜 - 网游编程技术  阅读(1798)  评论(2编辑  收藏  举报