【Cocos2d-x】源码分析之 2d/ui/Widget

前端之家收集整理的这篇文章主要介绍了【Cocos2d-x】源码分析之 2d/ui/Widget前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

【Cocos2d-x】源码分析之 2d/ui/Widget


转自:http://blog.csdn.net/yhhwatl/article/details/26487731

从今天开始 咱也模仿 红孩儿这些大牛分析源码 ,由于水平有限 不对之处欢迎狂喷。哈哈。

[cpp] view plain copy
@L_403_3@ ?
  1. #ifndef__UIWIDGET_H__
  2. #define__UIWIDGET_H__
  3. #include"ui/CCProtectedNode.h"
  4. #include"ui/UILayoutDefine.h"
  5. #include"ui/UILayoutParameter.h"
  6. #include"ui/GUIDefine.h"
  7. NS_CC_BEGIN
  8. namespaceui{
  9. typedefenum
  10. {
  11. BRIGHT_NONE=-1,
  12. BRIGHT_NORMAL,//正常
  13. BRIGHT_HIGHLIGHT//高亮按钮点击之后
  14. }BrightStyle;//明亮的风格
  15. enum
  16. {
  17. WidgetTypeWidget,119)">//control基本UIWidget默认
  18. WidgetTypeContainer//container容器layout实例化
  19. }WidgetType;//ui类型
  20. enum
  21. {
  22. UI_TEX_TYPE_LOCAL=0,119)">//meanslocalfile
  23. UI_TEX_TYPE_PLIST=1//meansspriteframe
  24. }TextureResType;//贴图类型
  25. enumclassTouchEventType
  26. {
  27. TOUCH_EVENT_BEGAN,119)">//开始
  28. TOUCH_EVENT_MOVED,119)">//移动
  29. TOUCH_EVENT_ENDED,119)">//结束
  30. TOUCH_EVENT_CANCELED//取消
  31. };//触摸事件类型
  32. enum
  33. {
  34. SIZE_ABSOLUTE,119)">//绝对值
  35. SIZE_PERCENT//百分比值
  36. }SizeType;//size值类型
  37. enum
  38. {
  39. POSITION_ABSOLUTE,119)">//绝对真实位置
  40. POSITION_PERCENT//相对父节点位置百分比
  41. }PositionType;//位置类型
  42. enum
  43. {
  44. WIDGET_SIZE,119)">//size
  45. WIDGET_POSITION//position
  46. }WidgetInfoType;//位置类型
  47. //哦这里说明一下回调函数被我修改了下主要是这样修改之后可以用到C++11的lambda表达式
copy
  1. //不必在使用的时候多声明一个回调函数了比较方便希望引擎组可以采用这种方式。
  2. typedefstd::function<void(Ref*,TouchEventType)>SEL_TouchEvent;
  3. //函数指针指向返回值void参数列表(Ref*,TouchEventType)类型的函数
  4. //typedefvoid(Ref::*SEL_TouchEvent)(Ref*,TouchEventType);
  5. //宏定义给函数指针SEL_TouchEvent取别名为toucheventselector
  6. #definetoucheventselector(_SELECTOR)(SEL_TouchEvent)(&_SELECTOR)
  7. classWidget:publicProtectedNode
  8. {
  9. public:
  10. Widget(void);
  11. virtual~Widget();
  12. staticWidget*create();
  13. /**设置是否触摸&&可见默认true*/
  14. virtualvoidsetEnabled(boolenabled);
  15. boolisEnabled()const;
  16. /**设置是否明亮默认true*/
  17. voidsetBright(boolbright);
  18. /**是否明亮*/
  19. boolisBright()/**是否可以触摸(响应事件)默认true*/
  20. voidsetTouchEnabled(boolenabled);
  21. /**设置明亮风格正常or明亮默认正常*/
  22. voidsetBrightStyle(BrightStylestyle);
  23. /**是否可以触摸*/
  24. boolisTouchEnabled()/**是否被选中默认false*/
  25. boolisFocused()/**是否被选中默认false*/
  26. voidsetFocused(boolfucosed);
  27. /**获取此控件距离左节点的下边界长度*/
  28. floatgetLeftInParent();
  29. /**获取此控件距离父节点的下边界长度*/
  30. floatgetBottomInParent();
  31. /**获取此控件距离父节点的右边界长度*/
  32. floatgetRightInParent();
  33. /**获取此控件距离父节点的上边界长度*/
  34. floatgetTopInParent();
  35. /**获取一个孩子从容器根据它的名字*/
  36. virtualWidget*getChildByName(constchar*name);
  37. /**渲染重载*/
  38. voidvisit(cocos2d::Renderer*renderer,constkmMat4&parentTransform,boolparentTransformUpdated)override;
  39. /**添加回调事件*/
  40. voidaddTouchEventListener(SEL_TouchEventselector);
  41. /**打印属性debug*/
  42. voidlogInfo(WidgetInfoType_type);
  43. //cocos2d属性
  44. /**
  45. 基类有的函数为virtual有的不是
  46. 不带virtual的是所有子类都拥有这个函数功能
  47. 带virtual的是拥有上述功能之外重载父类函数想拓展功能用的。
  48. 带virtual的函数可以使用多态即父类指针指向子类成员
  49. */
  50. /**
  51. *更改在OpenGL坐标系中widget的位置(X,Y)
  52. *原来的点(0,0)是在屏幕的左下角。
  53. *@参数位置在OpenGL坐标widget的位置(X,Y)
  54. */
  55. voidsetPosition(constPoint&pos)override;
  56. /**同上绝对位置变为百分比*/
  57. voidsetPositionPercent(constPoint&percent);
  58. /**得到在OpenGL坐标系中widget的百分比位置(X,Y)*/
  59. constPoint&getPositionPercent();
  60. /**设置位置类型*/
  61. voidsetPositionType(PositionTypetype);
  62. /**得到位置类型*/
  63. PositionTypegetPositionType()const;
  64. /**设置该widget是否水平翻转*/
  65. voidsetFlippedX(boolflippedX);
  66. /**该widget是否水平翻转*/
  67. virtualboolisFlippedX(){return_flippedX;};
  68. /**该widget是否垂直翻转*/
  69. voidsetFlippedY(boolflippedY);
  70. /**该widget是否垂直翻转*/
  71. boolisFlippedY(){return_flippedY;};
  72. /**设置颜色*/
  73. voidsetColor(constColor3B&color)override;
  74. /**设置透明度*/
  75. voidsetOpacity(GLubyteopacity)override;
  76. /**得到颜色值*/
  77. constColor3B&getColor()constoverride{return_color;};
  78. /**得到透明度*/
  79. GLubytegetOpacity()return_opacity;};
  80. /**弃用的属性*/
  81. /**@deprecatedUseisFlippedX()instead*/
  82. CC_DEPRECATED_ATTRIBUTEboolisFlipX(){returnisFlippedX();};
  83. /**@deprecatedUsesetFlippedX()instead*/
  84. CC_DEPRECATED_ATTRIBUTEvoidsetFlipX(boolflipX){setFlippedX(flipX);};
  85. /**@deprecatedUseisFlippedY()instead*/
  86. CC_DEPRECATED_ATTRIBUTEboolisFlipY(){returnisFlippedY();};
  87. /**@deprecatedUsesetFlippedY()instead*/
  88. CC_DEPRECATED_ATTRIBUTEvoidsetFlipY(boolflipY){setFlippedY(flipY);};
  89. /**当该widget失去焦点会调用*/
  90. voiddidNotSelectSelf();
  91. /**检查一个点是否在父节点区域*/
  92. boolclippingParentAreaContainPoint(constPoint&pt);
  93. /**发送触摸事件到widget的父节点*/
  94. voidcheckChildInfo(inthandleState,Widget*sender,255); font-weight:bold">constPoint&touchPoint);
  95. /**Getsthetouchbeganpointofwidgetwhenwidgetisselected.*/
  96. constPoint&getTouchStartPos();
  97. /**Getsthetouchmovepointofwidgetwhenwidgetisselected*/
  98. constPoint&getTouchMovePos();
  99. /**Getsthetouchendpointofwidgetwhenwidgetisselected.*/
  100. constPoint&getTouchEndPos();
  101. /**设置name*/
  102. voidsetName(char*name);
  103. /**得到name*/
  104. char*getName()const;
  105. /**得到控件类型*/
  106. WidgetTypegetWidgetType()/**设置控件大小*/
  107. voidsetSize(constSize&size);
  108. voidsetSizeW(int&sizeW);
  109. voidsetSizeH(int&sizeH);
  110. /**设置size百分比*/
  111. voidsetSizePercent(constPoint&percent);
  112. /**size类型*/
  113. voidsetSizeType(SizeTypetype);
  114. /**得到size类型*/
  115. SizeTypegetSizeType()/**得到size*/
  116. constSize&getSize()/**得到Customsize*/
  117. constSize&getCustomSize()/**得到layoutsize*/
  118. constSize&getLayoutSize(){return_size;};//虚函数供子类重写?
  119. /**得到size百分比*/
  120. constPoint&getSizePercent()/***/
  121. boolhitTest(constPoint&pt);
  122. /**触摸事件*/
  123. boolonTouchBegan(Touch*touch,Event*unusedEvent);
  124. voidonTouchMoved(Touch*touch,Event*unusedEvent);
  125. voidonTouchEnded(Touch*touch,255); font-weight:bold">voidonTouchCancelled(Touch*touch,Event*unusedEvent);
  126. /**设置布局参数*/
  127. voidsetLayoutParameter(LayoutParameter*parameter);
  128. /**得到布局参数*/
  129. LayoutParameter*getLayoutParameter(LayoutParameterTypetype);
  130. /**是否忽略size使用texturesize默认true*/
  131. voidignoreContentAdaptWithSize(boolignore);
  132. /**是否忽略size使用texturesize*/
  133. boolisIgnoreContentAdaptWithSize()/**得到世界位置*/
  134. PointgetWorldPosition();
  135. /**得到虚拟渲染器例如一个button的虚拟渲染器是他的texturerenderer贴图渲染器*/
  136. virtualNode*getVirtualRenderer();
  137. /**得到虚拟渲染器的size默认是_contentSize不同的子类有自己的重载*/
  138. constSize&getVirtualRendererSize()const;
  139. *得到改控件对应的"classname".
  140. virtualstd::stringgetDescription()constoverride;
  141. /**克隆替身*/
  142. Widget*clone();
  143. voidonEnter()override;
  144. voidonExit()override;
  145. /**更新size和position*/
  146. voidupdateSizeAndPosition();
  147. voidupdateSizeAndPosition(constSize&parentSize);
  148. /*tempaction*/
  149. voidsetActionTag(inttag);
  150. intgetActionTag();
  151. CC_CONSTRUCTOR_ACCESS:
  152. //initializesstateofwidget.
  153. boolinit()override;
  154. protected:
  155. //callbackfunctioncalledwhensizechanged.
  156. voidonSizeChanged();
  157. //initializesrendererofwidget.
  158. voidinitRenderer();
  159. //回复正常调用.
  160. voidonPressStateChangedToNormal();
  161. //选中会调用
  162. voidonPressStateChangedToPressed();
  163. //变暗会调用
  164. voidonPressStateChangedToDisabled();
  165. //不同的事件
  166. voidpushDownEvent();
  167. voidmoveEvent();
  168. voidreleaseUpEvent();
  169. voidcancelUpEvent();
  170. //空的虚函数为了多态
  171. voidupdateTextureColor(){};
  172. voidupdateTextureOpacity(){};
  173. voidupdateTextureRGBA(){};
  174. voidupdateFlippedX(){};
  175. voidupdateFlippedY(){};
  176. voidupdateColorToRenderer(Node*renderer);
  177. voidupdateOpacityToRenderer(Node*renderer);
  178. voidupdateRGBAToRenderer(Node*renderer);
  179. voidcopyProperties(Widget*model);
  180. virtualWidget*createCloneInstance();
  181. voidcopySpecialProperties(Widget*model);
  182. voidcopyClonedWidgetChildren(Widget*model);
  183. Widget*getWidgetParent();
  184. voidupdateContentSizeWithTextureSize(constSize&size);
  185. /**多态适用于所有的子类重载实现自己的逻辑*/
  186. voidadaptRenderers(){};
  187. protected:
  188. bool_enabled;///<是否可见&&可触摸最高属性
  189. bool_bright;///<是否光亮
  190. bool_touchEnabled;///<是否响应触摸
  191. bool_touchPassedEnabled;///<触摸时间是不是按下
  192. bool_focus;///<是不是焦点
  193. BrightStyle_brightStyle;///<明亮风格
  194. Point_touchStartPos;///<touchbeganpoint
  195. Point_touchMovePos;///<touchmovedpoint
  196. Point_touchEndPos;///<touchendedpoint
  197. SEL_TouchEvent_touchEventSelector;///回调函数类型
  198. std::string_name;///类名
  199. WidgetType_widgetType;///控件类型
  200. int_actionTag;///执行动作的tag
  201. Size_size;///untransformedsize
  202. Size_customSize;///自定义size
  203. bool_ignoreSize;///是否忽略自定义的大小而取资源原本的大小untransformedimgsize默认_size=_customSize
  204. bool_affectByClipping;
  205. SizeType_sizeType;///size类型
  206. Point_sizePercent;///相对父节点size百分比
  207. PositionType_positionType;///位置类型
  208. Point_positionPercent;///相对父节点的位置百分比
  209. bool_reorderWidgetChildDirty;
  210. bool_hitted;
  211. EventListenerTouchOneByOne*_touchListener;///单点触摸
  212. Color3B_color;///颜色值
  213. GLubyte_opacity;///透明度
  214. bool_flippedX;//是否镜像X轴
  215. bool_flippedY;//是否镜像Y轴
  216. Map<int,LayoutParameter*>_layoutParameterDictionary;//布局参数Map
  217. };
  218. }
  219. NS_CC_END
  220. #endif/*defined(__Widget__)*/

copy
/****************************************************************************
  • Copyright(c)2013-2014ChukongTechnologiesInc.
  • http://www.cocos2d-x.org
  • Permissionisherebygranted,freeofcharge,toanypersonobtainingacopy
  • ofthissoftwareandassociateddocumentationfiles(the"Software"),todeal
  • intheSoftwarewithoutrestriction,includingwithoutlimitationtherights
  • touse,copy,modify,merge,publish,distribute,sublicense,and/orsell
  • copiesoftheSoftware,andtopermitpersonstowhomtheSoftwareis
  • furnishedtodoso,subjecttothefollowingconditions:
  • Theabovecopyrightnoticeandthispermissionnoticeshallbeincludedin
  • allcopiesorsubstantialportionsoftheSoftware.
  • THESOFTWAREISPROVIDED"ASIS",WITHOUTWARRANTYOFANYKIND,EXPRESSOR
  • IMPLIED,INCLUDINGBUTNOTLIMITEDTOTHEWARRANTIESOFMERCHANTABILITY,
  • FITNESSFORAPARTICULARPURPOSEANDNONINFRINGEMENT.INNOEVENTSHALLTHE
  • AUTHORSORCOPYRIGHTHOLDERSBELIABLEFORANYCLAIM,DAMAGESOROTHER
  • LIABILITY,WHETHERINANACTIONOFCONTRACT,TORTOROTHERWISE,ARISINGFROM,
  • OUTOFORINCONNECTIONWITHTHESOFTWAREORTHEUSEOROTHERDEALINGSIN
  • THESOFTWARE.
  • ****************************************************************************/
  • #include"ui/UIWidget.h"
  • #include"ui/UILayout.h"
  • #include"ui/UIHelper.h"
  • NS_CC_BEGIN
  • namespaceui{
  • Widget::Widget():
  • _enabled(true),
  • _bright( _touchEnabled(false),
  • _touchPassedEnabled( _focus( _brightStyle(BRIGHT_NONE),
  • _touchStartPos(Point::ZERO),
  • _touchMovePos(Point::ZERO),
  • _touchEndPos(Point::ZERO),
  • _touchEventSelector(nullptr),
  • _name("default"),
  • _widgetType(WidgetTypeWidget),
  • _actionTag(0),
  • _size(Size::ZERO),
  • _customSize(Size::ZERO),
  • _ignoreSize( _affectByClipping( _sizeType(SIZE_ABSOLUTE),
  • _sizePercent(Point::ZERO),
  • _positionType(POSITION_ABSOLUTE),
  • _positionPercent(Point::ZERO),
  • _reorderWidgetChildDirty( _hitted( _touchListener(nullptr),
  • _color(Color3B::WHITE),
  • _opacity(255),
  • _flippedX( _flippedY(false)
  • {
  • }
  • Widget::~Widget()
  • {
  • _touchEventSelector=nullptr;
  • setTouchEnabled(false);
  • }
  • Widget*Widget::create()
  • {
  • Widget*widget=newWidget();
  • if(widget&&widget->init())
  • {
  • widget->autorelease();
  • returnwidget;
  • }
  • CC_SAFE_DELETE(widget);
  • returnnullptr;
  • }
  • boolWidget::init()
  • {
  • if(ProtectedNode::init())
  • {
  • initRenderer();//初始化渲染器多态
  • setBright(true);//设置明亮
  • ignoreContentAdaptWithSize(//默认内容不适应size大小
  • setAnchorPoint(Point(0.5f,0.5f));//默认锚点在中心
  • returntrue;
  • }
  • false;
  • }
  • voidWidget::onEnter()
  • {
  • updateSizeAndPosition();
  • ProtectedNode::onEnter();
  • }
  • voidWidget::onExit()
  • {
  • unscheduleUpdate();
  • ProtectedNode::onExit();
  • }
  • voidWidget::visit(Renderer*renderer,51); font-weight:bold">boolparentTransformUpdated)
  • {
  • if(_enabled)
  • {
  • adaptRenderers();
  • ProtectedNode::visit(renderer,parentTransform,parentTransformUpdated);
  • }
  • }
  • Widget*Widget::getWidgetParent()
  • {
  • //得到父节点
  • dynamic_cast<Widget*>(getParent());
  • }
  • voidWidget::setEnabled(boolenabled)
  • {
  • _enabled=enabled;
  • for(auto&child:_children)
  • {
  • if(child)
  • {
  • Widget*widgetChild=dynamic_cast<Widget*>(child);
  • if(widgetChild)
  • {
  • widgetChild->setEnabled(enabled);
  • }
  • }
  • }
  • for(auto&child:_protectedChildren)
  • {
  • if(widgetChild)
  • {
  • widgetChild->setEnabled(enabled);
  • }
  • }
  • }
  • }
  • Widget*Widget::getChildByName(char*name)
  • {
  • for(auto&child:_children)
  • {
  • if(child)
  • {
  • Widget*widgetChild=dynamic_cast<Widget*>(child);
  • if(widgetChild)
  • {
  • if(strcmp(widgetChild->getName(),name)==0)
  • {
  • returnwidgetChild;
  • }
  • }
  • }
  • }
  • returnnullptr;
  • }
  • voidWidget::initRenderer()
  • {
  • //多态不同的控件有自己的初始化渲染方式
  • }
  • voidWidget::setSizeW(int&sizeW)
  • {
  • _customSize.width=sizeW;
  • if(_ignoreSize)
  • {
  • _size=getVirtualRendererSize();
  • }
  • else
  • {
  • _size.width=sizeW;
  • }
  • if(_running)
  • {
  • Widget*widgetParent=getWidgetParent();
  • SizepSize;
  • if(widgetParent)
  • {
  • pSize=widgetParent->getSize();
  • }
  • else
  • {
  • pSize=_parent->getContentSize();
  • }
  • floatspx=0.0f;
  • floatspy=0.0f;
  • if(pSize.width>0.0f)
  • {
  • spx=_customSize.width/pSize.width;
  • }
  • if(pSize.height>0.0f)
  • {
  • spy=_customSize.height/pSize.height;
  • }
  • _sizePercent=Point(spx,spy);
  • }
  • onSizeChanged();
  • }
  • voidWidget::setSizeH(int&sizeH)
  • {
  • _customSize.height=sizeH;
  • if(_ignoreSize)
  • {
  • _size=getVirtualRendererSize();
  • }
  • else
  • {
  • _size.height=sizeH;
  • }
  • if(_running)
  • {
  • Widget*widgetParent=getWidgetParent();
  • SizepSize;
  • if(widgetParent)
  • {
  • pSize=widgetParent->getSize();
  • }
  • else
  • {
  • pSize=_parent->getContentSize();
  • }
  • floatspx=0.0f;
  • floatspy=0.0f;
  • if(pSize.width>0.0f)
  • {
  • spx=_customSize.width/pSize.width;
  • }
  • if(pSize.height>0.0f)
  • {
  • spy=_customSize.height/pSize.height;
  • }
  • _sizePercent=Point(spx,spy);
  • }
  • onSizeChanged();
  • }
  • voidWidget::setSize(constSize&size)
  • {
  • _customSize=size;
  • else
  • {
  • _size=size;
  • }
  • }
  • onSizeChanged();
  • }
  • voidWidget::setSizePercent(constPoint&percent)
  • {
  • _sizePercent=percent;
  • SizecSize=_customSize;
  • if(_running)
  • {
  • Widget*widgetParent=getWidgetParent();
  • if(widgetParent)
  • {
  • cSize=Size(widgetParent->getSize().width*percent.x,widgetParent->getSize().height*percent.y);
  • }
  • else
  • {
  • cSize=Size(_parent->getContentSize().width*percent.x,_parent->getContentSize().height*percent.y);
  • }
  • }
  • else
  • {
  • _size=cSize;
  • }
  • _customSize=cSize;
  • onSizeChanged();
  • }
  • voidWidget::updateSizeAndPosition()
  • {
  • Widget*widgetParent=getWidgetParent();
  • SizepSize;
  • if(widgetParent)
  • {//如果有父节点是控件基类widget保存父节点的容器大小
  • pSize=widgetParent->getLayoutSize();
  • }
  • else
  • {//如果父节点不是控件基类widget得到绑定贴图大小
  • pSize=_parent->getContentSize();
  • }
  • updateSizeAndPosition(pSize);
  • }
  • voidWidget::updateSizeAndPosition(constcocos2d::Size&parentSize)
  • {
  • switch(_sizeType)
  • {
  • caseSIZE_ABSOLUTE://绝对大小真实大小
  • {
  • if(_ignoreSize)//忽略设置的大小
  • {
  • _size=getVirtualRendererSize();//size取untransformedimgsize
  • }
  • else//不忽略自定义大小
  • {
  • _size=_customSize;//size取自定义大小
  • }
  • if(parentSize.width>0.0f)
  • {
  • spx=_customSize.width/parentSize.width;
  • }
  • if(parentSize.height>0.0f)
  • {
  • spy=_customSize.height/parentSize.height;
  • }
  • _sizePercent=Point(spx,spy);//计算得到相对父节点的size百分比
  • break;
  • }
  • caseSIZE_PERCENT://百分比size
  • {
  • SizecSize=Size(parentSize.width*_sizePercent.x,parentSize.height*_sizePercent.y);//计算得到自定义大小
  • //不忽略自定义大小
  • {
  • _size=cSize;//size取计算得到自定义大小
  • }
  • _customSize=cSize;//计算得到自定义大小
  • default:
  • break;
  • }
  • onSizeChanged();
  • PointabsPos=getPosition();
  • switch(_positionType)
  • {
  • casePOSITION_ABSOLUTE://真实位置
  • {
  • if(parentSize.width<=0.0f||parentSize.height<=0.0f)
  • {//父节点size=0
  • _positionPercent=Point::ZERO;//相对父节点的位置百分比为0
  • }
  • else
  • {
  • _positionPercent=Point(absPos.x/parentSize.width,absPos.y/parentSize.height);//相对父节点的位置百分比
  • }
  • break;
  • }
  • casePOSITION_PERCENT://相对位置
  • {
  • absPos=Point(parentSize.width*_positionPercent.x,parentSize.height*_positionPercent.y);//得到真实位置
  • break;
  • }
  • setPosition(absPos);//更新真实位置
  • }
  • voidWidget::setSizeType(SizeTypetype)
  • {
  • _sizeType=type;//设置size类型
  • }
  • SizeTypeWidget::getSizeType()const//返回值不可改
  • {
  • return_sizeType;//得到sizetype返回值不可改
  • }
  • voidWidget::ignoreContentAdaptWithSize(boolignore)
  • {
  • if(_ignoreSize==ignore)
  • {
  • return;//和当前值一样没必要更新处理了直接返回
  • }
  • _ignoreSize=ignore;
  • //忽略自定义size
  • {
  • Sizes=getVirtualRendererSize();//取原本大小的size
  • _size=s;
  • }
  • //不忽略自定义size
  • {
  • _size=_customSize;//取自定义size
  • }
  • onSizeChanged();//更新size
  • }
  • boolWidget::isIgnoreContentAdaptWithSize()const
  • {
  • return_ignoreSize;
  • }
  • constSize&Widget::getSize()const
  • {
  • return_size;
  • }
  • constSize&Widget::getCustomSize()return_customSize;
  • }
  • constPoint&Widget::getSizePercent()return_sizePercent;
  • }
  • PointWidget::getWorldPosition()
  • {
  • returnconvertToWorldSpace(Point(_anchorPoint.x*_contentSize.width,_anchorPoint.y*_contentSize.height));//得到世界坐标
  • }
  • Node*Widget::getVirtualRenderer()
  • {
  • this;//得到虚拟渲染器默认是自己不同的子类有自己的重载
  • }
  • voidWidget::onSizeChanged()
  • {
  • setContentSize(_size);//设置untransformedsize
  • for(auto&child:getChildren())
  • {
  • Widget*widgetChild=if(widgetChild)
  • {
  • widgetChild->updateSizeAndPosition();//递归更新所有子节点sizeposition
  • }
  • }
  • }
  • constSize&Widget::getVirtualRendererSize()return_contentSize;//得到虚拟渲染器zise默认是_contentSize不同的子类有自己的重载
  • }
  • voidWidget::updateContentSizeWithTextureSize(constcocos2d::Size&size)
  • {
  • if(_ignoreSize)
  • {
  • _size=size;
  • }
  • else
  • {
  • _size=_customSize;
  • }
  • onSizeChanged();
  • }
  • voidWidget::setTouchEnabled(boolenable)
  • {
  • if(enable==_touchEnabled)
  • {
  • return;
  • }
  • _touchEnabled=enable;
  • if(_touchEnabled)//如果开启触摸
  • {
  • _touchListener=EventListenerTouchOneByOne::create();
  • CC_SAFE_RETAIN(_touchListener);//创建单点触摸
  • _touchListener->setSwallowTouches(//不向下触摸,简单点来说,比如有两个sprite,A和B,A在上B在下(位置重叠),触摸A的时候,B不会受到影响
  • //绑定四个回调函数
  • _touchListener->onTouchBegan=CC_CALLBACK_2(Widget::onTouchBegan,this);
  • _touchListener->onTouchMoved=CC_CALLBACK_2(Widget::onTouchMoved,255); font-weight:bold">this);
  • _touchListener->onTouchEnded=CC_CALLBACK_2(Widget::onTouchEnded,255); font-weight:bold">this);
  • _touchListener->onTouchCancelled=CC_CALLBACK_2(Widget::onTouchCancelled,255); font-weight:bold">this);
  • _eventDispatcher->addEventListenerWithSceneGraPHPriority(_touchListener,255); font-weight:bold">this);
  • }
  • else//如果不开启触摸
  • {
  • _eventDispatcher->removeEventListener(_touchListener);//移除
  • CC_SAFE_RELEASE_NULL(_touchListener);//释放
  • }
  • }
  • boolWidget::isTouchEnabled()return_touchEnabled;
  • }
  • boolWidget::isFocused()return_focus;
  • }
  • voidWidget::setFocused(boolfucos)
  • {
  • if(fucos==_focus)
  • {
  • return;
  • }
  • _focus=fucos;
  • if(_bright)//如果亮
  • {
  • if(_focus)//如果选中
  • {
  • setBrightStyle(BRIGHT_HIGHLIGHT);//高亮
  • }
  • //如果没有选中
  • {
  • setBrightStyle(BRIGHT_NORMAL);//正常
  • }
  • }
  • //如果不亮
  • {
  • onPressStateChangedToDisabled();//变暗
  • }
  • }
  • voidWidget::setBright(boolbright)
  • {
  • _bright=bright;
  • //如果亮
  • {
  • _brightStyle=BRIGHT_NONE;
  • setBrightStyle(BRIGHT_NORMAL);//正常亮
  • }
  • voidWidget::setBrightStyle(BrightStylestyle)
  • {
  • if(_brightStyle==style)
  • {
  • return;
  • }
  • _brightStyle=style;
  • switch(_brightStyle)
  • {
  • caseBRIGHT_NORMAL:
  • onPressStateChangedToNormal();
  • break;
  • caseBRIGHT_HIGHLIGHT:
  • onPressStateChangedToPressed();
  • break;
  • default:
  • break;
  • }
  • }
  • voidWidget::onPressStateChangedToNormal()
  • {
  • }
  • voidWidget::onPressStateChangedToPressed()
  • {
  • }
  • voidWidget::onPressStateChangedToDisabled()
  • {
  • }
  • voidWidget::didNotSelectSelf()
  • {
  • }
  • voidWidget::logInfo(WidgetInfoType_type)
  • {
  • log("widgetanchorx=%f,y=%f",getAnchorPoint().x,getAnchorPoint().y);
  • if(_type==WIDGET_SIZE){
  • log("widgetsizewidth=%f,height=%f",_size.width,_size.height);
  • }
  • if(_type==WIDGET_POSITION){
  • log("widgetpositionx=%f,getPositionX(),getPositionY());
  • }
  • }
  • boolWidget::onTouchBegan(Touch*touch,Event*unusedEvent)
  • {
  • _hitted=false;//刚开始触摸没有碰到
  • if(isEnabled()&&isTouchEnabled())//节点可以使用可以点击
  • {
  • _touchStartPos=touch->getLocation();//得到点击位置
  • //触摸点在到图像区域并且触摸点在裁切区域
  • if(hitTest(_touchStartPos)&&clippingParentAreaContainPoint(_touchStartPos))
  • {
  • _hitted=true;//触摸到了
  • }
  • }
  • if(!_hitted)//没有触摸到
  • {
  • //停止
  • }
  • setFocused(//得到焦点
  • Widget*widgetParent=getWidgetParent();
  • if(widgetParent)//有父节点
  • {
  • widgetParent->checkChildInfo(0,255); font-weight:bold">this,_touchStartPos);//检查孩子属性
  • }
  • pushDownEvent();//按下回调响应
  • return!_touchPassedEnabled;
  • }
  • voidWidget::onTouchMoved(Touch*touch,Event*unusedEvent)
  • {
  • _touchMovePos=touch->getLocation();
  • setFocused(hitTest(_touchMovePos));
  • Widget*widgetParent=getWidgetParent();
  • if(widgetParent)
  • {
  • widgetParent->checkChildInfo(1,_touchMovePos);
  • }
  • moveEvent();
  • }
  • voidWidget::onTouchEnded(Touch*touch,Event*unusedEvent)
  • {
  • _touchEndPos=touch->getLocation();
  • boolfocus=_focus;
  • setFocused(false);
  • Widget*widgetParent=getWidgetParent();
  • if(widgetParent)
  • {
  • widgetParent->checkChildInfo(2,_touchEndPos);
  • }
  • if(focus)
  • {
  • releaseUpEvent();
  • }
  • else
  • {
  • cancelUpEvent();
  • }
  • }
  • voidWidget::onTouchCancelled(Touch*touch,Event*unusedEvent)
  • {
  • setFocused(false);
  • cancelUpEvent();
  • }
  • voidWidget::pushDownEvent()
  • {
  • if(_touchEventSelector)
  • {
  • //(->*_touchEventSelector)(this,TouchEventType::TOUCH_EVENT_BEGAN);//响应开始按下的回调
  • _touchEventSelector(//响应开始按下的回调
  • }
  • }
  • voidWidget::moveEvent()
  • {
  • if(_touchEventSelector)
  • {
  • _touchEventSelector(//响应移动的回调
  • }
  • }
  • voidWidget::releaseUpEvent()
  • {
  • _touchEventSelector(//响应结束的回调
  • }
  • }
  • voidWidget::cancelUpEvent()
  • {
  • if(_touchEventSelector)
  • {
  • _touchEventSelector(//响应取消按下的回调
  • }
  • }
  • //共外部注册回调
  • voidWidget::addTouchEventListener(SEL_TouchEventselector)
  • {
  • _touchEventSelector=selector;
  • }
  • boolWidget::hitTest(constPoint&pt)
  • {
  • Pointnsp=convertToNodeSpace(pt);//相对this的点
  • Rectbb;
  • bb.size=_contentSize;
  • if(bb.containsPoint(nsp))
  • {
  • //点在size内hit~!
  • }
  • false;
  • }
  • boolWidget::clippingParentAreaContainPoint(constPoint&pt)
  • {
  • _affectByClipping=false;
  • Widget*parent=getWidgetParent();
  • Widget*clippingParent=nullptr;
  • while(parent)//有父节点
  • {
  • Layout*layoutParent=dynamic_cast<Layout*>(parent);
  • if(layoutParent)//父节点是层容器
  • {
  • if(layoutParent->isClippingEnabled())//父节点是可以裁切的
  • {
  • _affectByClipping=//受裁切的影响
  • clippingParent=layoutParent;//取到已经裁切的父节点
  • break;//跳出循环
  • }
  • }
  • parent=parent->getWidgetParent();//向上遍历父节点
  • }
  • if(!_affectByClipping)//没有可以裁切的层容器
  • {
  • true;
  • }
  • if(clippingParent)//存在裁切的父节点
  • {
  • boolbRet=false;
  • if(clippingParent->hitTest(pt))//点在裁切裁切范围内
  • {
  • bRet=if(bRet)
  • {
  • returnclippingParent->clippingParentAreaContainPoint(pt);//递归裁切父节点
  • }
  • false;
  • }
  • true;
  • }
  • voidWidget::checkChildInfo(constPoint&touchPoint)
  • {
  • Widget*widgetParent=getWidgetParent();
  • if(widgetParent)
  • {
  • widgetParent->checkChildInfo(handleState,sender,touchPoint);//递归检查孩子的info
  • }
  • }
  • voidWidget::setPosition(constPoint&pos)
  • {
  • if(_running)//若在运行状态
  • {
  • Widget*widgetParent=getWidgetParent();
  • //若有父节点
  • {
  • SizepSize=widgetParent->getSize();//父节点大小
  • if(pSize.width<=0.0f||pSize.height<=0.0f)
  • {
  • _positionPercent=Point::ZERO;//百分比为0
  • }
  • else
  • {//计算相对父节点百分比
  • _positionPercent=Point(pos.x/pSize.width,pos.y/pSize.height);
  • }
  • }
  • }
  • //因为widget对于position的表示除了世界坐标之外还新加了百分比坐标
  • //所以需要额外处理计算百分比坐标
  • ProtectedNode::setPosition(pos);
  • }
  • voidWidget::setPositionPercent(constPoint&percent)
  • {
  • _positionPercent=percent;
  • if(_running)
  • {
  • Widget*widgetParent=getWidgetParent();
  • if(widgetParent)
  • {
  • SizeparentSize=widgetParent->getSize();
  • PointabsPos=Point(parentSize.width*_positionPercent.x,119)">//绝对坐标
  • setPosition(absPos);
  • }
  • }
  • }
  • constPoint&Widget::getPositionPercent()
  • {
  • return_positionPercent;
  • }
  • voidWidget::setPositionType(PositionTypetype)
  • {
  • _positionType=type;
  • }
  • PositionTypeWidget::getPositionType()return_positionType;
  • }
  • boolWidget::isBright()return_bright;
  • }
  • boolWidget::isEnabled()return_enabled;
  • }
  • floatWidget::getLeftInParent()
  • {
  • returngetPosition().x-getAnchorPoint().x*_size.width;;
  • }
  • //得到距离父节点底部的距离
  • floatWidget::getBottomInParent()
  • {
  • returngetPosition().y-getAnchorPoint().y*_size.height;;
  • }
  • floatWidget::getRightInParent()
  • {
  • returngetLeftInParent()+_size.width;
  • }
  • floatWidget::getTopInParent()
  • {
  • returngetBottomInParent()+_size.height;
  • }
  • constPoint&Widget::getTouchStartPos()
  • {
  • return_touchStartPos;
  • }
  • constPoint&Widget::getTouchMovePos()
  • {
  • return_touchMovePos;
  • }
  • constPoint&Widget::getTouchEndPos()
  • {
  • return_touchEndPos;
  • }
  • voidWidget::setName(char*name)
  • {
  • _name=name;
  • }
  • char*Widget::getName()return_name.c_str();
  • }
  • WidgetTypeWidget::getWidgetType()return_widgetType;
  • }
  • //设置布局参数
  • voidWidget::setLayoutParameter(LayoutParameter*parameter)
  • {
  • if(!parameter)
  • {
  • return;
  • }
  • _layoutParameterDictionary.insert(parameter->getLayoutType(),parameter);
  • }
  • //得到所有布局参数
  • LayoutParameter*Widget::getLayoutParameter(LayoutParameterTypetype)
  • {
  • dynamic_cast<LayoutParameter*>(_layoutParameterDictionary.at(type));
  • }
  • std::stringWidget::getDescription()return"Widget";
  • }
  • //克隆
  • Widget*Widget::clone()
  • {
  • Widget*clonedWidget=createCloneInstance();
  • clonedWidget->copyProperties(this);//拷贝基础属性
  • clonedWidget->copyClonedWidgetChildren(//拷贝所有孩子
  • returnclonedWidget;
  • }
  • Widget*Widget::createCloneInstance()
  • {
  • returnWidget::create();
  • }
  • voidWidget::copyClonedWidgetChildren(Widget*model)
  • {
  • //引用类型auto&
  • auto&modelChildren=model->getChildren();
  • for(auto&subWidget:modelChildren)
  • {
  • Widget*child=dynamic_cast<Widget*>(subWidget);
  • if(child)
  • {
  • addChild(child->clone());
  • }
  • }
  • }
  • voidWidget::copySpecialProperties(Widget*model)
  • {
  • }
  • //拷贝属性
  • voidWidget::copyProperties(Widget*widget)
  • {
  • setEnabled(widget->isEnabled());
  • setVisible(widget->isVisible());
  • setBright(widget->isBright());
  • setTouchEnabled(widget->isTouchEnabled());
  • _touchPassedEnabled=false;
  • setLocalZOrder(widget->getLocalZOrder());
  • setTag(widget->getTag());
  • setName(widget->getName());
  • setActionTag(widget->getActionTag());
  • _ignoreSize=widget->_ignoreSize;
  • _size=widget->_size;
  • _customSize=widget->_customSize;
  • copySpecialProperties(widget);
  • _sizeType=widget->getSizeType();
  • _sizePercent=widget->_sizePercent;
  • _positionType=widget->_positionType;
  • _positionPercent=widget->_positionPercent;
  • setPosition(widget->getPosition());
  • setAnchorPoint(widget->getAnchorPoint());
  • setScaleX(widget->getScaleX());
  • setScaleY(widget->getScaleY());
  • setRotation(widget->getRotation());
  • setRotationSkewX(widget->getRotationSkewX());
  • setRotationSkewY(widget->getRotationSkewY());
  • setFlippedX(widget->isFlippedX());
  • setFlippedY(widget->isFlippedY());
  • setColor(widget->getColor());
  • setOpacity(widget->getOpacity());
  • //遍历布局参数容器拷贝
  • Map< for(autoiter=layoutParameterDic.begin();iter!=layoutParameterDic.end();++iter)
  • {
  • setLayoutParameter(iter->second->clone());
  • }
  • onSizeChanged();
  • }
  • voidWidget::setColor(constColor3B&color)
  • {
  • _color=color;
  • updateTextureColor();
  • }
  • voidWidget::setOpacity(GLubyteopacity)
  • {
  • _opacity=opacity;
  • updateTextureOpacity();
  • }
  • voidWidget::setFlippedX(boolflippedX)
  • {
  • _flippedX=flippedX;
  • updateFlippedX();
  • }
  • voidWidget::setFlippedY(boolflippedY)
  • {
  • _flippedY=flippedY;
  • updateFlippedY();
  • }
  • voidWidget::updateColorToRenderer(Node*renderer)
  • {
  • renderer->setColor(_color);
  • }
  • voidWidget::updateOpacityToRenderer(Node*renderer)
  • {
  • renderer->setOpacity(_opacity);
  • }
  • voidWidget::updateRGBAToRenderer(Node*renderer)
  • {
  • renderer->setColor(_color);
  • renderer->setOpacity(_opacity);
  • }
  • /*tempaction*/
  • voidWidget::setActionTag(inttag)
  • {
  • _actionTag=tag;
  • }
  • intWidget::getActionTag()
  • {
  • return_actionTag;
  • }
  • }
  • NS_CC_END
  • 猜你在找的Cocos2d-x相关文章