日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發布時間:2025/1/21 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【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_BEGINnamespace 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 fileUI_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,//sizeWIDGET_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 pointPoint _touchMovePos; ///< touch moved pointPoint _touchEndPos; ///< touch ended pointSEL_TouchEvent _touchEventSelector;///回調函數類型std::string _name;///類名WidgetType _widgetType;///控件類型int _actionTag;///運行動作的tagSize _size;///untransformed sizeSize _customSize;///自己定義sizebool _ignoreSize;///是否忽略自己定義的大小 而取資源原本的大小 untransformed img size 默認_size = _customSizebool _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.orgPermission 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_BEGINnamespace 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 sizefor (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的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 国产精品短视频 | 香蕉视频污在线观看 | 午夜伦伦 | 午夜精品福利视频 | 欧美日韩小说 | 毛茸茸free性熟hd | 男女偷爱性视频刺激 | 久久久久久不卡 | 成人h视频在线 | 国产精品无码AV无码国产 | 国产成人精品一区二区三区免费 | 2019年中文字幕 | 欧美成人精品一区二区男人小说 | 狠狠干老司机 | 色先锋av| 丁香婷婷激情五月 | 日韩在线免费视频观看 | 国产日韩欧美视频在线观看 | 国产免费av一区二区 | 日韩国产三级 | 青青操青青 | 久久久久久久久久影视 | 欧美在线性爱视频 | 精品123区| 射进来av影视网 | 久久99精品久久久水蜜桃 | 精品偷拍一区 | 总裁憋尿呻吟双腿大开憋尿 | 国产精品日韩精品欧美精品 | 亚洲成人av一区二区三区 | 狠狠干伊人网 | 欧美在线一二 | 欧州一区二区三区 | 日本a级大片| 国产午夜福利视频在线观看 | 欧美日本一道 | 欧美三极片 | 欧美午夜精品久久久久免费视 | 天堂网wwww| 永久免费精品影视网站 | 日本黄色片 | 美女被娇喘视频 | 亚洲欧美成人 | 不卡中文字幕av | 手机看片国产精品 | 中文字幕不卡一区 | 日日噜噜噜夜夜爽爽狠狠 | 色777| 调教奶奴 | 桃色网站在线观看 | 成人免费一区二区三区在线观看 | 九九色视频 | 日本一区不卡在线观看 | 免费视频网站在线观看入口 | 秘密爱大尺度做爰呻吟 | 巨乳美女在线 | wwwav视频在线观看 | 国产成人精品一区二区三 | 夜夜干天天操 | jjzz国产 | 在线观看特色大片免费网站 | 91成人亚洲| 日韩高清三区 | 大胸奶汁乳流奶水出来h | 日韩Av无码精品 | 色偷偷中文字幕 | 国内成人自拍 | 老地方在线观看免费动漫 | 吞精囗交69激情欧美 | 91精品亚洲一区 | 国产91精品久久久 | 亚洲免费在线视频 | 精品美女久久 | av大帝在线观看 | 最污网站在线观看 | 国产真实乱偷精品视频 | 人妻无码久久一区二区三区免费 | 国产精品视频一区二区三区在3 | 国产美女精品人人做人人爽 | 精品国产乱码久久久久久1区2区 | 人人搞人人 | 国产精品扒开腿做爽爽爽a片唱戏 | 欧美精品做受xxx性少妇 | 九色国产精品 | 国产精品视频一二三区 | 色窝窝综合色窝窝久久 | а√在线中文网新版地址在线 | 中文字幕无码毛片免费看 | 中国av一区二区 | 丁香网五月天 | 女女调教被c哭捆绑喷水百合 | 成人中文字幕+乱码+中文字幕 | 久久免费精品视频 | 中文字幕一区二区三区四区 | 亚洲欧洲综合网 | 亚洲v在线观看 | 色爱综合网 | 日韩有码在线播放 | 国内成人精品视频 |