Merge pull request #5953 from dumganhar/merge5934

closed #4541: [ui] Removed Widget::addNode, added ProtectedNode.
This commit is contained in:
James Chen 2014-03-25 15:46:56 +08:00
commit 34245d4bd0
30 changed files with 855 additions and 539 deletions

View File

@ -1 +1 @@
68ac83318dc8df5fee3badc4eb3f0e75ee0a9ce0 ebeb897c2c3303710c06b9de3cb3d499f89fb78c

View File

@ -72,7 +72,7 @@ bool nodeComparisonLess(Node* n1, Node* n2)
} }
// XXX: Yes, nodes might have a sort problem once every 15 days if the game runs at 60 FPS and each frame sprites are reordered. // XXX: Yes, nodes might have a sort problem once every 15 days if the game runs at 60 FPS and each frame sprites are reordered.
static int s_globalOrderOfArrival = 1; int Node::s_globalOrderOfArrival = 1;
Node::Node(void) Node::Node(void)
: _rotationX(0.0f) : _rotationX(0.0f)

View File

@ -1452,6 +1452,8 @@ protected:
bool _cascadeColorEnabled; bool _cascadeColorEnabled;
bool _cascadeOpacityEnabled; bool _cascadeOpacityEnabled;
static int s_globalOrderOfArrival;
private: private:
CC_DISALLOW_COPY_AND_ASSIGN(Node); CC_DISALLOW_COPY_AND_ASSIGN(Node);
}; };

View File

@ -68,6 +68,7 @@ CC_CONSTRUCTOR_ACCESS:
protected: protected:
friend class Node; friend class Node;
friend class ProtectedNode;
friend class SpriteBatchNode; friend class SpriteBatchNode;
private: private:

View File

@ -349,6 +349,7 @@ protected:
friend class PhysicsShape; friend class PhysicsShape;
friend class PhysicsJoint; friend class PhysicsJoint;
friend class Node; friend class Node;
friend class ProtectedNode;
}; };
NS_CC_END NS_CC_END

View File

@ -24,7 +24,8 @@ UITextBMFont.cpp \
UILoadingBar.cpp \ UILoadingBar.cpp \
UISlider.cpp \ UISlider.cpp \
UITextField.cpp \ UITextField.cpp \
UIRichText.cpp UIRichText.cpp \
CCProtectedNode.cpp
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/.. \ LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/.. \

View File

@ -0,0 +1,415 @@
/****************************************************************************
Copyright (c) 2008-2010 Ricardo Quesada
Copyright (c) 2009 Valentin Milea
Copyright (c) 2010-2012 cocos2d-x.org
Copyright (c) 2011 Zynga Inc.
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 "CCProtectedNode.h"
#include "kazmath/GL/matrix.h"
#if CC_USE_PHYSICS
#include "CCPhysicsBody.h"
#endif
#include "CCScene.h"
NS_CC_BEGIN
ProtectedNode::ProtectedNode() : _reorderProtectedChildDirty(false)
{
}
ProtectedNode::~ProtectedNode()
{
CCLOGINFO( "deallocing ProtectedNode: %p - tag: %i", this, _tag );
}
ProtectedNode * ProtectedNode::create(void)
{
ProtectedNode * ret = new ProtectedNode();
if (ret && ret->init())
{
ret->autorelease();
}
else
{
CC_SAFE_DELETE(ret);
}
return ret;
}
void ProtectedNode::cleanup()
{
Node::cleanup();
// timers
for( const auto &child: _protectedChildren)
child->cleanup();
}
void ProtectedNode::addProtectedChild(cocos2d::Node *child)
{
addProtectedChild(child, child->getLocalZOrder(), child->getTag());
}
void ProtectedNode::addProtectedChild(cocos2d::Node *child, int localZOrder)
{
addProtectedChild(child, localZOrder, child->getTag());
}
/* "add" logic MUST only be on this method
* If a class want's to extend the 'addChild' behavior it only needs
* to override this method
*/
void ProtectedNode::addProtectedChild(Node *child, int zOrder, int tag)
{
CCASSERT( child != nullptr, "Argument must be non-nil");
CCASSERT( child->getParent() == nullptr, "child already added. It can't be added again");
if (_protectedChildren.empty())
{
_protectedChildren.reserve(4);
}
this->insertProtectedChild(child, zOrder);
#if CC_USE_PHYSICS
if (child->getPhysicsBody() != nullptr)
{
child->getPhysicsBody()->setPosition(this->convertToWorldSpace(child->getPosition()));
}
for (Node* node = this->getParent(); node != nullptr; node = node->getParent())
{
if (dynamic_cast<Scene*>(node) != nullptr)
{
(dynamic_cast<Scene*>(node))->addChildToPhysicsWorld(child);
break;
}
}
#endif
child->setTag(tag);
child->setParent(this);
child->setOrderOfArrival(s_globalOrderOfArrival++);
if( _running )
{
child->onEnter();
// prevent onEnterTransitionDidFinish to be called twice when a node is added in onEnter
if (_isTransitionFinished) {
child->onEnterTransitionDidFinish();
}
}
if (_cascadeColorEnabled)
{
updateCascadeColor();
}
if (_cascadeOpacityEnabled)
{
updateCascadeOpacity();
}
}
Node* ProtectedNode::getProtectedChildByTag(int tag)
{
CCASSERT( tag != Node::INVALID_TAG, "Invalid tag");
for (auto& child : _protectedChildren)
{
if(child && child->getTag() == tag)
return child;
}
return nullptr;
}
/* "remove" logic MUST only be on this method
* If a class want's to extend the 'removeChild' behavior it only needs
* to override this method
*/
void ProtectedNode::removeProtectedChild(cocos2d::Node *child, bool cleanup)
{
// explicit nil handling
if (_protectedChildren.empty())
{
return;
}
ssize_t index = _protectedChildren.getIndex(child);
if( index != CC_INVALID_INDEX )
{
// IMPORTANT:
// -1st do onExit
// -2nd cleanup
if (_running)
{
child->onExitTransitionDidStart();
child->onExit();
}
#if CC_USE_PHYSICS
if (child->getPhysicsBody() != nullptr)
{
child->getPhysicsBody()->removeFromWorld();
}
#endif
// If you don't do cleanup, the child's actions will not get removed and the
// its scheduledSelectors_ dict will not get released!
if (cleanup)
{
child->cleanup();
}
// set parent nil at the end
child->setParent(nullptr);
_protectedChildren.erase(index);
}
}
void ProtectedNode::removeAllProtectedChildren()
{
removeAllProtectedChildrenWithCleanup(true);
}
void ProtectedNode::removeAllProtectedChildrenWithCleanup(bool cleanup)
{
// not using detachChild improves speed here
for (auto& child : _protectedChildren)
{
// IMPORTANT:
// -1st do onExit
// -2nd cleanup
if(_running)
{
child->onExitTransitionDidStart();
child->onExit();
}
#if CC_USE_PHYSICS
if (child->getPhysicsBody() != nullptr)
{
child->getPhysicsBody()->removeFromWorld();
}
#endif
if (cleanup)
{
child->cleanup();
}
// set parent nil at the end
child->setParent(nullptr);
}
_protectedChildren.clear();
}
void ProtectedNode::removeProtectedChildByTag(int tag, bool cleanup)
{
CCASSERT( tag != Node::INVALID_TAG, "Invalid tag");
Node *child = this->getProtectedChildByTag(tag);
if (child == nullptr)
{
CCLOG("cocos2d: removeChildByTag(tag = %d): child not found!", tag);
}
else
{
this->removeProtectedChild(child, cleanup);
}
}
// helper used by reorderChild & add
void ProtectedNode::insertProtectedChild(cocos2d::Node *child, int z)
{
_reorderProtectedChildDirty = true;
_protectedChildren.pushBack(child);
child->_setLocalZOrder(z);
}
void ProtectedNode::sortAllProtectedChildren()
{
if( _reorderProtectedChildDirty ) {
std::sort( std::begin(_protectedChildren), std::end(_protectedChildren), nodeComparisonLess );
_reorderProtectedChildDirty = false;
}
}
void ProtectedNode::reorderProtectedChild(cocos2d::Node *child, int localZOrder)
{
CCASSERT( child != nullptr, "Child must be non-nil");
_reorderProtectedChildDirty = true;
child->setOrderOfArrival(s_globalOrderOfArrival++);
child->_setLocalZOrder(localZOrder);
}
void ProtectedNode::visit(Renderer* renderer, const kmMat4 &parentTransform, bool parentTransformUpdated)
{
// quick return if not visible. children won't be drawn.
if (!_visible)
{
return;
}
bool dirty = _transformUpdated || parentTransformUpdated;
if(dirty)
_modelViewTransform = this->transform(parentTransform);
_transformUpdated = false;
// IMPORTANT:
// To ease the migration to v3.0, we still support the kmGL stack,
// but it is deprecated and your code should not rely on it
kmGLPushMatrix();
kmGLLoadMatrix(&_modelViewTransform);
int i = 0; // used by _children
int j = 0; // used by _protectedChildren
sortAllChildren();
sortAllProtectedChildren();
//
// draw children and protectedChildren zOrder < 0
//
for( ; i < _children.size(); i++ )
{
auto node = _children.at(i);
if ( node && node->getZOrder() < 0 )
node->visit(renderer, _modelViewTransform, dirty);
else
break;
}
for( ; j < _protectedChildren.size(); j++ )
{
auto node = _protectedChildren.at(j);
if ( node && node->getZOrder() < 0 )
node->visit(renderer, _modelViewTransform, dirty);
else
break;
}
//
// draw self
//
this->draw(renderer, _modelViewTransform, dirty);
//
// draw children and protectedChildren zOrder >= 0
//
for(auto it=_protectedChildren.cbegin()+j; it != _protectedChildren.cend(); ++it)
(*it)->visit(renderer, _modelViewTransform, dirty);
for(auto it=_children.cbegin()+i; it != _children.cend(); ++it)
(*it)->visit(renderer, _modelViewTransform, dirty);
// reset for next frame
_orderOfArrival = 0;
kmGLPopMatrix();
}
void ProtectedNode::onEnter()
{
Node::onEnter();
for( const auto &child: _protectedChildren)
child->onEnter();
}
void ProtectedNode::onEnterTransitionDidFinish()
{
Node::onEnterTransitionDidFinish();
for( const auto &child: _protectedChildren)
child->onEnterTransitionDidFinish();
}
void ProtectedNode::onExitTransitionDidStart()
{
Node::onExitTransitionDidStart();
for( const auto &child: _protectedChildren)
child->onExitTransitionDidStart();
}
void ProtectedNode::onExit()
{
Node::onExit();
for( const auto &child: _protectedChildren)
child->onExit();
}
void ProtectedNode::updateDisplayedOpacity(GLubyte parentOpacity)
{
_displayedOpacity = _realOpacity * parentOpacity/255.0;
updateColor();
if (_cascadeOpacityEnabled)
{
for(auto child : _children){
child->updateDisplayedOpacity(_displayedOpacity);
}
for(auto child : _protectedChildren){
child->updateDisplayedOpacity(_displayedOpacity);
}
}
}
void ProtectedNode::updateDisplayedColor(const Color3B& parentColor)
{
_displayedColor.r = _realColor.r * parentColor.r/255.0;
_displayedColor.g = _realColor.g * parentColor.g/255.0;
_displayedColor.b = _realColor.b * parentColor.b/255.0;
updateColor();
if (_cascadeColorEnabled)
{
for(const auto &child : _children){
child->updateDisplayedColor(_displayedColor);
}
for(const auto &child : _protectedChildren){
child->updateDisplayedColor(_displayedColor);
}
}
}
void ProtectedNode::disableCascadeColor()
{
for(auto child : _children){
child->updateDisplayedColor(Color3B::WHITE);
}
for(auto child : _protectedChildren){
child->updateDisplayedColor(Color3B::WHITE);
}
}
NS_CC_END

184
cocos/ui/CCProtectedNode.h Normal file
View File

@ -0,0 +1,184 @@
/****************************************************************************
Copyright (c) 2008-2010 Ricardo Quesada
Copyright (c) 2009 Valentin Milea
Copyright (c) 2010-2012 cocos2d-x.org
Copyright (c) 2011 Zynga Inc.
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.
****************************************************************************/
#ifndef __CPROTECTEDCNODE_H__
#define __CPROTECTEDCNODE_H__
#include "CCNode.h"
NS_CC_BEGIN
class CC_DLL ProtectedNode : public Node
{
public:
static ProtectedNode * create(void);
/// @{
/// @name Children and Parent
/**
* Adds a child to the container with z-order as 0.
*
* If the child is added to a 'running' node, then 'onEnter' and 'onEnterTransitionDidFinish' will be called immediately.
*
* @param child A child node
*/
virtual void addProtectedChild(Node * child);
/**
* Adds a child to the container with a local z-order
*
* If the child is added to a 'running' node, then 'onEnter' and 'onEnterTransitionDidFinish' will be called immediately.
*
* @param child A child node
* @param zOrder Z order for drawing priority. Please refer to `setLocalZOrder(int)`
*/
virtual void addProtectedChild(Node * child, int localZOrder);
/**
* Adds a child to the container with z order and tag
*
* If the child is added to a 'running' node, then 'onEnter' and 'onEnterTransitionDidFinish' will be called immediately.
*
* @param child A child node
* @param zOrder Z order for drawing priority. Please refer to `setLocalZOrder(int)`
* @param tag An integer to identify the node easily. Please refer to `setTag(int)`
*/
virtual void addProtectedChild(Node* child, int localZOrder, int tag);
/**
* Gets a child from the container with its tag
*
* @param tag An identifier to find the child node.
*
* @return a Node object whose tag equals to the input parameter
*/
virtual Node * getProtectedChildByTag(int tag);
////// REMOVES //////
/**
* Removes a child from the container. It will also cleanup all running actions depending on the cleanup parameter.
*
* @param child The child node which will be removed.
* @param cleanup true if all running actions and callbacks on the child node will be cleanup, false otherwise.
*/
virtual void removeProtectedChild(Node* child, bool cleanup = true);
/**
* Removes a child from the container by tag value. It will also cleanup all running actions depending on the cleanup parameter
*
* @param tag An interger number that identifies a child node
* @param cleanup true if all running actions and callbacks on the child node will be cleanup, false otherwise.
*/
virtual void removeProtectedChildByTag(int tag, bool cleanup = true);
/**
* Removes all children from the container with a cleanup.
*
* @see `removeAllChildrenWithCleanup(bool)`
*/
virtual void removeAllProtectedChildren();
/**
* Removes all children from the container, and do a cleanup to all running actions depending on the cleanup parameter.
*
* @param cleanup true if all running actions on all children nodes should be cleanup, false oterwise.
* @js removeAllChildren
* @lua removeAllChildren
*/
virtual void removeAllProtectedChildrenWithCleanup(bool cleanup);
/**
* Reorders a child according to a new z value.
*
* @param child An already added child node. It MUST be already added.
* @param localZOrder Z order for drawing priority. Please refer to setLocalZOrder(int)
*/
virtual void reorderProtectedChild(Node * child, int localZOrder);
/**
* Sorts the children array once before drawing, instead of every time when a child is added or reordered.
* This appraoch can improves the performance massively.
* @note Don't call this manually unless a child added needs to be removed in the same frame
*/
virtual void sortAllProtectedChildren();
/// @} end of Children and Parent
virtual void visit(Renderer *renderer, const kmMat4 &parentTransform, bool transformUpdated) override;
virtual void cleanup() override;
virtual void onEnter() override;
/** Event callback that is invoked when the Node enters in the 'stage'.
* If the Node enters the 'stage' with a transition, this event is called when the transition finishes.
* If you override onEnterTransitionDidFinish, you shall call its parent's one, e.g. Node::onEnterTransitionDidFinish()
* @js NA
* @lua NA
*/
virtual void onEnterTransitionDidFinish() override;
/**
* Event callback that is invoked every time the Node leaves the 'stage'.
* If the Node leaves the 'stage' with a transition, this event is called when the transition finishes.
* During onExit you can't access a sibling node.
* If you override onExit, you shall call its parent's one, e.g., Node::onExit().
* @js NA
* @lua NA
*/
virtual void onExit() override;
/**
* Event callback that is called every time the Node leaves the 'stage'.
* If the Node leaves the 'stage' with a transition, this callback is called when the transition starts.
* @js NA
* @lua NA
*/
virtual void onExitTransitionDidStart() override;
virtual void updateDisplayedOpacity(GLubyte parentOpacity) override;
virtual void updateDisplayedColor(const Color3B& parentColor) override;
virtual void disableCascadeColor() override;
protected:
ProtectedNode();
virtual ~ProtectedNode();
/// helper that reorder a child
void insertProtectedChild(Node* child, int z);
Vector<Node*> _protectedChildren; ///< array of children nodes
bool _reorderProtectedChildDirty;
private:
CC_DISALLOW_COPY_AND_ASSIGN(ProtectedNode);
};
NS_CC_END
#endif // __CPROTECTEDCNODE_H__

View File

@ -18,6 +18,7 @@ set(GUI_SRC
UISlider.cpp UISlider.cpp
UITextField.cpp UITextField.cpp
UIRichText.cpp UIRichText.cpp
CCProtectedNode.cpp
) )
add_library(ui STATIC add_library(ui STATIC

View File

@ -102,10 +102,10 @@ void Button::initRenderer()
_titleRenderer = Label::create(); _titleRenderer = Label::create();
_titleRenderer->setAnchorPoint(Point::ANCHOR_MIDDLE); _titleRenderer->setAnchorPoint(Point::ANCHOR_MIDDLE);
Node::addChild(_buttonNormalRenderer, NORMAL_RENDERER_Z, -1); addProtectedChild(_buttonNormalRenderer, NORMAL_RENDERER_Z, -1);
Node::addChild(_buttonClickedRenderer, PRESSED_RENDERER_Z, -1); addProtectedChild(_buttonClickedRenderer, PRESSED_RENDERER_Z, -1);
Node::addChild(_buttonDisableRenderer, DISABLED_RENDERER_Z, -1); addProtectedChild(_buttonDisableRenderer, DISABLED_RENDERER_Z, -1);
Node::addChild(_titleRenderer, TITLE_RENDERER_Z, -1); addProtectedChild(_titleRenderer, TITLE_RENDERER_Z, -1);
} }
void Button::setScale9Enabled(bool able) void Button::setScale9Enabled(bool able)
@ -116,9 +116,9 @@ void Button::setScale9Enabled(bool able)
} }
_brightStyle = BRIGHT_NONE; _brightStyle = BRIGHT_NONE;
_scale9Enabled = able; _scale9Enabled = able;
Node::removeChild(_buttonNormalRenderer); removeProtectedChild(_buttonNormalRenderer);
Node::removeChild(_buttonClickedRenderer); removeProtectedChild(_buttonClickedRenderer);
Node::removeChild(_buttonDisableRenderer); removeProtectedChild(_buttonDisableRenderer);
_buttonNormalRenderer = nullptr; _buttonNormalRenderer = nullptr;
_buttonClickedRenderer = nullptr; _buttonClickedRenderer = nullptr;
_buttonDisableRenderer = nullptr; _buttonDisableRenderer = nullptr;
@ -138,9 +138,9 @@ void Button::setScale9Enabled(bool able)
loadTextureNormal(_normalFileName.c_str(), _normalTexType); loadTextureNormal(_normalFileName.c_str(), _normalTexType);
loadTexturePressed(_clickedFileName.c_str(), _pressedTexType); loadTexturePressed(_clickedFileName.c_str(), _pressedTexType);
loadTextureDisabled(_disabledFileName.c_str(), _disabledTexType); loadTextureDisabled(_disabledFileName.c_str(), _disabledTexType);
Node::addChild(_buttonNormalRenderer, NORMAL_RENDERER_Z, -1); addProtectedChild(_buttonNormalRenderer, NORMAL_RENDERER_Z, -1);
Node::addChild(_buttonClickedRenderer, PRESSED_RENDERER_Z, -1); addProtectedChild(_buttonClickedRenderer, PRESSED_RENDERER_Z, -1);
Node::addChild(_buttonDisableRenderer, DISABLED_RENDERER_Z, -1); addProtectedChild(_buttonDisableRenderer, DISABLED_RENDERER_Z, -1);
if (_scale9Enabled) if (_scale9Enabled)
{ {
bool ignoreBefore = _ignoreSize; bool ignoreBefore = _ignoreSize;

View File

@ -95,11 +95,11 @@ void CheckBox::initRenderer()
_backGroundBoxDisabledRenderer = Sprite::create(); _backGroundBoxDisabledRenderer = Sprite::create();
_frontCrossDisabledRenderer = Sprite::create(); _frontCrossDisabledRenderer = Sprite::create();
Node::addChild(_backGroundBoxRenderer, BACKGROUNDBOX_RENDERER_Z, -1); addProtectedChild(_backGroundBoxRenderer, BACKGROUNDBOX_RENDERER_Z, -1);
Node::addChild(_backGroundSelectedBoxRenderer, BACKGROUNDSELECTEDBOX_RENDERER_Z, -1); addProtectedChild(_backGroundSelectedBoxRenderer, BACKGROUNDSELECTEDBOX_RENDERER_Z, -1);
Node::addChild(_frontCrossRenderer, FRONTCROSS_RENDERER_Z, -1); addProtectedChild(_frontCrossRenderer, FRONTCROSS_RENDERER_Z, -1);
Node::addChild(_backGroundBoxDisabledRenderer, BACKGROUNDBOXDISABLED_RENDERER_Z, -1); addProtectedChild(_backGroundBoxDisabledRenderer, BACKGROUNDBOXDISABLED_RENDERER_Z, -1);
Node::addChild(_frontCrossDisabledRenderer, FRONTCROSSDISABLED_RENDERER_Z, -1); addProtectedChild(_frontCrossDisabledRenderer, FRONTCROSSDISABLED_RENDERER_Z, -1);
} }
void CheckBox::loadTextures(const char *backGround, const char *backGroundSelected, const char *cross,const char* backGroundDisabled,const char* frontCrossDisabled,TextureResType texType) void CheckBox::loadTextures(const char *backGround, const char *backGroundSelected, const char *cross,const char* backGroundDisabled,const char* frontCrossDisabled,TextureResType texType)

View File

@ -42,11 +42,14 @@ Widget* Helper::seekWidgetByTag(Widget* root, int tag)
ssize_t length = arrayRootChildren.size(); ssize_t length = arrayRootChildren.size();
for (ssize_t i=0;i<length;i++) for (ssize_t i=0;i<length;i++)
{ {
Widget* child = static_cast<Widget*>(arrayRootChildren.at(i)); Widget* child = dynamic_cast<Widget*>(arrayRootChildren.at(i));
Widget* res = seekWidgetByTag(child,tag); if (child)
if (res != nullptr)
{ {
return res; Widget* res = seekWidgetByTag(child,tag);
if (res != nullptr)
{
return res;
}
} }
} }
return nullptr; return nullptr;
@ -65,11 +68,14 @@ Widget* Helper::seekWidgetByName(Widget* root, const char *name)
const auto& arrayRootChildren = root->getChildren(); const auto& arrayRootChildren = root->getChildren();
for (auto& subWidget : arrayRootChildren) for (auto& subWidget : arrayRootChildren)
{ {
Widget* child = static_cast<Widget*>(subWidget); Widget* child = dynamic_cast<Widget*>(subWidget);
Widget* res = seekWidgetByName(child,name); if (child)
if (res != nullptr)
{ {
return res; Widget* res = seekWidgetByName(child,name);
if (res != nullptr)
{
return res;
}
} }
} }
return nullptr; return nullptr;
@ -84,11 +90,14 @@ Widget* Helper::seekWidgetByRelativeName(Widget *root, const char *name)
const auto& arrayRootChildren = root->getChildren(); const auto& arrayRootChildren = root->getChildren();
for (auto& subWidget : arrayRootChildren) for (auto& subWidget : arrayRootChildren)
{ {
Widget* child = static_cast<Widget*>(subWidget); Widget* child = dynamic_cast<Widget*>(subWidget);
RelativeLayoutParameter* layoutParameter = dynamic_cast<RelativeLayoutParameter*>(child->getLayoutParameter(LAYOUT_PARAMETER_RELATIVE)); if (child)
if (layoutParameter && strcmp(layoutParameter->getRelativeName(), name) == 0)
{ {
return child; RelativeLayoutParameter* layoutParameter = dynamic_cast<RelativeLayoutParameter*>(child->getLayoutParameter(LAYOUT_PARAMETER_RELATIVE));
if (layoutParameter && strcmp(layoutParameter->getRelativeName(), name) == 0)
{
return child;
}
} }
} }
return nullptr; return nullptr;
@ -108,12 +117,15 @@ Widget* Helper::seekActionWidgetByActionTag(Widget* root, int tag)
const auto& arrayRootChildren = root->getChildren(); const auto& arrayRootChildren = root->getChildren();
for (auto& subWidget : arrayRootChildren) for (auto& subWidget : arrayRootChildren)
{ {
Widget* child = static_cast<Widget*>(subWidget); Widget* child = dynamic_cast<Widget*>(subWidget);
Widget* res = seekActionWidgetByActionTag(child,tag); if (child)
if (res != nullptr) {
{ Widget* res = seekActionWidgetByActionTag(child,tag);
return res; if (res != nullptr)
} {
return res;
}
}
} }
return nullptr; return nullptr;
} }

View File

@ -69,7 +69,7 @@ ImageView* ImageView::create()
void ImageView::initRenderer() void ImageView::initRenderer()
{ {
_imageRenderer = Sprite::create(); _imageRenderer = Sprite::create();
Node::addChild(_imageRenderer, IMAGE_RENDERER_Z, -1); addProtectedChild(_imageRenderer, IMAGE_RENDERER_Z, -1);
} }
void ImageView::loadTexture(const char *fileName, TextureResType texType) void ImageView::loadTexture(const char *fileName, TextureResType texType)
@ -166,7 +166,7 @@ void ImageView::setScale9Enabled(bool able)
_scale9Enabled = able; _scale9Enabled = able;
Node::removeChild(_imageRenderer); removeProtectedChild(_imageRenderer);
_imageRenderer = nullptr; _imageRenderer = nullptr;
if (_scale9Enabled) if (_scale9Enabled)
{ {
@ -177,7 +177,7 @@ void ImageView::setScale9Enabled(bool able)
_imageRenderer = Sprite::create(); _imageRenderer = Sprite::create();
} }
loadTexture(_textureFile.c_str(),_imageTexType); loadTexture(_textureFile.c_str(),_imageTexType);
Node::addChild(_imageRenderer, IMAGE_RENDERER_Z, -1); addProtectedChild(_imageRenderer, IMAGE_RENDERER_Z, -1);
if (_scale9Enabled) if (_scale9Enabled)
{ {
bool ignoreBefore = _ignoreSize; bool ignoreBefore = _ignoreSize;

View File

@ -127,7 +127,7 @@ Layout* Layout::create()
bool Layout::init() bool Layout::init()
{ {
if (Node::init()) if (ProtectedNode::init())
{ {
initRenderer(); initRenderer();
setBright(true); setBright(true);
@ -211,7 +211,7 @@ void Layout::visit(Renderer *renderer, const kmMat4 &parentTransform, bool paren
} }
else else
{ {
Node::visit(renderer, parentTransform, parentTransformUpdated); ProtectedNode::visit(renderer, parentTransform, parentTransformUpdated);
} }
} }
@ -254,32 +254,50 @@ void Layout::stencilClippingVisit(Renderer *renderer, const kmMat4 &parentTransf
_afterDrawStencilCmd.func = CC_CALLBACK_0(Layout::onAfterDrawStencil, this); _afterDrawStencilCmd.func = CC_CALLBACK_0(Layout::onAfterDrawStencil, this);
renderer->addCommand(&_afterDrawStencilCmd); renderer->addCommand(&_afterDrawStencilCmd);
int i = 0; int i = 0; // used by _children
int j = 0; // used by _protectedChildren
if(!_children.empty()) sortAllChildren();
sortAllProtectedChildren();
//
// draw children and protectedChildren zOrder < 0
//
for( ; i < _children.size(); i++ )
{ {
sortAllChildren(); auto node = _children.at(i);
// draw children zOrder < 0
for( ; i < _children.size(); i++ )
{
auto node = _children.at(i);
if ( node && node->getLocalZOrder() < 0 ) if ( node && node->getZOrder() < 0 )
node->visit(renderer, _modelViewTransform, dirty); node->visit(renderer, _modelViewTransform, dirty);
else else
break; break;
}
// self draw
this->draw(renderer, _modelViewTransform, dirty);
for(auto it=_children.cbegin()+i; it != _children.cend(); ++it)
(*it)->visit(renderer, _modelViewTransform, dirty);
} }
else
for( ; j < _protectedChildren.size(); j++ )
{ {
this->draw(renderer, _modelViewTransform, dirty); auto node = _protectedChildren.at(j);
if ( node && node->getZOrder() < 0 )
node->visit(renderer, _modelViewTransform, dirty);
else
break;
} }
//
// draw self
//
this->draw(renderer, _modelViewTransform, dirty);
//
// draw children and protectedChildren zOrder >= 0
//
for(auto it=_protectedChildren.cbegin()+j; it != _protectedChildren.cend(); ++it)
(*it)->visit(renderer, _modelViewTransform, dirty);
for(auto it=_children.cbegin()+i; it != _children.cend(); ++it)
(*it)->visit(renderer, _modelViewTransform, dirty);
_afterVisitCmdStencil.init(_globalZOrder); _afterVisitCmdStencil.init(_globalZOrder);
_afterVisitCmdStencil.func = CC_CALLBACK_0(Layout::onAfterVisitStencil, this); _afterVisitCmdStencil.func = CC_CALLBACK_0(Layout::onAfterVisitStencil, this);
renderer->addCommand(&_afterVisitCmdStencil); renderer->addCommand(&_afterVisitCmdStencil);
@ -368,7 +386,7 @@ void Layout::scissorClippingVisit(Renderer *renderer, const kmMat4& parentTransf
_beforeVisitCmdScissor.func = CC_CALLBACK_0(Layout::onBeforeVisitScissor, this); _beforeVisitCmdScissor.func = CC_CALLBACK_0(Layout::onBeforeVisitScissor, this);
renderer->addCommand(&_beforeVisitCmdScissor); renderer->addCommand(&_beforeVisitCmdScissor);
Node::visit(renderer, parentTransform, parentTransformUpdated); ProtectedNode::visit(renderer, parentTransform, parentTransformUpdated);
_afterVisitCmdScissor.init(_globalZOrder); _afterVisitCmdScissor.init(_globalZOrder);
_afterVisitCmdScissor.func = CC_CALLBACK_0(Layout::onAfterVisitScissor, this); _afterVisitCmdScissor.func = CC_CALLBACK_0(Layout::onAfterVisitScissor, this);
@ -566,19 +584,10 @@ void Layout::setBackGroundImageScale9Enabled(bool able)
{ {
return; return;
} }
Node::removeChild(_backGroundImage); removeProtectedChild(_backGroundImage);
_backGroundImage = nullptr; _backGroundImage = nullptr;
_backGroundScale9Enabled = able; _backGroundScale9Enabled = able;
if (_backGroundScale9Enabled) addBackGroundImage();
{
_backGroundImage = extension::Scale9Sprite::create();
Node::addChild(_backGroundImage, BACKGROUNDIMAGE_Z, -1);
}
else
{
_backGroundImage = Sprite::create();
Node::addChild(_backGroundImage, BACKGROUNDIMAGE_Z, -1);
}
setBackGroundImage(_backGroundImageFileName.c_str(),_bgImageTexType); setBackGroundImage(_backGroundImageFileName.c_str(),_bgImageTexType);
setBackGroundImageCapInsets(_backGroundImageCapInsets); setBackGroundImageCapInsets(_backGroundImageCapInsets);
} }
@ -688,15 +697,13 @@ void Layout::addBackGroundImage()
if (_backGroundScale9Enabled) if (_backGroundScale9Enabled)
{ {
_backGroundImage = extension::Scale9Sprite::create(); _backGroundImage = extension::Scale9Sprite::create();
_backGroundImage->setLocalZOrder(-1); addProtectedChild(_backGroundImage, BACKGROUNDIMAGE_Z, -1);
Node::addChild(_backGroundImage, BACKGROUNDIMAGE_Z, -1);
static_cast<extension::Scale9Sprite*>(_backGroundImage)->setPreferredSize(_size); static_cast<extension::Scale9Sprite*>(_backGroundImage)->setPreferredSize(_size);
} }
else else
{ {
_backGroundImage = Sprite::create(); _backGroundImage = Sprite::create();
_backGroundImage->setLocalZOrder(-1); addProtectedChild(_backGroundImage, BACKGROUNDIMAGE_Z, -1);
Node::addChild(_backGroundImage, BACKGROUNDIMAGE_Z, -1);
} }
_backGroundImage->setPosition(Point(_size.width/2.0f, _size.height/2.0f)); _backGroundImage->setPosition(Point(_size.width/2.0f, _size.height/2.0f));
} }
@ -707,7 +714,7 @@ void Layout::removeBackGroundImage()
{ {
return; return;
} }
Node::removeChild(_backGroundImage); removeProtectedChild(_backGroundImage);
_backGroundImage = nullptr; _backGroundImage = nullptr;
_backGroundImageFileName = ""; _backGroundImageFileName = "";
_backGroundImageTextureSize = Size::ZERO; _backGroundImageTextureSize = Size::ZERO;
@ -724,26 +731,26 @@ void Layout::setBackGroundColorType(LayoutBackGroundColorType type)
case LAYOUT_COLOR_NONE: case LAYOUT_COLOR_NONE:
if (_colorRender) if (_colorRender)
{ {
Node::removeChild(_colorRender); removeProtectedChild(_colorRender);
_colorRender = nullptr; _colorRender = nullptr;
} }
if (_gradientRender) if (_gradientRender)
{ {
Node::removeChild(_gradientRender); removeProtectedChild(_gradientRender);
_gradientRender = nullptr; _gradientRender = nullptr;
} }
break; break;
case LAYOUT_COLOR_SOLID: case LAYOUT_COLOR_SOLID:
if (_colorRender) if (_colorRender)
{ {
Node::removeChild(_colorRender); removeProtectedChild(_colorRender);
_colorRender = nullptr; _colorRender = nullptr;
} }
break; break;
case LAYOUT_COLOR_GRADIENT: case LAYOUT_COLOR_GRADIENT:
if (_gradientRender) if (_gradientRender)
{ {
Node::removeChild(_gradientRender); removeProtectedChild(_gradientRender);
_gradientRender = nullptr; _gradientRender = nullptr;
} }
break; break;
@ -760,7 +767,7 @@ void Layout::setBackGroundColorType(LayoutBackGroundColorType type)
_colorRender->setContentSize(_size); _colorRender->setContentSize(_size);
_colorRender->setOpacity(_cOpacity); _colorRender->setOpacity(_cOpacity);
_colorRender->setColor(_cColor); _colorRender->setColor(_cColor);
Node::addChild(_colorRender, BCAKGROUNDCOLORRENDERER_Z, -1); addProtectedChild(_colorRender, BCAKGROUNDCOLORRENDERER_Z, -1);
break; break;
case LAYOUT_COLOR_GRADIENT: case LAYOUT_COLOR_GRADIENT:
_gradientRender = LayerGradient::create(); _gradientRender = LayerGradient::create();
@ -769,7 +776,7 @@ void Layout::setBackGroundColorType(LayoutBackGroundColorType type)
_gradientRender->setStartColor(_gStartColor); _gradientRender->setStartColor(_gStartColor);
_gradientRender->setEndColor(_gEndColor); _gradientRender->setEndColor(_gEndColor);
_gradientRender->setVector(_alongVector); _gradientRender->setVector(_alongVector);
Node::addChild(_gradientRender, BCAKGROUNDCOLORRENDERER_Z, -1); addProtectedChild(_gradientRender, BCAKGROUNDCOLORRENDERER_Z, -1);
break; break;
default: default:
break; break;
@ -911,9 +918,10 @@ const Size& Layout::getBackGroundImageTextureSize() const
void Layout::setLayoutType(LayoutType type) void Layout::setLayoutType(LayoutType type)
{ {
_layoutType = type; _layoutType = type;
for (auto& child : _widgetChildren) for (auto& child : _children)
{ {
if (child) Widget* widgetChild = dynamic_cast<Widget*>(child);
if (widgetChild)
{ {
supplyTheLayoutParameterLackToChild(static_cast<Widget*>(child)); supplyTheLayoutParameterLackToChild(static_cast<Widget*>(child));
} }
@ -946,37 +954,40 @@ void Layout::doLayout()
Size layoutSize = getSize(); Size layoutSize = getSize();
float topBoundary = layoutSize.height; float topBoundary = layoutSize.height;
for (auto& subWidget : _widgetChildren) for (auto& subWidget : _children)
{ {
Widget* child = static_cast<Widget*>(subWidget); Widget* child = dynamic_cast<Widget*>(subWidget);
LinearLayoutParameter* layoutParameter = dynamic_cast<LinearLayoutParameter*>(child->getLayoutParameter(LAYOUT_PARAMETER_LINEAR)); if (child)
if (layoutParameter)
{ {
LinearGravity childGravity = layoutParameter->getGravity(); LinearLayoutParameter* layoutParameter = dynamic_cast<LinearLayoutParameter*>(child->getLayoutParameter(LAYOUT_PARAMETER_LINEAR));
Point ap = child->getAnchorPoint();
Size cs = child->getSize(); if (layoutParameter)
float finalPosX = ap.x * cs.width;
float finalPosY = topBoundary - ((1.0f-ap.y) * cs.height);
switch (childGravity)
{ {
case LINEAR_GRAVITY_NONE: LinearGravity childGravity = layoutParameter->getGravity();
case LINEAR_GRAVITY_LEFT: Point ap = child->getAnchorPoint();
break; Size cs = child->getSize();
case LINEAR_GRAVITY_RIGHT: float finalPosX = ap.x * cs.width;
finalPosX = layoutSize.width - ((1.0f - ap.x) * cs.width); float finalPosY = topBoundary - ((1.0f-ap.y) * cs.height);
break; switch (childGravity)
case LINEAR_GRAVITY_CENTER_HORIZONTAL: {
finalPosX = layoutSize.width / 2.0f - cs.width * (0.5f-ap.x); case LINEAR_GRAVITY_NONE:
break; case LINEAR_GRAVITY_LEFT:
default: break;
break; case LINEAR_GRAVITY_RIGHT:
finalPosX = layoutSize.width - ((1.0f - ap.x) * cs.width);
break;
case LINEAR_GRAVITY_CENTER_HORIZONTAL:
finalPosX = layoutSize.width / 2.0f - cs.width * (0.5f-ap.x);
break;
default:
break;
}
Margin mg = layoutParameter->getMargin();
finalPosX += mg.left;
finalPosY -= mg.top;
child->setPosition(Point(finalPosX, finalPosY));
topBoundary = child->getBottomInParent() - mg.bottom;
} }
Margin mg = layoutParameter->getMargin();
finalPosX += mg.left;
finalPosY -= mg.top;
child->setPosition(Point(finalPosX, finalPosY));
topBoundary = child->getBottomInParent() - mg.bottom;
} }
} }
break; break;
@ -985,54 +996,62 @@ void Layout::doLayout()
{ {
Size layoutSize = getSize(); Size layoutSize = getSize();
float leftBoundary = 0.0f; float leftBoundary = 0.0f;
for (auto& subWidget : _widgetChildren) for (auto& subWidget : _children)
{ {
Widget* child = static_cast<Widget*>(subWidget); Widget* child = dynamic_cast<Widget*>(subWidget);
LinearLayoutParameter* layoutParameter = dynamic_cast<LinearLayoutParameter*>(child->getLayoutParameter(LAYOUT_PARAMETER_LINEAR)); if (child)
if (layoutParameter)
{ {
LinearGravity childGravity = layoutParameter->getGravity(); LinearLayoutParameter* layoutParameter = dynamic_cast<LinearLayoutParameter*>(child->getLayoutParameter(LAYOUT_PARAMETER_LINEAR));
Point ap = child->getAnchorPoint(); if (layoutParameter)
Size cs = child->getSize();
float finalPosX = leftBoundary + (ap.x * cs.width);
float finalPosY = layoutSize.height - (1.0f - ap.y) * cs.height;
switch (childGravity)
{ {
case LINEAR_GRAVITY_NONE: LinearGravity childGravity = layoutParameter->getGravity();
case LINEAR_GRAVITY_TOP: Point ap = child->getAnchorPoint();
break; Size cs = child->getSize();
case LINEAR_GRAVITY_BOTTOM: float finalPosX = leftBoundary + (ap.x * cs.width);
finalPosY = ap.y * cs.height; float finalPosY = layoutSize.height - (1.0f - ap.y) * cs.height;
break; switch (childGravity)
case LINEAR_GRAVITY_CENTER_VERTICAL: {
finalPosY = layoutSize.height / 2.0f - cs.height * (0.5f - ap.y); case LINEAR_GRAVITY_NONE:
break; case LINEAR_GRAVITY_TOP:
default: break;
break; case LINEAR_GRAVITY_BOTTOM:
finalPosY = ap.y * cs.height;
break;
case LINEAR_GRAVITY_CENTER_VERTICAL:
finalPosY = layoutSize.height / 2.0f - cs.height * (0.5f - ap.y);
break;
default:
break;
}
Margin mg = layoutParameter->getMargin();
finalPosX += mg.left;
finalPosY -= mg.top;
child->setPosition(Point(finalPosX, finalPosY));
leftBoundary = child->getRightInParent() + mg.right;
} }
Margin mg = layoutParameter->getMargin();
finalPosX += mg.left;
finalPosY -= mg.top;
child->setPosition(Point(finalPosX, finalPosY));
leftBoundary = child->getRightInParent() + mg.right;
} }
} }
break; break;
} }
case LAYOUT_RELATIVE: case LAYOUT_RELATIVE:
{ {
ssize_t unlayoutChildCount = _widgetChildren.size(); ssize_t unlayoutChildCount = 0;
Size layoutSize = getSize(); Size layoutSize = getSize();
for (auto& subWidget : _widgetChildren) Vector<Widget*> widgetChildren;
for (auto& subWidget : _children)
{ {
Widget* child = static_cast<Widget*>(subWidget); Widget* child = dynamic_cast<Widget*>(subWidget);
RelativeLayoutParameter* layoutParameter = dynamic_cast<RelativeLayoutParameter*>(child->getLayoutParameter(LAYOUT_PARAMETER_RELATIVE)); if (child)
layoutParameter->_put = false; {
RelativeLayoutParameter* layoutParameter = dynamic_cast<RelativeLayoutParameter*>(child->getLayoutParameter(LAYOUT_PARAMETER_RELATIVE));
layoutParameter->_put = false;
unlayoutChildCount++;
widgetChildren.pushBack(child);
}
} }
while (unlayoutChildCount > 0) while (unlayoutChildCount > 0)
{ {
for (auto& subWidget : _widgetChildren) for (auto& subWidget : widgetChildren)
{ {
Widget* child = static_cast<Widget*>(subWidget); Widget* child = static_cast<Widget*>(subWidget);
RelativeLayoutParameter* layoutParameter = dynamic_cast<RelativeLayoutParameter*>(child->getLayoutParameter(LAYOUT_PARAMETER_RELATIVE)); RelativeLayoutParameter* layoutParameter = dynamic_cast<RelativeLayoutParameter*>(child->getLayoutParameter(LAYOUT_PARAMETER_RELATIVE));
@ -1359,6 +1378,7 @@ void Layout::doLayout()
} }
} }
} }
widgetChildren.clear();
break; break;
} }
default: default:

View File

@ -67,7 +67,7 @@ LoadingBar* LoadingBar::create()
void LoadingBar::initRenderer() void LoadingBar::initRenderer()
{ {
_barRenderer = Sprite::create(); _barRenderer = Sprite::create();
Node::addChild(_barRenderer, BAR_RENDERER_Z, -1); addProtectedChild(_barRenderer, BAR_RENDERER_Z, -1);
_barRenderer->setAnchorPoint(Point(0.0,0.5)); _barRenderer->setAnchorPoint(Point(0.0,0.5));
} }
@ -172,7 +172,7 @@ void LoadingBar::setScale9Enabled(bool enabled)
return; return;
} }
_scale9Enabled = enabled; _scale9Enabled = enabled;
Node::removeChild(_barRenderer); removeProtectedChild(_barRenderer);
_barRenderer = nullptr; _barRenderer = nullptr;
if (_scale9Enabled) if (_scale9Enabled)
{ {
@ -183,7 +183,7 @@ void LoadingBar::setScale9Enabled(bool enabled)
_barRenderer = Sprite::create(); _barRenderer = Sprite::create();
} }
loadTexture(_textureFile.c_str(),_renderBarTexType); loadTexture(_textureFile.c_str(),_renderBarTexType);
Node::addChild(_barRenderer, BAR_RENDERER_Z, -1); addProtectedChild(_barRenderer, BAR_RENDERER_Z, -1);
if (_scale9Enabled) if (_scale9Enabled)
{ {
bool ignoreBefore = _ignoreSize; bool ignoreBefore = _ignoreSize;

View File

@ -148,7 +148,7 @@ void RichText::initRenderer()
{ {
_elementRenderersContainer = Node::create(); _elementRenderersContainer = Node::create();
_elementRenderersContainer->setAnchorPoint(Point(0.5f, 0.5f)); _elementRenderersContainer->setAnchorPoint(Point(0.5f, 0.5f));
Node::addChild(_elementRenderersContainer, 0, -1); addProtectedChild(_elementRenderersContainer, 0, -1);
} }
void RichText::insertElement(RichElement *element, int index) void RichText::insertElement(RichElement *element, int index)
@ -437,6 +437,11 @@ void RichText::ignoreContentAdaptWithSize(bool ignore)
} }
} }
std::string RichText::getDescription() const
{
return "RichText";
}
} }
NS_CC_END NS_CC_END

View File

@ -108,6 +108,7 @@ public:
virtual const Size& getContentSize() const; virtual const Size& getContentSize() const;
void formatText(); void formatText();
virtual void ignoreContentAdaptWithSize(bool ignore); virtual void ignoreContentAdaptWithSize(bool ignore);
virtual std::string getDescription() const override;
CC_CONSTRUCTOR_ACCESS: CC_CONSTRUCTOR_ACCESS:
virtual bool init() override; virtual bool init() override;

View File

@ -311,46 +311,6 @@ Widget* ScrollView::getChildByName(const char *name)
return _innerContainer->getChildByName(name); return _innerContainer->getChildByName(name);
} }
void ScrollView::addNode(Node* node)
{
Layout::addNode(node);
}
void ScrollView::addNode(Node * node, int zOrder)
{
Layout::addNode(node, zOrder);
}
void ScrollView::addNode(Node* node, int zOrder, int tag)
{
_innerContainer->addNode(node, zOrder, tag);
}
Node* ScrollView::getNodeByTag(int tag)
{
return _innerContainer->getNodeByTag(tag);
}
Vector<Node*>& ScrollView::getNodes()
{
return _innerContainer->getNodes();
}
void ScrollView::removeNode(Node* node)
{
_innerContainer->removeNode(node);
}
void ScrollView::removeNodeByTag(int tag)
{
_innerContainer->removeNodeByTag(tag);
}
void ScrollView::removeAllNodes()
{
_innerContainer->removeAllNodes();
}
void ScrollView::moveChildren(float offsetX, float offsetY) void ScrollView::moveChildren(float offsetX, float offsetY)
{ {
_moveChildPoint = _innerContainer->getPosition() + Point(offsetX, offsetY); _moveChildPoint = _innerContainer->getPosition() + Point(offsetX, offsetY);

View File

@ -286,22 +286,6 @@ public:
virtual Widget* getChildByName(const char* name) override; virtual Widget* getChildByName(const char* name) override;
virtual void addNode(Node* node) override;
virtual void addNode(Node * node, int zOrder) override;
virtual void addNode(Node* node, int zOrder, int tag) override;
virtual Node * getNodeByTag(int tag) override;
virtual Vector<Node*>& getNodes() override;
virtual void removeNode(Node* node) override;
virtual void removeNodeByTag(int tag) override;
virtual void removeAllNodes() override;
virtual bool onTouchBegan(Touch *touch, Event *unusedEvent) override; virtual bool onTouchBegan(Touch *touch, Event *unusedEvent) override;
virtual void onTouchMoved(Touch *touch, Event *unusedEvent) override; virtual void onTouchMoved(Touch *touch, Event *unusedEvent) override;
virtual void onTouchEnded(Touch *touch, Event *unusedEvent) override; virtual void onTouchEnded(Touch *touch, Event *unusedEvent) override;

View File

@ -97,8 +97,8 @@ void Slider::initRenderer()
_barRenderer = Sprite::create(); _barRenderer = Sprite::create();
_progressBarRenderer = Sprite::create(); _progressBarRenderer = Sprite::create();
_progressBarRenderer->setAnchorPoint(Point(0.0f, 0.5f)); _progressBarRenderer->setAnchorPoint(Point(0.0f, 0.5f));
Node::addChild(_barRenderer, BASEBAR_RENDERER_Z, -1); addProtectedChild(_barRenderer, BASEBAR_RENDERER_Z, -1);
Node::addChild(_progressBarRenderer, PROGRESSBAR_RENDERER_Z, -1); addProtectedChild(_progressBarRenderer, PROGRESSBAR_RENDERER_Z, -1);
_slidBallNormalRenderer = Sprite::create(); _slidBallNormalRenderer = Sprite::create();
_slidBallPressedRenderer = Sprite::create(); _slidBallPressedRenderer = Sprite::create();
_slidBallPressedRenderer->setVisible(false); _slidBallPressedRenderer->setVisible(false);
@ -108,7 +108,7 @@ void Slider::initRenderer()
_slidBallRenderer->addChild(_slidBallNormalRenderer); _slidBallRenderer->addChild(_slidBallNormalRenderer);
_slidBallRenderer->addChild(_slidBallPressedRenderer); _slidBallRenderer->addChild(_slidBallPressedRenderer);
_slidBallRenderer->addChild(_slidBallDisabledRenderer); _slidBallRenderer->addChild(_slidBallDisabledRenderer);
Node::addChild(_slidBallRenderer, SLIDBALL_RENDERER_Z, -1); addProtectedChild(_slidBallRenderer, SLIDBALL_RENDERER_Z, -1);
} }
void Slider::loadBarTexture(const char* fileName, TextureResType texType) void Slider::loadBarTexture(const char* fileName, TextureResType texType)
@ -196,8 +196,8 @@ void Slider::setScale9Enabled(bool able)
} }
_scale9Enabled = able; _scale9Enabled = able;
Node::removeChild(_barRenderer); removeProtectedChild(_barRenderer);
Node::removeChild(_progressBarRenderer); removeProtectedChild(_progressBarRenderer);
_barRenderer = nullptr; _barRenderer = nullptr;
_progressBarRenderer = nullptr; _progressBarRenderer = nullptr;
if (_scale9Enabled) if (_scale9Enabled)
@ -212,8 +212,8 @@ void Slider::setScale9Enabled(bool able)
} }
loadBarTexture(_textureFile.c_str(), _barTexType); loadBarTexture(_textureFile.c_str(), _barTexType);
loadProgressBarTexture(_progressBarTextureFile.c_str(), _progressBarTexType); loadProgressBarTexture(_progressBarTextureFile.c_str(), _progressBarTexType);
Node::addChild(_barRenderer, BASEBAR_RENDERER_Z, -1); addProtectedChild(_barRenderer, BASEBAR_RENDERER_Z, -1);
Node::addChild(_progressBarRenderer, PROGRESSBAR_RENDERER_Z, -1); addProtectedChild(_progressBarRenderer, PROGRESSBAR_RENDERER_Z, -1);
if (_scale9Enabled) if (_scale9Enabled)
{ {
bool ignoreBefore = _ignoreSize; bool ignoreBefore = _ignoreSize;

View File

@ -72,7 +72,7 @@ bool Text::init()
void Text::initRenderer() void Text::initRenderer()
{ {
_labelRenderer = Label::create(); _labelRenderer = Label::create();
Node::addChild(_labelRenderer, LABEL_RENDERER_Z, -1); addProtectedChild(_labelRenderer, LABEL_RENDERER_Z, -1);
} }
void Text::setText(const std::string& text) void Text::setText(const std::string& text)

View File

@ -62,7 +62,7 @@ TextAtlas* TextAtlas::create()
void TextAtlas::initRenderer() void TextAtlas::initRenderer()
{ {
_labelAtlasRenderer = LabelAtlas::create(); _labelAtlasRenderer = LabelAtlas::create();
Node::addChild(_labelAtlasRenderer, LABELATLAS_RENDERER_Z, -1); addProtectedChild(_labelAtlasRenderer, LABELATLAS_RENDERER_Z, -1);
} }
void TextAtlas::setProperty(const std::string& stringValue, const std::string& charMapFile, int itemWidth, int itemHeight, const std::string& startCharMap) void TextAtlas::setProperty(const std::string& stringValue, const std::string& charMapFile, int itemWidth, int itemHeight, const std::string& startCharMap)

View File

@ -60,7 +60,7 @@ TextBMFont* TextBMFont::create()
void TextBMFont::initRenderer() void TextBMFont::initRenderer()
{ {
_labelBMFontRenderer = cocos2d::LabelBMFont::create(); _labelBMFontRenderer = cocos2d::LabelBMFont::create();
Node::addChild(_labelBMFontRenderer, LABELBMFONT_RENDERER_Z, -1); addProtectedChild(_labelBMFontRenderer, LABELBMFONT_RENDERER_Z, -1);
} }
void TextBMFont::setFntFile(const char *fileName) void TextBMFont::setFntFile(const char *fileName)

View File

@ -392,7 +392,7 @@ void TextField::onEnter()
void TextField::initRenderer() void TextField::initRenderer()
{ {
_textFieldRenderer = UICCTextField::create("input words here", "Thonburi", 20); _textFieldRenderer = UICCTextField::create("input words here", "Thonburi", 20);
Node::addChild(_textFieldRenderer, TEXTFIELD_RENDERER_Z, -1); addProtectedChild(_textFieldRenderer, TEXTFIELD_RENDERER_Z, -1);
} }
void TextField::setTouchSize(const Size &size) void TextField::setTouchSize(const Size &size)

View File

@ -56,7 +56,6 @@ _positionPercent(Point::ZERO),
_reorderWidgetChildDirty(true), _reorderWidgetChildDirty(true),
_hitted(false), _hitted(false),
_touchListener(nullptr), _touchListener(nullptr),
_nodes(NULL),
_color(Color3B::WHITE), _color(Color3B::WHITE),
_opacity(255), _opacity(255),
_flippedX(false), _flippedX(false),
@ -69,9 +68,7 @@ Widget::~Widget()
{ {
_touchEventListener = nullptr; _touchEventListener = nullptr;
_touchEventSelector = nullptr; _touchEventSelector = nullptr;
_widgetChildren.clear();
setTouchEnabled(false); setTouchEnabled(false);
_nodes.clear();
} }
Widget* Widget::create() Widget* Widget::create()
@ -88,7 +85,7 @@ Widget* Widget::create()
bool Widget::init() bool Widget::init()
{ {
if (Node::init()) if (ProtectedNode::init())
{ {
initRenderer(); initRenderer();
setBright(true); setBright(true);
@ -102,229 +99,75 @@ bool Widget::init()
void Widget::onEnter() void Widget::onEnter()
{ {
updateSizeAndPosition(); updateSizeAndPosition();
Node::onEnter(); ProtectedNode::onEnter();
} }
void Widget::onExit() void Widget::onExit()
{ {
unscheduleUpdate(); unscheduleUpdate();
Node::onExit(); ProtectedNode::onExit();
} }
void Widget::visit(Renderer *renderer, const kmMat4 &parentTransform, bool parentTransformUpdated) void Widget::visit(Renderer *renderer, const kmMat4 &parentTransform, bool parentTransformUpdated)
{ {
if (_enabled) if (_enabled)
{ {
Node::visit(renderer, parentTransform, parentTransformUpdated); ProtectedNode::visit(renderer, parentTransform, parentTransformUpdated);
} }
} }
void Widget::addChild(Node *child)
{
Node::addChild(child);
}
void Widget::addChild(Node * child, int zOrder)
{
Node::addChild(child, zOrder);
}
void Widget::addChild(Node* child, int zOrder, int tag)
{
CCASSERT(dynamic_cast<Widget*>(child) != nullptr, "Widget only supports Widgets as children");
Node::addChild(child, zOrder, tag);
_widgetChildren.pushBack(child);
}
void Widget::sortAllChildren()
{
_reorderWidgetChildDirty = _reorderChildDirty;
Node::sortAllChildren();
if( _reorderWidgetChildDirty )
{
std::sort( std::begin(_widgetChildren), std::end(_widgetChildren), nodeComparisonLess );
_reorderWidgetChildDirty = false;
}
}
Node* Widget::getChildByTag(int aTag)
{
CCASSERT( aTag != Node::INVALID_TAG, "Invalid tag");
for (auto& child : _widgetChildren)
{
if(child && child->getTag() == aTag)
return child;
}
return nullptr;
}
Vector<Node*>& Widget::getChildren()
{
return _widgetChildren;
}
const Vector<Node*>& Widget::getChildren() const
{
return _widgetChildren;
}
ssize_t Widget::getChildrenCount() const
{
return _widgetChildren.size();
}
Widget* Widget::getWidgetParent() Widget* Widget::getWidgetParent()
{ {
return dynamic_cast<Widget*>(getParent()); return dynamic_cast<Widget*>(getParent());
} }
void Widget::removeFromParent()
{
removeFromParentAndCleanup(true);
}
void Widget::removeFromParentAndCleanup(bool cleanup)
{
Node::removeFromParentAndCleanup(cleanup);
}
void Widget::removeChild(Node *child, bool cleanup)
{
Node::removeChild(child, cleanup);
_widgetChildren.eraseObject(child);
}
void Widget::removeChildByTag(int tag, bool cleanup)
{
CCASSERT( tag != Node::INVALID_TAG, "Invalid tag");
Node *child = getChildByTag(tag);
if (child == nullptr)
{
CCLOG("cocos2d: removeChildByTag(tag = %d): child not found!", tag);
}
else
{
removeChild(child, cleanup);
}
}
void Widget::removeAllChildren()
{
removeAllChildrenWithCleanup(true);
}
void Widget::removeAllChildrenWithCleanup(bool cleanup)
{
for (auto& child : _widgetChildren)
{
if (child)
{
Node::removeChild(child);
}
}
_widgetChildren.clear();
}
void Widget::setEnabled(bool enabled) void Widget::setEnabled(bool enabled)
{ {
_enabled = enabled; _enabled = enabled;
for (auto& child : _widgetChildren) for (auto& child : _children)
{ {
if (child) if (child)
{ {
static_cast<Widget*>(child)->setEnabled(enabled); 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) Widget* Widget::getChildByName(const char *name)
{ {
for (auto& child : _widgetChildren) for (auto& child : _children)
{ {
if (child) if (child)
{ {
Widget* widgetChild = static_cast<Widget*>(child); Widget* widgetChild = dynamic_cast<Widget*>(child);
if (strcmp(widgetChild->getName(), name) == 0) if (widgetChild)
{ {
return widgetChild; if (strcmp(widgetChild->getName(), name) == 0)
{
return widgetChild;
}
} }
} }
} }
return nullptr; return nullptr;
} }
void Widget::addNode(Node* node)
{
addNode(node, node->getLocalZOrder(), node->getTag());
}
void Widget::addNode(Node * node, int zOrder)
{
addNode(node, zOrder, node->getTag());
}
void Widget::addNode(Node* node, int zOrder, int tag)
{
CCAssert(dynamic_cast<Widget*>(node) == nullptr, "Widget only supports Nodes as renderer");
Node::addChild(node, zOrder, tag);
_nodes.pushBack(node);
}
Node* Widget::getNodeByTag(int tag)
{
CCAssert( tag != Node::INVALID_TAG, "Invalid tag");
for (auto& node : _nodes)
{
if(node && node->getTag() == tag)
return node;
}
return nullptr;
}
Vector<Node*>& Widget::getNodes()
{
return _nodes;
}
void Widget::removeNode(Node* node)
{
Node::removeChild(node);
_nodes.eraseObject(node);
}
void Widget::removeNodeByTag(int tag)
{
CCAssert( tag != Node::INVALID_TAG, "Invalid tag");
Node *node = this->getNodeByTag(tag);
if (node == nullptr)
{
CCLOG("cocos2d: removeNodeByTag(tag = %d): child not found!", tag);
}
else
{
this->removeNode(node);
}
}
void Widget::removeAllNodes()
{
for (auto& node : _nodes)
{
if (node)
{
Node::removeChild(node);
}
}
_nodes.clear();
}
void Widget::initRenderer() void Widget::initRenderer()
{ {
} }
@ -544,9 +387,10 @@ void Widget::onSizeChanged()
{ {
for (auto& child : getChildren()) for (auto& child : getChildren())
{ {
if (child) Widget* widgetChild = dynamic_cast<Widget*>(child);
if (widgetChild)
{ {
static_cast<Widget*>(child)->updateSizeAndPosition(); widgetChild->updateSizeAndPosition();
} }
} }
} }
@ -850,7 +694,7 @@ void Widget::setPosition(const Point &pos)
} }
} }
} }
Node::setPosition(pos); ProtectedNode::setPosition(pos);
} }
void Widget::setPositionPercent(const Point &percent) void Widget::setPositionPercent(const Point &percent)
@ -986,8 +830,11 @@ void Widget::copyClonedWidgetChildren(Widget* model)
for (auto& subWidget : modelChildren) for (auto& subWidget : modelChildren)
{ {
Widget* child = static_cast<Widget*>(subWidget); Widget* child = dynamic_cast<Widget*>(subWidget);
addChild(child->clone()); if (child)
{
addChild(child->clone());
}
} }
} }

View File

@ -25,7 +25,7 @@ THE SOFTWARE.
#ifndef __UIWIDGET_H__ #ifndef __UIWIDGET_H__
#define __UIWIDGET_H__ #define __UIWIDGET_H__
#include "CCNode.h" #include "ui/CCProtectedNode.h"
#include "ui/UILayoutDefine.h" #include "ui/UILayoutDefine.h"
#include "ui/UILayoutParameter.h" #include "ui/UILayoutParameter.h"
#include "ui/GUIDefine.h" #include "ui/GUIDefine.h"
@ -79,7 +79,7 @@ typedef void (Ref::*SEL_TouchEvent)(Ref*,TouchEventType);
* @js NA * @js NA
* @lua NA * @lua NA
*/ */
class Widget : public Node class Widget : public ProtectedNode
{ {
public: public:
/** /**
@ -199,114 +199,6 @@ public:
*/ */
float getTopInParent(); float getTopInParent();
/**
* Adds a child to the container with z-order as 0.
*
* If the child is added to a 'running' node, then 'onEnter' and 'onEnterTransitionDidFinish' will be called immediately.
*
* @param child A child node
*/
virtual void addChild(Node * child) override;
/**
* Adds a child to the container with a z-order
*
* If the child is added to a 'running' node, then 'onEnter' and 'onEnterTransitionDidFinish' will be called immediately.
*
* @param child A child node
* @param zOrder Z order for drawing priority. Please refer to setLocalZOrder(int)
*/
virtual void addChild(Node * child, int zOrder) override;
/**
* Adds a child to the container with z order and tag
*
* If the child is added to a 'running' node, then 'onEnter' and 'onEnterTransitionDidFinish' will be called immediately.
*
* @param child A child node
* @param zOrder Z order for drawing priority. Please refer to setLocalZOrder(int)
* @param tag A interger to identify the node easily. Please refer to setTag(int)
*/
virtual void addChild(Node* child, int zOrder, int tag) override;
/**
* Gets a child from the container with its tag
*
* @param tag An identifier to find the child node.
*
* @return a Node object whose tag equals to the input parameter
*/
virtual Node * getChildByTag(int tag) override;
virtual void sortAllChildren() override;
/**
* Return an array of children
*
* Composing a "tree" structure is a very important feature of Node
* Here's a sample code of traversing children array:
@code
Node* node = NULL;
CCARRAY_FOREACH(parent->getChildren(), node)
{
node->setPosition(0,0);
}
@endcode
* This sample code traverses all children nodes, and set their position to (0,0)
*
* @return An array of children
*/
virtual Vector<Node*>& getChildren() override;
virtual const Vector<Node*>& getChildren() const override;
/**
* Get the amount of children.
*
* @return The amount of children.
*/
virtual ssize_t getChildrenCount() const override;
/**
* Removes this node itself from its parent node with a cleanup.
* If the node orphan, then nothing happens.
* @see `removeFromParentAndCleanup(bool)`
*/
virtual void removeFromParent() override;
/**
* Removes this node itself from its parent node.
* If the node orphan, then nothing happens.
* @param cleanup true if all actions and callbacks on this node should be removed, false otherwise.
* @js removeFromParent
* @lua removeFromParent
*/
virtual void removeFromParentAndCleanup(bool cleanup) override;
/**
* Removes a child from the container. It will also cleanup all running actions depending on the cleanup parameter.
*
* @param child The child node which will be removed.
* @param cleanup true if all running actions and callbacks on the child node will be cleanup, false otherwise.
*/
virtual void removeChild(Node* child, bool cleanup = true) override;
/**
* Removes a child from the container by tag value. It will also cleanup all running actions depending on the cleanup parameter
*
* @param tag An interger number that identifies a child node
* @param cleanup true if all running actions and callbacks on the child node will be cleanup, false otherwise.
*/
virtual void removeChildByTag(int tag, bool cleanup = true) override;
/**
* Removes all children from the container with a cleanup.
*
* @see `removeAllChildrenWithCleanup(bool)`
*/
virtual void removeAllChildren() override;
/**
* Removes all children from the container, and do a cleanup to all running actions depending on the cleanup parameter.
*
* @param cleanup true if all running actions on all children nodes should be cleanup, false oterwise.
* @js removeAllChildren
* @lua removeAllChildren
*/
virtual void removeAllChildrenWithCleanup(bool cleanup) override;
/** /**
* Gets a child from the container with its name * Gets a child from the container with its name
* *
@ -316,22 +208,6 @@ public:
*/ */
virtual Widget* getChildByName(const char* name); virtual Widget* getChildByName(const char* name);
virtual void addNode(Node* node);
virtual void addNode(Node * node, int zOrder);
virtual void addNode(Node* node, int zOrder, int tag);
virtual Node * getNodeByTag(int tag);
virtual Vector<Node*>& getNodes();
virtual void removeNode(Node* node);
virtual void removeNodeByTag(int tag);
virtual void removeAllNodes();
virtual void visit(cocos2d::Renderer *renderer, const kmMat4 &parentTransform, bool parentTransformUpdated) override; virtual void visit(cocos2d::Renderer *renderer, const kmMat4 &parentTransform, bool parentTransformUpdated) override;
/** /**
@ -713,13 +589,11 @@ protected:
bool _reorderWidgetChildDirty; bool _reorderWidgetChildDirty;
bool _hitted; bool _hitted;
EventListenerTouchOneByOne* _touchListener; EventListenerTouchOneByOne* _touchListener;
Vector<Node*> _nodes;
Color3B _color; Color3B _color;
GLubyte _opacity; GLubyte _opacity;
bool _flippedX; bool _flippedX;
bool _flippedY; bool _flippedY;
Map<int, LayoutParameter*> _layoutParameterDictionary; Map<int, LayoutParameter*> _layoutParameterDictionary;
Vector<Node*> _widgetChildren;
}; };
} }

View File

@ -11,6 +11,7 @@
</ProjectConfiguration> </ProjectConfiguration>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\CCProtectedNode.h" />
<ClInclude Include="..\CocosGUI.h" /> <ClInclude Include="..\CocosGUI.h" />
<ClInclude Include="..\UIButton.h" /> <ClInclude Include="..\UIButton.h" />
<ClInclude Include="..\UICheckBox.h" /> <ClInclude Include="..\UICheckBox.h" />
@ -33,6 +34,7 @@
<ClInclude Include="..\UIWidget.h" /> <ClInclude Include="..\UIWidget.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\CCProtectedNode.cpp" />
<ClCompile Include="..\CocosGUI.cpp" /> <ClCompile Include="..\CocosGUI.cpp" />
<ClCompile Include="..\UIButton.cpp" /> <ClCompile Include="..\UIButton.cpp" />
<ClCompile Include="..\UICheckBox.cpp" /> <ClCompile Include="..\UICheckBox.cpp" />

View File

@ -78,6 +78,9 @@
<ClInclude Include="..\UIRichText.h"> <ClInclude Include="..\UIRichText.h">
<Filter>UIWidgets</Filter> <Filter>UIWidgets</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\CCProtectedNode.h">
<Filter>BaseClasses</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\UIScrollView.cpp"> <ClCompile Include="..\UIScrollView.cpp">
@ -137,5 +140,8 @@
<ClCompile Include="..\UIRichText.cpp"> <ClCompile Include="..\UIRichText.cpp">
<Filter>UIWidgets</Filter> <Filter>UIWidgets</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\CCProtectedNode.cpp">
<Filter>BaseClasses</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -36,7 +36,7 @@ bool UIWidgetAddNodeTest::init()
Sprite* sprite = Sprite::create("cocosui/ccicon.png"); Sprite* sprite = Sprite::create("cocosui/ccicon.png");
sprite->setPosition(Point(0, sprite->getBoundingBox().size.height / 4)); sprite->setPosition(Point(0, sprite->getBoundingBox().size.height / 4));
widget->addNode(sprite); widget->addChild(sprite);
return true; return true;
} }

View File

@ -41,7 +41,7 @@ bool UIWidgetAddNodeTest_Editor::init()
_layout->addChild(widget); _layout->addChild(widget);
Sprite* sprite = Sprite::create("cocosui/ccicon.png"); Sprite* sprite = Sprite::create("cocosui/ccicon.png");
widget->addNode(sprite); widget->addChild(sprite);
return true; return true;
} }