【Cocos2d-x】源代码分析之 2d/ui/Widget
从今天開始 咱也模仿 红孩儿这些大牛分析源代码 ,因为水平有限 不正确之处欢迎狂喷。哈哈。
- #ifndef __UIWIDGET_H__
- #define __UIWIDGET_H__
- #include "ui/CCProtectedNode.h"
- #include "ui/UILayoutDefine.h"
- #include "ui/UILayoutParameter.h"
- #include "ui/GUIDefine.h"
- NS_CC_BEGIN
- namespace ui {
- typedef enum
- {
- BRIGHT_NONE = -1,
- BRIGHT_NORMAL,//正常
- BRIGHT_HIGHLIGHT//高亮 按钮点击之后
- }BrightStyle;//明亮的风格
- typedef enum
- {
- WidgetTypeWidget, //control 基本 UIWidget 默认
- WidgetTypeContainer //container 容器 layout 实例化
- }WidgetType;//ui 类型
- typedef enum
- {
- UI_TEX_TYPE_LOCAL = 0,//means local file
- UI_TEX_TYPE_PLIST = 1// means sprite frame
- }TextureResType;//贴图类型
- enum class TouchEventType
- {
- TOUCH_EVENT_BEGAN,//開始
- TOUCH_EVENT_MOVED,//移动
- TOUCH_EVENT_ENDED,//结束
- TOUCH_EVENT_CANCELED//取消
- };//触摸事件类型
- typedef enum
- {
- SIZE_ABSOLUTE,//绝对值
- SIZE_PERCENT//百分比值
- }SizeType;//size值类型
- typedef enum
- {
- POSITION_ABSOLUTE,//绝对 真实位置
- POSITION_PERCENT//相对父节点位置百分比
- }PositionType;//位置类型
- typedef enum
- {
- WIDGET_SIZE,//size
- WIDGET_POSITION//position
- }WidgetInfoType;//位置类型
- //哦 这里说明一下 回调函数被我改动了下 主要是这样改动之后能够用到C++11的lambda表达式
- //不必在使用的时候多声明一个回调函数了 比較方便 希望引擎组能够採用这样的方式。
- typedef std::function<void(Ref*,TouchEventType)> SEL_TouchEvent;
- //函数指针 指向 返回值 void 參数列表(Ref*,TouchEventType) 类型的函数
- //typedef void (Ref::*SEL_TouchEvent)(Ref*,TouchEventType);
- //宏定义 给函数指针SEL_TouchEvent取别名为toucheventselector
- #define toucheventselector(_SELECTOR) (SEL_TouchEvent)(&_SELECTOR)
- class Widget : public ProtectedNode
- {
- public:
- Widget(void);
- virtual ~Widget();
- static Widget* create();
- /**设置 是否 触摸&&可见 默认true*/
- virtual void setEnabled(bool enabled);
- bool isEnabled() const;
- /**设置是否明亮 默认true*/
- void setBright(bool bright);
- /**是否明亮*/
- bool isBright() const;
- /**能否够触摸(响应事件)默认true*/
- virtual void setTouchEnabled(bool enabled);
- /**设置明亮风格 正常 or 明亮 默认正常*/
- void setBrightStyle(BrightStyle style);
- /**能否够触摸*/
- bool isTouchEnabled() const;
- /**是否被选中 默认false*/
- bool isFocused() const;
- /**是否被选中 默认false*/
- void setFocused(bool fucosed);
- /**获取此控件距离左节点的下边界长度*/
- float getLeftInParent();
- /**获取此控件距离父节点的下边界长度*/
- float getBottomInParent();
- /**获取此控件距离父节点的右边界长度*/
- float getRightInParent();
- /**获取此控件距离父节点的上边界长度*/
- float getTopInParent();
- /**获取一个孩子从容器依据它的名字*/
- virtual Widget* getChildByName(const char* name);
- /**渲染重载*/
- virtual void visit(cocos2d::Renderer *renderer, const kmMat4 &parentTransform, bool parentTransformUpdated) override;
- /**加入回调事件*/
- void addTouchEventListener(SEL_TouchEvent selector);
- /**打印属性 debug*/
- virtual void logInfo(WidgetInfoType _type);
- //cocos2d 属性
- /**
- 基类有的函数为virtual 有的不是
- 不带virtual 的是全部子类都拥有这个函数的功能。
- 带virtual 的是拥有上述功能之外 重载父类的函数 想拓展功能用的。
- 带virtual 的函数能够使用多态 即父类指针指向子类成员
- */
- /**
- *更改在OpenGL坐标系中widget的位置(X,Y)
- *原来的点(0,0)是在屏幕的左下角。
- *@參数位置在OpenGL坐标widget的位置(X,Y)
- */
- virtual void setPosition(const Point &pos) override;
- /**同上绝对位置变为百分比*/
- void setPositionPercent(const Point &percent);
- /**得到在OpenGL坐标系中widget的百分比位置(X,Y)*/
- const Point& getPositionPercent();
- /**设置位置类型*/
- void setPositionType(PositionType type);
- /**得到位置类型*/
- PositionType getPositionType() const;
- /**设置该widget是否水平翻转*/
- virtual void setFlippedX(bool flippedX);
- /**该widget是否水平翻转*/
- virtual bool isFlippedX(){return _flippedX;};
- /**该widget是否垂直翻转*/
- virtual void setFlippedY(bool flippedY);
- /**该widget是否垂直翻转*/
- virtual bool isFlippedY(){return _flippedY;};
- /**设置颜色*/
- virtual void setColor(const Color3B& color) override;
- /**设置透明度*/
- virtual void setOpacity(GLubyte opacity) override;
- /**得到颜色值*/
- const Color3B& getColor() const override {return _color;};
- /**得到透明度*/
- GLubyte getOpacity() const override {return _opacity;};
- /**弃用的属性*/
- /** @deprecated Use isFlippedX() instead */
- CC_DEPRECATED_ATTRIBUTE bool isFlipX() { return isFlippedX(); };
- /** @deprecated Use setFlippedX() instead */
- CC_DEPRECATED_ATTRIBUTE void setFlipX(bool flipX) { setFlippedX(flipX); };
- /** @deprecated Use isFlippedY() instead */
- CC_DEPRECATED_ATTRIBUTE bool isFlipY() { return isFlippedY(); };
- /** @deprecated Use setFlippedY() instead */
- CC_DEPRECATED_ATTRIBUTE void setFlipY(bool flipY) { setFlippedY(flipY); };
- /**当该widget失去焦点会调用*/
- void didNotSelectSelf();
- /**检查一个点是否在父节点区域*/
- bool clippingParentAreaContainPoint(const Point &pt);
- /** 发送触摸事件到widget的父节点*/
- virtual void checkChildInfo(int handleState,Widget* sender,const Point &touchPoint);
- /** Gets the touch began point of widget when widget is selected.*/
- const Point& getTouchStartPos();
- /** Gets the touch move point of widget when widget is selected*/
- const Point& getTouchMovePos();
- /** Gets the touch end point of widget when widget is selected.*/
- const Point& getTouchEndPos();
- /**设置name*/
- void setName(const char* name);
- /**得到name*/
- const char* getName() const;
- /**得到控件类型*/
- WidgetType getWidgetType() const;
- /**设置控件大小*/
- virtual void setSize(const Size &size);
- virtual void setSizeW(const int &sizeW);
- virtual void setSizeH(const int &sizeH);
- /**设置size百分比*/
- virtual void setSizePercent(const Point &percent);
- /**size类型*/
- void setSizeType(SizeType type);
- /**得到size类型*/
- SizeType getSizeType() const;
- /**得到size*/
- const Size& getSize() const;
- /**得到Customsize*/
- const Size& getCustomSize() const;
- /**得到layout size*/
- virtual const Size& getLayoutSize() {return _size;};//虚函数 供子类重写?
- /**得到size百分比*/
- const Point& getSizePercent() const;
- /***/
- virtual bool hitTest(const Point &pt);
- /**触摸事件*/
- virtual bool onTouchBegan(Touch *touch, Event *unusedEvent);
- virtual void onTouchMoved(Touch *touch, Event *unusedEvent);
- virtual void onTouchEnded(Touch *touch, Event *unusedEvent);
- virtual void onTouchCancelled(Touch *touch, Event *unusedEvent);
- /**设置布局參数*/
- void setLayoutParameter(LayoutParameter* parameter);
- /**得到布局參数*/
- LayoutParameter* getLayoutParameter(LayoutParameterType type);
- /**是否忽略size使用texture size 默认true*/
- virtual void ignoreContentAdaptWithSize(bool ignore);
- /**是否忽略size使用texture size*/
- bool isIgnoreContentAdaptWithSize() const;
- /**得到世界位置*/
- Point getWorldPosition();
- /**得到虚拟渲染器 比如 一个button的虚拟渲染器是他的 texture renderer 贴图渲染器*/
- virtual Node* getVirtualRenderer();
- /**得到虚拟渲染器的size 默认是_contentSize 不同的子类有自己的重载*/
- virtual const Size& getVirtualRendererSize() const;
- /**
- * 得到改控件相应的"class name".
- */
- virtual std::string getDescription() const override;
- /**克隆替身*/
- Widget* clone();
- virtual void onEnter() override;
- virtual void onExit() override;
- /**更新size和position*/
- void updateSizeAndPosition();
- void updateSizeAndPosition(const Size& parentSize);
- /*temp action*/
- void setActionTag(int tag);
- int getActionTag();
- CC_CONSTRUCTOR_ACCESS:
- //initializes state of widget.
- virtual bool init() override;
- protected:
- //call back function called when size changed.
- virtual void onSizeChanged();
- //initializes renderer of widget.
- virtual void initRenderer();
- //回复正常调用.
- virtual void onPressStateChangedToNormal();
- //选中会调用
- virtual void onPressStateChangedToPressed();
- //变暗会调用
- virtual void onPressStateChangedToDisabled();
- //不同的事件
- void pushDownEvent();
- void moveEvent();
- void releaseUpEvent();
- void cancelUpEvent();
- //空的虚函数为了多态
- virtual void updateTextureColor(){};
- virtual void updateTextureOpacity(){};
- virtual void updateTextureRGBA(){};
- virtual void updateFlippedX(){};
- virtual void updateFlippedY(){};
- void updateColorToRenderer(Node* renderer);
- void updateOpacityToRenderer(Node* renderer);
- void updateRGBAToRenderer(Node* renderer);
- void copyProperties(Widget* model);
- virtual Widget* createCloneInstance();
- virtual void copySpecialProperties(Widget* model);
- virtual void copyClonedWidgetChildren(Widget* model);
- Widget* getWidgetParent();
- void updateContentSizeWithTextureSize(const Size& size);
- /**多态 适用于全部的子类重载 实现自己的逻辑*/
- virtual void adaptRenderers(){};
- protected:
- bool _enabled; ///< 是否可见&&可触摸 最高属性
- bool _bright; ///< 是否光亮
- bool _touchEnabled; ///< 是否响应触摸
- bool _touchPassedEnabled; ///< 触摸时间是不是按下
- bool _focus; ///< 是不是焦点
- BrightStyle _brightStyle; ///< 明亮风格
- Point _touchStartPos; ///< touch began point
- Point _touchMovePos; ///< touch moved point
- Point _touchEndPos; ///< touch ended point
- SEL_TouchEvent _touchEventSelector;///回调函数类型
- std::string _name;///类名
- WidgetType _widgetType;///控件类型
- int _actionTag;///运行动作的tag
- Size _size;///untransformed size
- Size _customSize;///自己定义size
- bool _ignoreSize;///是否忽略自己定义的大小 而取资源原本的大小 untransformed img size 默认_size = _customSize
- bool _affectByClipping;
- SizeType _sizeType;///size 类型
- Point _sizePercent;///相对父节点size百分比
- PositionType _positionType;///位置类型
- Point _positionPercent;///相对父节点的位置百分比
- bool _reorderWidgetChildDirty;
- bool _hitted;
- EventListenerTouchOneByOne* _touchListener;///单点触摸
- Color3B _color;///颜色值
- GLubyte _opacity;///透明度
- bool _flippedX;//是否镜像X轴
- bool _flippedY;//是否镜像Y轴
- Map<int, LayoutParameter*> _layoutParameterDictionary;//布局參数Map
- };
- }
- NS_CC_END
- #endif /* defined(__Widget__) */
- /****************************************************************************
- Copyright (c) 2013-2014 Chukong Technologies Inc.
- http://www.cocos2d-x.org
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
- ****************************************************************************/
- #include "ui/UIWidget.h"
- #include "ui/UILayout.h"
- #include "ui/UIHelper.h"
- NS_CC_BEGIN
- namespace ui {
- Widget::Widget():
- _enabled(true),
- _bright(true),
- _touchEnabled(false),
- _touchPassedEnabled(false),
- _focus(false),
- _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(false),
- _affectByClipping(false),
- _sizeType(SIZE_ABSOLUTE),
- _sizePercent(Point::ZERO),
- _positionType(POSITION_ABSOLUTE),
- _positionPercent(Point::ZERO),
- _reorderWidgetChildDirty(true),
- _hitted(false),
- _touchListener(nullptr),
- _color(Color3B::WHITE),
- _opacity(255),
- _flippedX(false),
- _flippedY(false)
- {
- }
- Widget::~Widget()
- {
- _touchEventSelector = nullptr;
- setTouchEnabled(false);
- }
- Widget* Widget::create()
- {
- Widget* widget = new Widget();
- if (widget && widget->init())
- {
- widget->autorelease();
- return widget;
- }
- CC_SAFE_DELETE(widget);
- return nullptr;
- }
- bool Widget::init()
- {
- if (ProtectedNode::init())
- {
- initRenderer();//初始化渲染器 多态
- setBright(true);//设置明亮
- ignoreContentAdaptWithSize(true);//默认 内容不适应size大小
- setAnchorPoint(Point(0.5f, 0.5f));//默认 锚点在中心
- return true;
- }
- return false;
- }
- void Widget::onEnter()
- {
- updateSizeAndPosition();
- ProtectedNode::onEnter();
- }
- void Widget::onExit()
- {
- unscheduleUpdate();
- ProtectedNode::onExit();
- }
- void Widget::visit(Renderer *renderer, const kmMat4 &parentTransform, bool parentTransformUpdated)
- {
- if (_enabled)
- {
- adaptRenderers();
- ProtectedNode::visit(renderer, parentTransform, parentTransformUpdated);
- }
- }
- Widget* Widget::getWidgetParent()
- {
- //得到父节点
- return dynamic_cast<Widget*>(getParent());
- }
- void Widget::setEnabled(bool enabled)
- {
- _enabled = enabled;
- for (auto& child : _children)
- {
- if (child)
- {
- Widget* widgetChild = dynamic_cast<Widget*>(child);
- if (widgetChild)
- {
- widgetChild->setEnabled(enabled);
- }
- }
- }
- for (auto& child : _protectedChildren)
- {
- if (child)
- {
- Widget* widgetChild = dynamic_cast<Widget*>(child);
- if (widgetChild)
- {
- widgetChild->setEnabled(enabled);
- }
- }
- }
- }
- Widget* Widget::getChildByName(const char *name)
- {
- for (auto& child : _children)
- {
- if (child)
- {
- Widget* widgetChild = dynamic_cast<Widget*>(child);
- if (widgetChild)
- {
- if (strcmp(widgetChild->getName(), name) == 0)
- {
- return widgetChild;
- }
- }
- }
- }
- return nullptr;
- }
- void Widget::initRenderer()
- {
- //多态 不同的控件有自己的初始化渲染方式
- }
- void Widget::setSizeW(const int &sizeW)
- {
- _customSize.width = sizeW;
- if (_ignoreSize)
- {
- _size = getVirtualRendererSize();
- }
- else
- {
- _size.width = sizeW;
- }
- if (_running)
- {
- Widget* widgetParent = getWidgetParent();
- Size pSize;
- if (widgetParent)
- {
- pSize = widgetParent->getSize();
- }
- else
- {
- pSize = _parent->getContentSize();
- }
- float spx = 0.0f;
- float spy = 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();
- }
- void Widget::setSizeH(const int &sizeH)
- {
- _customSize.height = sizeH;
- if (_ignoreSize)
- {
- _size = getVirtualRendererSize();
- }
- else
- {
- _size.height = sizeH;
- }
- if (_running)
- {
- Widget* widgetParent = getWidgetParent();
- Size pSize;
- if (widgetParent)
- {
- pSize = widgetParent->getSize();
- }
- else
- {
- pSize = _parent->getContentSize();
- }
- float spx = 0.0f;
- float spy = 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();
- }
- void Widget::setSize(const Size &size)
- {
- _customSize = size;
- if (_ignoreSize)
- {
- _size = getVirtualRendererSize();
- }
- else
- {
- _size = size;
- }
- if (_running)
- {
- Widget* widgetParent = getWidgetParent();
- Size pSize;
- if (widgetParent)
- {
- pSize = widgetParent->getSize();
- }
- else
- {
- pSize = _parent->getContentSize();
- }
- float spx = 0.0f;
- float spy = 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();
- }
- void Widget::setSizePercent(const Point &percent)
- {
- _sizePercent = percent;
- Size cSize = _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);
- }
- }
- if (_ignoreSize)
- {
- _size = getVirtualRendererSize();
- }
- else
- {
- _size = cSize;
- }
- _customSize = cSize;
- onSizeChanged();
- }
- void Widget::updateSizeAndPosition()
- {
- Widget* widgetParent = getWidgetParent();
- Size pSize;
- if (widgetParent)
- {//假设有父节点是控件基类widget 保存父节点的容器大小
- pSize = widgetParent->getLayoutSize();
- }
- else
- {//假设父节点不是控件基类widget 得到绑定贴图大小
- pSize = _parent->getContentSize();
- }
- updateSizeAndPosition(pSize);
- }
- void Widget::updateSizeAndPosition(const cocos2d::Size &parentSize)
- {
- switch (_sizeType)
- {
- case SIZE_ABSOLUTE://绝对大小 真实大小
- {
- if (_ignoreSize)//忽略设置的大小
- {
- _size = getVirtualRendererSize();//size取untransformed img size
- }
- else//不忽略自己定义大小
- {
- _size = _customSize;//size 取自己定义大小
- }
- float spx = 0.0f;
- float spy = 0.0f;
- 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;
- }
- case SIZE_PERCENT://百分比size
- {
- Size cSize = Size(parentSize.width * _sizePercent.x , parentSize.height * _sizePercent.y);//计算得到自己定义大小
- if (_ignoreSize)//忽略设置的大小
- {
- _size = getVirtualRendererSize();//size取untransformed img size
- }
- else//不忽略自己定义大小
- {
- _size = cSize;//size 取 计算得到自己定义大小
- }
- _customSize = cSize;//计算得到自己定义大小
- break;
- }
- default:
- break;
- }
- onSizeChanged();
- Point absPos = getPosition();
- switch (_positionType)
- {
- case POSITION_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;
- }
- case POSITION_PERCENT://相对位置
- {
- absPos = Point(parentSize.width * _positionPercent.x, parentSize.height * _positionPercent.y);//得到真实位置
- break;
- }
- default:
- break;
- }
- setPosition(absPos);//更新真实位置
- }
- void Widget::setSizeType(SizeType type)
- {
- _sizeType = type;//设置size类型
- }
- SizeType Widget::getSizeType() const//返回值不可改
- {
- return _sizeType;//得到size type 返回值不可改
- }
- void Widget::ignoreContentAdaptWithSize(bool ignore)
- {
- if (_ignoreSize == ignore)
- {
- return;//和当前值一样 不是必需更新处理了 直接返回
- }
- _ignoreSize = ignore;
- if (_ignoreSize)//忽略自己定义size
- {
- Size s = getVirtualRendererSize();//取原本大小的size
- _size = s;
- }
- else//不忽略自己定义size
- {
- _size = _customSize;//取自己定义size
- }
- onSizeChanged();//更新size
- }
- bool Widget::isIgnoreContentAdaptWithSize() const
- {
- return _ignoreSize;
- }
- const Size& Widget::getSize() const
- {
- return _size;
- }
- const Size& Widget::getCustomSize() const
- {
- return _customSize;
- }
- const Point& Widget::getSizePercent() const
- {
- return _sizePercent;
- }
- Point Widget::getWorldPosition()
- {
- return convertToWorldSpace(Point(_anchorPoint.x * _contentSize.width, _anchorPoint.y * _contentSize.height));//得到世界坐标
- }
- Node* Widget::getVirtualRenderer()
- {
- return this;//得到虚拟渲染器 默认是自己 不同的子类有自己的重载
- }
- void Widget::onSizeChanged()
- {
- setContentSize(_size);//设置 untransformed size
- for (auto& child : getChildren())
- {
- Widget* widgetChild = dynamic_cast<Widget*>(child);
- if (widgetChild)
- {
- widgetChild->updateSizeAndPosition();//递归更新全部子节点size position
- }
- }
- }
- const Size& Widget::getVirtualRendererSize() const
- {
- return _contentSize;//得到虚拟渲染器zise 默认是_contentSize 不同的子类有自己的重载
- }
- void Widget::updateContentSizeWithTextureSize(const cocos2d::Size &size)
- {
- if (_ignoreSize)
- {
- _size = size;
- }
- else
- {
- _size = _customSize;
- }
- onSizeChanged();
- }
- void Widget::setTouchEnabled(bool enable)
- {
- if (enable == _touchEnabled)
- {
- return;
- }
- _touchEnabled = enable;
- if (_touchEnabled)//假设开启触摸
- {
- _touchListener = EventListenerTouchOneByOne::create();
- CC_SAFE_RETAIN(_touchListener);//创建单点触摸
- _touchListener->setSwallowTouches(true);//不向下触摸,简单点来说,比方有两个sprite ,A 和B,A在上B在下(位置重叠),触摸A的时候,B不会受到影响
- //绑定四个回调函数
- _touchListener->onTouchBegan = CC_CALLBACK_2(Widget::onTouchBegan, this);
- _touchListener->onTouchMoved = CC_CALLBACK_2(Widget::onTouchMoved, this);
- _touchListener->onTouchEnded = CC_CALLBACK_2(Widget::onTouchEnded, this);
- _touchListener->onTouchCancelled = CC_CALLBACK_2(Widget::onTouchCancelled, this);
- _eventDispatcher->addEventListenerWithSceneGraphPriority(_touchListener, this);
- }
- else //假设不开启触摸
- {
- _eventDispatcher->removeEventListener(_touchListener);//移除
- CC_SAFE_RELEASE_NULL(_touchListener);//释放
- }
- }
- bool Widget::isTouchEnabled() const
- {
- return _touchEnabled;
- }
- bool Widget::isFocused() const
- {
- return _focus;
- }
- void Widget::setFocused(bool fucos)
- {
- if (fucos == _focus)
- {
- return;
- }
- _focus = fucos;
- if (_bright)//假设亮
- {
- if (_focus)//假设选中
- {
- setBrightStyle(BRIGHT_HIGHLIGHT);//高亮
- }
- else//假设没有选中
- {
- setBrightStyle(BRIGHT_NORMAL);//正常
- }
- }
- else//假设不亮
- {
- onPressStateChangedToDisabled();//变暗
- }
- }
- void Widget::setBright(bool bright)
- {
- _bright = bright;
- if (_bright)//假设亮
- {
- _brightStyle = BRIGHT_NONE;
- setBrightStyle(BRIGHT_NORMAL);//正常亮
- }
- else//假设不亮
- {
- onPressStateChangedToDisabled();//变暗
- }
- }
- void Widget::setBrightStyle(BrightStyle style)
- {
- if (_brightStyle == style)
- {
- return;
- }
- _brightStyle = style;
- switch (_brightStyle)
- {
- case BRIGHT_NORMAL:
- onPressStateChangedToNormal();
- break;
- case BRIGHT_HIGHLIGHT:
- onPressStateChangedToPressed();
- break;
- default:
- break;
- }
- }
- void Widget::onPressStateChangedToNormal()
- {
- }
- void Widget::onPressStateChangedToPressed()
- {
- }
- void Widget::onPressStateChangedToDisabled()
- {
- }
- void Widget::didNotSelectSelf()
- {
- }
- void Widget::logInfo(WidgetInfoType _type)
- {
- log("widget anchor x = %f,y = %f",getAnchorPoint().x,getAnchorPoint().y);
- if (_type == WIDGET_SIZE) {
- log("widget size width = %f,height = %f",_size.width,_size.height);
- }
- if (_type == WIDGET_POSITION) {
- log("widget position x = %f,y = %f",getPositionX(),getPositionY());
- }
- }
- bool Widget::onTouchBegan(Touch *touch, Event *unusedEvent)
- {
- _hitted = false;//刚開始触摸 没有碰到
- if (isEnabled() && isTouchEnabled())//节点能够使用 能够点击
- {
- _touchStartPos = touch->getLocation();//得到点击位置
- //触摸点在到图像区域 而且 触摸点在裁切区域
- if(hitTest(_touchStartPos) && clippingParentAreaContainPoint(_touchStartPos))
- {
- _hitted = true;//触摸到了
- }
- }
- if (!_hitted)//没有触摸到
- {
- return false;//停止
- }
- setFocused(true);//得到焦点
- Widget* widgetParent = getWidgetParent();
- if (widgetParent)//有父节点
- {
- widgetParent->checkChildInfo(0,this,_touchStartPos);//检查孩子属性
- }
- pushDownEvent();//按下回调响应
- return !_touchPassedEnabled;
- }
- void Widget::onTouchMoved(Touch *touch, Event *unusedEvent)
- {
- _touchMovePos = touch->getLocation();
- setFocused(hitTest(_touchMovePos));
- Widget* widgetParent = getWidgetParent();
- if (widgetParent)
- {
- widgetParent->checkChildInfo(1,this,_touchMovePos);
- }
- moveEvent();
- }
- void Widget::onTouchEnded(Touch *touch, Event *unusedEvent)
- {
- _touchEndPos = touch->getLocation();
- bool focus = _focus;
- setFocused(false);
- Widget* widgetParent = getWidgetParent();
- if (widgetParent)
- {
- widgetParent->checkChildInfo(2,this,_touchEndPos);
- }
- if (focus)
- {
- releaseUpEvent();
- }
- else
- {
- cancelUpEvent();
- }
- }
- void Widget::onTouchCancelled(Touch *touch, Event *unusedEvent)
- {
- setFocused(false);
- cancelUpEvent();
- }
- void Widget::pushDownEvent()
- {
- if ( _touchEventSelector)
- {
- // ( ->*_touchEventSelector)(this,TouchEventType::TOUCH_EVENT_BEGAN);//响应開始按下的回调
- _touchEventSelector(this,TouchEventType::TOUCH_EVENT_BEGAN);//响应開始按下的回调
- }
- }
- void Widget::moveEvent()
- {
- if ( _touchEventSelector)
- {
- // ( ->*_touchEventSelector)(this,TouchEventType::TOUCH_EVENT_MOVED);//响应移动的回调
- _touchEventSelector(this,TouchEventType::TOUCH_EVENT_MOVED);//响应移动的回调
- }
- }
- void Widget::releaseUpEvent()
- {
- if ( _touchEventSelector)
- {
- // ( ->*_touchEventSelector)(this,TouchEventType::TOUCH_EVENT_ENDED);//响应结束的回调
- _touchEventSelector(this,TouchEventType::TOUCH_EVENT_ENDED);//响应结束的回调
- }
- }
- void Widget::cancelUpEvent()
- {
- if ( _touchEventSelector)
- {
- _touchEventSelector(this,TouchEventType::TOUCH_EVENT_CANCELED);//响应取消按下的回调
- // ( ->*_touchEventSelector)(this,TouchEventType::TOUCH_EVENT_CANCELED);//响应取消按下的回调
- }
- }
- //共外部注冊回调
- void Widget::addTouchEventListener( SEL_TouchEvent selector)
- {
- _touchEventSelector = selector;
- }
- bool Widget::hitTest(const Point &pt)
- {
- Point nsp = convertToNodeSpace(pt);//相对this的点
- Rect bb;
- bb.size = _contentSize;
- if (bb.containsPoint(nsp))
- {
- return true;//点在size内 hit ~!
- }
- return false;
- }
- bool Widget::clippingParentAreaContainPoint(const Point &pt)
- {
- _affectByClipping = false;
- Widget* parent = getWidgetParent();
- Widget* clippingParent = nullptr;
- while (parent)//有父节点
- {
- Layout* layoutParent = dynamic_cast<Layout*>(parent);
- if (layoutParent)//父节点是层容器
- {
- if (layoutParent->isClippingEnabled())//父节点是能够裁切的
- {
- _affectByClipping = true;//受裁切的影响
- clippingParent = layoutParent;//取到已经裁切的父节点
- break;//跳出循环
- }
- }
- parent = parent->getWidgetParent();//向上遍历父节点
- }
- if (!_affectByClipping)//没有能够裁切的层容器
- {
- return true;
- }
- if (clippingParent)//存在裁切的父节点
- {
- bool bRet = false;
- if (clippingParent->hitTest(pt))//点在裁切裁切范围内
- {
- bRet = true;
- }
- if (bRet)
- {
- return clippingParent->clippingParentAreaContainPoint(pt);//递归裁切父节点
- }
- return false;
- }
- return true;
- }
- void Widget::checkChildInfo(int handleState, Widget *sender, const Point &touchPoint)
- {
- Widget* widgetParent = getWidgetParent();
- if (widgetParent)
- {
- widgetParent->checkChildInfo(handleState,sender,touchPoint);//递归检查孩子的info
- }
- }
- void Widget::setPosition(const Point &pos)
- {
- if (_running)//若在执行状态
- {
- Widget* widgetParent = getWidgetParent();
- if (widgetParent)//若有父节点
- {
- Size pSize = 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);
- }
- void Widget::setPositionPercent(const Point &percent)
- {
- _positionPercent = percent;
- if (_running)
- {
- Widget* widgetParent = getWidgetParent();
- if (widgetParent)
- {
- Size parentSize = widgetParent->getSize();
- Point absPos = Point(parentSize.width * _positionPercent.x, parentSize.height * _positionPercent.y);//绝对坐标
- setPosition(absPos);
- }
- }
- }
- const Point& Widget::getPositionPercent()
- {
- return _positionPercent;
- }
- void Widget::setPositionType(PositionType type)
- {
- _positionType = type;
- }
- PositionType Widget::getPositionType() const
- {
- return _positionType;
- }
- bool Widget::isBright() const
- {
- return _bright;
- }
- bool Widget::isEnabled() const
- {
- return _enabled;
- }
- float Widget::getLeftInParent()
- {
- return getPosition().x - getAnchorPoint().x * _size.width;;
- }
- //得到距离父节点底部的距离
- float Widget::getBottomInParent()
- {
- return getPosition().y - getAnchorPoint().y * _size.height;;
- }
- float Widget::getRightInParent()
- {
- return getLeftInParent() + _size.width;
- }
- float Widget::getTopInParent()
- {
- return getBottomInParent() + _size.height;
- }
- const Point& Widget::getTouchStartPos()
- {
- return _touchStartPos;
- }
- const Point& Widget::getTouchMovePos()
- {
- return _touchMovePos;
- }
- const Point& Widget::getTouchEndPos()
- {
- return _touchEndPos;
- }
- void Widget::setName(const char* name)
- {
- _name = name;
- }
- const char* Widget::getName() const
- {
- return _name.c_str();
- }
- WidgetType Widget::getWidgetType() const
- {
- return _widgetType;
- }
- //设置布局參数
- void Widget::setLayoutParameter(LayoutParameter *parameter)
- {
- if (!parameter)
- {
- return;
- }
- _layoutParameterDictionary.insert(parameter->getLayoutType(), parameter);
- }
- //得到全部布局參数
- LayoutParameter* Widget::getLayoutParameter(LayoutParameterType type)
- {
- return dynamic_cast<LayoutParameter*>(_layoutParameterDictionary.at(type));
- }
- std::string Widget::getDescription() const
- {
- return "Widget";
- }
- //克隆
- Widget* Widget::clone()
- {
- Widget* clonedWidget = createCloneInstance();
- clonedWidget->copyProperties(this);//拷贝基础属性
- clonedWidget->copyClonedWidgetChildren(this);//拷贝全部孩子
- return clonedWidget;
- }
- Widget* Widget::createCloneInstance()
- {
- return Widget::create();
- }
- void Widget::copyClonedWidgetChildren(Widget* model)
- {
- //引用类型auto&
- auto& modelChildren = model->getChildren();
- for (auto& subWidget : modelChildren)
- {
- Widget* child = dynamic_cast<Widget*>(subWidget);
- if (child)
- {
- addChild(child->clone());
- }
- }
- }
- void Widget::copySpecialProperties(Widget* model)
- {
- }
- //拷贝属性
- void Widget::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<int, LayoutParameter*>& layoutParameterDic = widget->_layoutParameterDictionary;
- for (auto iter = layoutParameterDic.begin(); iter != layoutParameterDic.end(); ++iter)
- {
- setLayoutParameter(iter->second->clone());
- }
- onSizeChanged();
- }
- void Widget::setColor(const Color3B& color)
- {
- _color = color;
- updateTextureColor();
- }
- void Widget::setOpacity(GLubyte opacity)
- {
- _opacity = opacity;
- updateTextureOpacity();
- }
- void Widget::setFlippedX(bool flippedX)
- {
- _flippedX = flippedX;
- updateFlippedX();
- }
- void Widget::setFlippedY(bool flippedY)
- {
- _flippedY = flippedY;
- updateFlippedY();
- }
- void Widget::updateColorToRenderer(Node* renderer)
- {
- renderer->setColor(_color);
- }
- void Widget::updateOpacityToRenderer(Node* renderer)
- {
- renderer->setOpacity(_opacity);
- }
- void Widget::updateRGBAToRenderer(Node* renderer)
- {
- renderer->setColor(_color);
- renderer->setOpacity(_opacity);
- }
- /*temp action*/
- void Widget::setActionTag(int tag)
- {
- _actionTag = tag;
- }
- int Widget::getActionTag()
- {
- return _actionTag;
- }
- }
- NS_CC_END
【Cocos2d-x】源代码分析之 2d/ui/Widget的更多相关文章
- jquery ui widget 源代码分析
jquery ui 的全部组件都是基于一个简单,可重用的widget. 这个widget是jquery ui的核心部分,有用它能实现一致的API.创建有状态的插件,而无需关心插件的内部转换. $.wi ...
- Android应用Activity、Dialog、PopWindow、Toast窗体加入机制及源代码分析
[工匠若水 http://blog.csdn.net/yanbober 转载烦请注明出处.尊重劳动成果] 1 背景 之所以写这一篇博客的原因是由于之前有写过一篇<Android应用setCont ...
- UiAutomator源代码分析之UiAutomatorBridge框架
上一篇文章<UIAutomator源代码分析之启动和执行>我们描写叙述了uitautomator从命令行执行到载入測试用例执行測试的整个流程.过程中我们也描写叙述了UiAutomatorB ...
- 【Android开源项目分析】android轻量级开源缓存框架——ASimpleCache(ACache)源代码分析
转载请注明出处:http://blog.csdn.net/zhoubin1992/article/details/46379055 ASimpleCache框架源代码链接 https://github ...
- Robotium原则的实施源代码分析
从前面的章节<Robotium源代码分析之Instrumentation进阶>中我们了解到了Robotium所基于的Instrumentation的一些进阶基础.比方它注入事件的原理等,但 ...
- LIRe 源代码分析 3:基本接口(ImageSearcher)
===================================================== LIRe源代码分析系列文章列表: LIRe 源代码分析 1:整体结构 LIRe 源代码分析 ...
- Android HandlerThread 源代码分析
HandlerThread 简单介绍: 我们知道Thread线程是一次性消费品,当Thread线程运行完一个耗时的任务之后.线程就会被自己主动销毁了.假设此时我又有一 个耗时任务须要运行,我们不得不又 ...
- Cocos2d-x 源代码分析 : Scheduler(定时器) 源代码分析
源代码版本号 3.1r,转载请注明 我也最终不out了,開始看3.x的源代码了.此时此刻的心情仅仅能是wtf! !!!!!!! !.只是也最终告别CC时代了. cocos2d-x 源代码分析文件夹 h ...
- Eclipse源代码分析
Eclipse源代码分析 一.概述走入Eclipse的内核,看看它到底是怎么工作的? 1.Eclipse源代码 下载地址:http://download.eclipse.org/eclipse/dow ...
随机推荐
- iPhone开发【一】从HelloWorld開始
转载请注明出处,原文网址:http://blog.csdn.net/m_changgong/article/details/8013553 作者:张燕广 从经典的HelloWorld開始踏入iPhon ...
- Android获取设备採用的时间制式(12小时制式或24小时制式)
/** * 获取设备採用的时间制式(12小时制式或者24小时制式) * 注意: * 在模拟器上获取的时间制式为空 */ private void getTime_12_24(Context conte ...
- VMwave下Ubuntu扩展磁盘空间
VMwave下Ubuntu扩展磁盘空间 Ubuntu原预装磁盘空间20G,随着系统安装软件越来越多,空间慢慢不够用. 打算安装DB2,许扩展磁盘空间. 环境: No LSB modules are a ...
- Android实战开发租赁管理软件(适配UI,数据的存储,多线程下载)课程分享
亲爱的网友,我这里有套课程想和大家分享,假设对这个课程有兴趣的,能够加我的QQ2059055336和我联系. 课程内容简单介绍 我们软件是基于移动设备的.所以我们必定的选择了安卓作为我们的开发工具.课 ...
- AFNetworking2.0后 进行Post请求
本文以新浪微博的Oauth认证为样例进行Post请求的演示 以下直接上代码: #import "ViewController.h" #import "AFNetworki ...
- Delphi过程函数传递参数的八种方式
今天一同事问我为什么有些过程函数里面有Var而有些没有,不解,遂到网上百度,得解.快哉,快哉. 在Delphi过程.函数中传递参数几个修饰符为Const.Var.Out.另一种不加修饰符的为默认按值传 ...
- JavaScript实战
JavaScript之单例实战 一.概述 所谓单例模式,顾名思义即一个类只有一个实例. 所以,当我们创建一个实例时,就必须判断其是否已经存在了这个实例,如果已经存在了这个实例,那么就返回这个已经存在的 ...
- Spark简述及基本架构
Spark简述 Spark发源于美国加州大学伯克利分校AMPLab的集群计算平台.它立足 于内存计算.从多迭代批量处理出发,兼收并蓄数据仓库.流处理和图计算等多种计算范式. 特点: 1.轻 Spark ...
- oracle 之 内存—鞭辟近里(一)
oracle 之 内存—鞭辟近里(一) 今天是2013-07-8日,这几天一直都在寻找一本深入研究oracle内存的书籍,期间一波三折弄的自己神魂颠倒,但是还是被我拿下了,感谢支持我的朋友,这周打算把 ...
- Anyterm - Introduction
Anyterm - Introduction Anyterm