diff --git a/creator_project/packages/creator-luacpp-support/CreatorReader.fbs b/creator_project/packages/creator-luacpp-support/CreatorReader.fbs index 1b8eb15b..9df677b8 100644 --- a/creator_project/packages/creator-luacpp-support/CreatorReader.fbs +++ b/creator_project/packages/creator-luacpp-support/CreatorReader.fbs @@ -102,6 +102,7 @@ table Node tag:int = 0; anim:AnimationRef; colliders:[Collider]; + widget:Widget; groupIndex:int; } @@ -354,6 +355,24 @@ table Collider radius:float; // CircleCollider } +table Widget +{ + isAlignOnce:bool; + alignFlags:int; + left:float; + right:float; + top:float; + bottom:float; + verticalCenter:float; + horizontalCenter:float; + isAbsLeft:bool; + isAbsRight:bool; + isAbsTop:bool; + isAbsBottom:bool; + isAbsHorizontalCenter:bool; + isAbsVerticalCenter:bool; +} + table DragonBones { node:Node; diff --git a/creator_project/packages/creator-luacpp-support/core/parser/Node.js b/creator_project/packages/creator-luacpp-support/core/parser/Node.js index fba99c64..01345fa9 100644 --- a/creator_project/packages/creator-luacpp-support/core/parser/Node.js +++ b/creator_project/packages/creator-luacpp-support/core/parser/Node.js @@ -1,5 +1,6 @@ const state = require('./Global').state; const Collider = require('./Collider'); +const Widget = require('./Widget'); let Utils = require('./Utils'); const fs = require('fs'); @@ -194,6 +195,7 @@ class Node { this.parse_clip(); this.parse_colliders(); + this.parse_widget(); } parse_child(node_idx) { @@ -224,6 +226,13 @@ class Node { } } + parse_widget() { + let component = Node.get_node_components_of_type(this._node_data, 'cc.Widget'); + if(component.length === 1) { + this._properties.widget = Widget.parse(component[0]); + } + } + parse_clip() { let component = Node.get_node_component_of_type(this._node_data, 'cc.Animation'); if (component) { @@ -291,6 +300,29 @@ class Node { }); } + //scale + if (props.scale) { + result['scaleX'] = []; + result['scaleY'] = []; + + props.scale.forEach(function(scl) { + let valueX = { + frame: scl.frame, + value: scl.value['x'] + }; + parseCurveProperty(scl, valueX); + result['scaleX'].push(valueX) + + + let valueY = { + frame: scl.frame, + value: scl.value['y'] + }; + parseCurveProperty(scl, valueY); + result['scaleY'].push(valueY) + }); + } + // color if (props.color) { result.color = []; diff --git a/creator_project/packages/creator-luacpp-support/core/parser/Widget.js b/creator_project/packages/creator-luacpp-support/core/parser/Widget.js new file mode 100644 index 00000000..7068fd8f --- /dev/null +++ b/creator_project/packages/creator-luacpp-support/core/parser/Widget.js @@ -0,0 +1,34 @@ +let Utils = require('./Utils'); + +class Widget { + static parse(data) { + let result = {}; + + result.isAlignOnce = data.isAlignOnce; + result.alignFlags = data._alignFlags; + + // margin value, only support pixel, didn't support percentage + result.left = data._left; + result.right = data._right; + result.top = data._top; + result.bottom = data._bottom; + result.verticalCenter = data._verticalCenter; + result.horizontalCenter = data._horizontalCenter; + + // If true, value is pixel, otherwise is percentage (0 - 1) + // invalid value in cocos2d-x + result.isAbsLeft = data._isAbsLeft; + result.isAbsRight = data._isAbsRight; + result.isAbsTop = data._isAbsTop; + result.isAbsBottom = data._isAbsBottom; + result.isAbsHorizontalCenter = data._isAbsHorizontalCenter; + result.isAbsVerticalCenter = data._isAbsVerticalCenter; + + Utils.log("parse widget result value:" + JSON.stringify(result)); + + return result; + } +} + + +module.exports = Widget; \ No newline at end of file diff --git a/creator_project/packages/creator-luacpp-support/reader/CMakeLists.txt b/creator_project/packages/creator-luacpp-support/reader/CMakeLists.txt index b2063166..fa2a0b54 100644 --- a/creator_project/packages/creator-luacpp-support/reader/CMakeLists.txt +++ b/creator_project/packages/creator-luacpp-support/reader/CMakeLists.txt @@ -31,6 +31,7 @@ set(READER_HEADER Macros.h ui/RichtextStringVisitor.h ui/PageView.h + ui/WidgetExport.h ) set(READER_SOURCE @@ -46,6 +47,7 @@ set(READER_SOURCE CreatorReader.cpp ui/PageView.cpp ui/RichtextStringVisitor.cpp + ui/WidgetExport.cpp ) if(BUILD_LUA_LIBS) diff --git a/creator_project/packages/creator-luacpp-support/reader/CreatorReader.cpp b/creator_project/packages/creator-luacpp-support/reader/CreatorReader.cpp index 45989582..35ddd250 100644 --- a/creator_project/packages/creator-luacpp-support/reader/CreatorReader.cpp +++ b/creator_project/packages/creator-luacpp-support/reader/CreatorReader.cpp @@ -131,12 +131,23 @@ CreatorReader::CreatorReader() { _animationManager = new AnimationManager(); _collisionManager = new ColliderManager(); + _widgetManager = new WidgetManager(); + + _animationManager->autorelease(); + _collisionManager->autorelease(); + _widgetManager->autorelease(); + + CC_SAFE_RETAIN(_animationManager); + CC_SAFE_RETAIN(_collisionManager); + CC_SAFE_RETAIN(_widgetManager); + } CreatorReader::~CreatorReader() { CC_SAFE_RELEASE_NULL(_collisionManager); CC_SAFE_RELEASE_NULL(_animationManager); + CC_SAFE_RELEASE_NULL(_widgetManager); } CreatorReader* CreatorReader::createWithFilename(const std::string& filename) @@ -274,11 +285,14 @@ cocos2d::Scene* CreatorReader::getSceneGraph() const child->setPosition(child->getPosition() + _positionDiffDesignResolution); _animationManager->playOnLoad(); - + node->addChild(_collisionManager); node->addChild(_animationManager); _collisionManager->start(); + _widgetManager->setupWidgets(); + node->addChild(_widgetManager); + return static_cast(node); } @@ -292,6 +306,11 @@ ColliderManager* CreatorReader::getColliderManager() const return _collisionManager; } +WidgetManager* CreatorReader::getWidgetManager() const +{ + return _widgetManager; +} + std::string CreatorReader::getVersion() const { return _version; @@ -465,6 +484,8 @@ void CreatorReader::parseNode(cocos2d::Node* node, const buffers::Node* nodeBuff parseNodeAnimation(node, nodeBuffer); parseColliders(node, nodeBuffer); + + parseWidget(node, nodeBuffer); } void CreatorReader::parseNodeAnimation(cocos2d::Node* node, const buffers::Node* nodeBuffer) const @@ -599,6 +620,65 @@ void CreatorReader::parseColliders(cocos2d::Node* node, const buffers::Node* nod _collisionManager->addCollider(collider); } +void CreatorReader::parseWidget(cocos2d::Node *node, const buffers::Node *nodeBuffer) const +{ + const auto& info = nodeBuffer->widget(); + //auto pNode = dynamic_cast(node); + auto pNode = dynamic_cast(node); + if ((info != nullptr) && (pNode != nullptr)) { + // save the widget margin info + const auto& margin = ui::Margin(info->left(), info->top(), info->right(), info->bottom()); + auto parameter = ui::RelativeLayoutParameter::create(); + parameter->setMargin(margin); + + WidgetAdapter::AlignComb alignComb = static_cast(info->alignFlags()); + switch (alignComb) { + case WidgetAdapter::AlignComb::TOP_LEFT: + parameter->setAlign(cocos2d::ui::RelativeLayoutParameter::RelativeAlign::PARENT_TOP_LEFT); + break; + case WidgetAdapter::AlignComb::TOP_RIGHT: + parameter->setAlign(cocos2d::ui::RelativeLayoutParameter::RelativeAlign::PARENT_TOP_RIGHT); + break; + case WidgetAdapter::AlignComb::RIGHT_BOTTOM: + parameter->setAlign(cocos2d::ui::RelativeLayoutParameter::RelativeAlign::PARENT_RIGHT_BOTTOM); + break; + case WidgetAdapter::AlignComb::LEFT_BOTTOM: + parameter->setAlign(cocos2d::ui::RelativeLayoutParameter::RelativeAlign::PARENT_LEFT_BOTTOM); + break; + case WidgetAdapter::AlignComb::LEFT_CENTER_VERTICAL: + parameter->setAlign(cocos2d::ui::RelativeLayoutParameter::RelativeAlign::PARENT_LEFT_CENTER_VERTICAL); + break; + case WidgetAdapter::AlignComb::RIGHT_CENTER_VERTICAL: + parameter->setAlign(cocos2d::ui::RelativeLayoutParameter::RelativeAlign::PARENT_RIGHT_CENTER_VERTICAL); + break; + case WidgetAdapter::AlignComb::TOP_CENTER_HORIZONTAL: + parameter->setAlign(cocos2d::ui::RelativeLayoutParameter::RelativeAlign::PARENT_TOP_CENTER_HORIZONTAL); + break; + case WidgetAdapter::AlignComb::BOTTOM_CENTER_HORIZONTAL: + parameter->setAlign(cocos2d::ui::RelativeLayoutParameter::RelativeAlign::PARENT_BOTTOM_CENTER_HORIZONTAL); + break; + case WidgetAdapter::AlignComb::CENTER_IN_PARENT: + parameter->setAlign(cocos2d::ui::RelativeLayoutParameter::RelativeAlign::CENTER_IN_PARENT); + break; + default: + CCLOG("align combination of UI Node: %s isn't supported", node->getName().c_str()); + CCASSERT(false, "Only 9 creator align combinations are supported by cocos2d-x"); + break; + } + + + + auto widgetInfo = WidgetAdapter::create(); + // TODO: support Layout target, how to get the layout target? + // parameter->setRelativeToWidgetName(const std::string &name); + // widgetInfo->setLayoutTarget(cocos2d::Node *layoutTarget); + widgetInfo->setLayoutParameter(parameter); + widgetInfo->setAdaptNode(pNode); + widgetInfo->setIsAlignOnce(info->isAlignOnce()); + _widgetManager->_needAdaptWidgets.pushBack(widgetInfo); + } +} + cocos2d::Sprite* CreatorReader::createSprite(const buffers::Sprite* spriteBuffer) const { cocos2d::Sprite* sprite = cocos2d::Sprite::create(); diff --git a/creator_project/packages/creator-luacpp-support/reader/CreatorReader.h b/creator_project/packages/creator-luacpp-support/reader/CreatorReader.h index 3fc38d80..d14d20e3 100644 --- a/creator_project/packages/creator-luacpp-support/reader/CreatorReader.h +++ b/creator_project/packages/creator-luacpp-support/reader/CreatorReader.h @@ -34,6 +34,8 @@ #include "collider/ColliderManager.h" #include "dragonbones/DragonBonesHeaders.h" #include "dragonbones/cocos2dx/CCDragonBonesHeaders.h" +#include "ui/WidgetExport.h" +//#include "ui/NodeExport.h" @@ -62,6 +64,12 @@ class CreatorReader: public cocos2d::Ref */ ColliderManager* getColliderManager() const; + /** + Return the WidgetManager. It is added as a child of the Scene to make Creator Widget component take effect. + @return The `WidgetManager` of the scene + */ + WidgetManager* getWidgetManager() const; + /** Returns the FlatBuffers Schema version. @return a string containing the flatbuffer's schema version @@ -88,6 +96,7 @@ class CreatorReader: public cocos2d::Ref void parseNode(cocos2d::Node* node, const buffers::Node* nodeBuffer) const; void parseNodeAnimation(cocos2d::Node* node, const buffers::Node* nodeBuffer) const; void parseColliders(cocos2d::Node* node, const buffers::Node* nodeBuffer) const; + void parseWidget(cocos2d::Node* node, const buffers::Node* nodeBuffer) const; cocos2d::Sprite* createSprite(const buffers::Sprite* spriteBuffer) const; void parseSprite(cocos2d::Sprite* sprite, const buffers::Sprite* spriteBuffer) const; @@ -160,14 +169,19 @@ class CreatorReader: public cocos2d::Ref // variables cocos2d::Data _data; std::string _version; - + AnimationManager *_animationManager; ColliderManager *_collisionManager; + + // Widget in creator is a component used to do Layout + WidgetManager *_widgetManager; + +// NodeLayoutManager *_nodeLayoutManager; // creator will make scene at the center of screen when apply design solution strategy, cocos2d-x doesn't do it like this // this value record the diff cocos2d::Vec2 _positionDiffDesignResolution; - + CREATOR_DISALLOW_COPY_ASSIGN_AND_MOVE(CreatorReader); }; diff --git a/creator_project/packages/creator-luacpp-support/reader/CreatorReader_generated.h b/creator_project/packages/creator-luacpp-support/reader/CreatorReader_generated.h index f51df3df..3a14f668 100644 --- a/creator_project/packages/creator-luacpp-support/reader/CreatorReader_generated.h +++ b/creator_project/packages/creator-luacpp-support/reader/CreatorReader_generated.h @@ -68,6 +68,8 @@ struct AnimationRef; struct Collider; +struct Widget; + struct DragonBones; struct AnimationClip; @@ -875,7 +877,8 @@ struct Node FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { VT_TAG = 38, VT_ANIM = 40, VT_COLLIDERS = 42, - VT_GROUPINDEX = 44 + VT_WIDGET = 44, + VT_GROUPINDEX = 46 }; const Size *contentSize() const { return GetStruct(VT_CONTENTSIZE); } bool enabled() const { return GetField(VT_ENABLED, 1) != 0; } @@ -897,6 +900,7 @@ struct Node FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { int32_t tag() const { return GetField(VT_TAG, 0); } const AnimationRef *anim() const { return GetPointer(VT_ANIM); } const flatbuffers::Vector> *colliders() const { return GetPointer> *>(VT_COLLIDERS); } + const Widget *widget() const { return GetPointer(VT_WIDGET); } int32_t groupIndex() const { return GetField(VT_GROUPINDEX, 0); } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && @@ -924,6 +928,8 @@ struct Node FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { VerifyField(verifier, VT_COLLIDERS) && verifier.Verify(colliders()) && verifier.VerifyVectorOfTables(colliders()) && + VerifyField(verifier, VT_WIDGET) && + verifier.VerifyTable(widget()) && VerifyField(verifier, VT_GROUPINDEX) && verifier.EndTable(); } @@ -952,11 +958,12 @@ struct NodeBuilder { void add_tag(int32_t tag) { fbb_.AddElement(Node::VT_TAG, tag, 0); } void add_anim(flatbuffers::Offset anim) { fbb_.AddOffset(Node::VT_ANIM, anim); } void add_colliders(flatbuffers::Offset>> colliders) { fbb_.AddOffset(Node::VT_COLLIDERS, colliders); } + void add_widget(flatbuffers::Offset widget) { fbb_.AddOffset(Node::VT_WIDGET, widget); } void add_groupIndex(int32_t groupIndex) { fbb_.AddElement(Node::VT_GROUPINDEX, groupIndex, 0); } NodeBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); } NodeBuilder &operator=(const NodeBuilder &); flatbuffers::Offset Finish() { - auto o = flatbuffers::Offset(fbb_.EndTable(start_, 21)); + auto o = flatbuffers::Offset(fbb_.EndTable(start_, 22)); return o; } }; @@ -982,9 +989,11 @@ inline flatbuffers::Offset CreateNode(flatbuffers::FlatBufferBuilder &_fbb int32_t tag = 0, flatbuffers::Offset anim = 0, flatbuffers::Offset>> colliders = 0, + flatbuffers::Offset widget = 0, int32_t groupIndex = 0) { NodeBuilder builder_(_fbb); builder_.add_groupIndex(groupIndex); + builder_.add_widget(widget); builder_.add_colliders(colliders); builder_.add_anim(anim); builder_.add_tag(tag); @@ -1029,8 +1038,9 @@ inline flatbuffers::Offset CreateNodeDirect(flatbuffers::FlatBufferBuilder int32_t tag = 0, flatbuffers::Offset anim = 0, const std::vector> *colliders = nullptr, + flatbuffers::Offset widget = 0, int32_t groupIndex = 0) { - return CreateNode(_fbb, contentSize, enabled, name ? _fbb.CreateString(name) : 0, anchorPoint, cascadeOpacityEnabled, color, globalZOrder, localZOrder, opacity, opacityModifyRGB, position, rotationSkewX, rotationSkewY, scaleX, scaleY, skewX, skewY, tag, anim, colliders ? _fbb.CreateVector>(*colliders) : 0, groupIndex); + return CreateNode(_fbb, contentSize, enabled, name ? _fbb.CreateString(name) : 0, anchorPoint, cascadeOpacityEnabled, color, globalZOrder, localZOrder, opacity, opacityModifyRGB, position, rotationSkewX, rotationSkewY, scaleX, scaleY, skewX, skewY, tag, anim, colliders ? _fbb.CreateVector>(*colliders) : 0, widget, groupIndex); } struct Sprite FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { @@ -2755,6 +2765,115 @@ inline flatbuffers::Offset CreateColliderDirect(flatbuffers::FlatBuffe return CreateCollider(_fbb, type, offset, size, points ? _fbb.CreateVector(*points) : 0, radius); } +struct Widget FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + enum { + VT_ISALIGNONCE = 4, + VT_ALIGNFLAGS = 6, + VT_LEFT = 8, + VT_RIGHT = 10, + VT_TOP = 12, + VT_BOTTOM = 14, + VT_VERTICALCENTER = 16, + VT_HORIZONTALCENTER = 18, + VT_ISABSLEFT = 20, + VT_ISABSRIGHT = 22, + VT_ISABSTOP = 24, + VT_ISABSBOTTOM = 26, + VT_ISABSHORIZONTALCENTER = 28, + VT_ISABSVERTICALCENTER = 30 + }; + bool isAlignOnce() const { return GetField(VT_ISALIGNONCE, 0) != 0; } + int32_t alignFlags() const { return GetField(VT_ALIGNFLAGS, 0); } + float left() const { return GetField(VT_LEFT, 0.0f); } + float right() const { return GetField(VT_RIGHT, 0.0f); } + float top() const { return GetField(VT_TOP, 0.0f); } + float bottom() const { return GetField(VT_BOTTOM, 0.0f); } + float verticalCenter() const { return GetField(VT_VERTICALCENTER, 0.0f); } + float horizontalCenter() const { return GetField(VT_HORIZONTALCENTER, 0.0f); } + bool isAbsLeft() const { return GetField(VT_ISABSLEFT, 0) != 0; } + bool isAbsRight() const { return GetField(VT_ISABSRIGHT, 0) != 0; } + bool isAbsTop() const { return GetField(VT_ISABSTOP, 0) != 0; } + bool isAbsBottom() const { return GetField(VT_ISABSBOTTOM, 0) != 0; } + bool isAbsHorizontalCenter() const { return GetField(VT_ISABSHORIZONTALCENTER, 0) != 0; } + bool isAbsVerticalCenter() const { return GetField(VT_ISABSVERTICALCENTER, 0) != 0; } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_ISALIGNONCE) && + VerifyField(verifier, VT_ALIGNFLAGS) && + VerifyField(verifier, VT_LEFT) && + VerifyField(verifier, VT_RIGHT) && + VerifyField(verifier, VT_TOP) && + VerifyField(verifier, VT_BOTTOM) && + VerifyField(verifier, VT_VERTICALCENTER) && + VerifyField(verifier, VT_HORIZONTALCENTER) && + VerifyField(verifier, VT_ISABSLEFT) && + VerifyField(verifier, VT_ISABSRIGHT) && + VerifyField(verifier, VT_ISABSTOP) && + VerifyField(verifier, VT_ISABSBOTTOM) && + VerifyField(verifier, VT_ISABSHORIZONTALCENTER) && + VerifyField(verifier, VT_ISABSVERTICALCENTER) && + verifier.EndTable(); + } +}; + +struct WidgetBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_isAlignOnce(bool isAlignOnce) { fbb_.AddElement(Widget::VT_ISALIGNONCE, static_cast(isAlignOnce), 0); } + void add_alignFlags(int32_t alignFlags) { fbb_.AddElement(Widget::VT_ALIGNFLAGS, alignFlags, 0); } + void add_left(float left) { fbb_.AddElement(Widget::VT_LEFT, left, 0.0f); } + void add_right(float right) { fbb_.AddElement(Widget::VT_RIGHT, right, 0.0f); } + void add_top(float top) { fbb_.AddElement(Widget::VT_TOP, top, 0.0f); } + void add_bottom(float bottom) { fbb_.AddElement(Widget::VT_BOTTOM, bottom, 0.0f); } + void add_verticalCenter(float verticalCenter) { fbb_.AddElement(Widget::VT_VERTICALCENTER, verticalCenter, 0.0f); } + void add_horizontalCenter(float horizontalCenter) { fbb_.AddElement(Widget::VT_HORIZONTALCENTER, horizontalCenter, 0.0f); } + void add_isAbsLeft(bool isAbsLeft) { fbb_.AddElement(Widget::VT_ISABSLEFT, static_cast(isAbsLeft), 0); } + void add_isAbsRight(bool isAbsRight) { fbb_.AddElement(Widget::VT_ISABSRIGHT, static_cast(isAbsRight), 0); } + void add_isAbsTop(bool isAbsTop) { fbb_.AddElement(Widget::VT_ISABSTOP, static_cast(isAbsTop), 0); } + void add_isAbsBottom(bool isAbsBottom) { fbb_.AddElement(Widget::VT_ISABSBOTTOM, static_cast(isAbsBottom), 0); } + void add_isAbsHorizontalCenter(bool isAbsHorizontalCenter) { fbb_.AddElement(Widget::VT_ISABSHORIZONTALCENTER, static_cast(isAbsHorizontalCenter), 0); } + void add_isAbsVerticalCenter(bool isAbsVerticalCenter) { fbb_.AddElement(Widget::VT_ISABSVERTICALCENTER, static_cast(isAbsVerticalCenter), 0); } + WidgetBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); } + WidgetBuilder &operator=(const WidgetBuilder &); + flatbuffers::Offset Finish() { + auto o = flatbuffers::Offset(fbb_.EndTable(start_, 14)); + return o; + } +}; + +inline flatbuffers::Offset CreateWidget(flatbuffers::FlatBufferBuilder &_fbb, + bool isAlignOnce = false, + int32_t alignFlags = 0, + float left = 0.0f, + float right = 0.0f, + float top = 0.0f, + float bottom = 0.0f, + float verticalCenter = 0.0f, + float horizontalCenter = 0.0f, + bool isAbsLeft = false, + bool isAbsRight = false, + bool isAbsTop = false, + bool isAbsBottom = false, + bool isAbsHorizontalCenter = false, + bool isAbsVerticalCenter = false) { + WidgetBuilder builder_(_fbb); + builder_.add_horizontalCenter(horizontalCenter); + builder_.add_verticalCenter(verticalCenter); + builder_.add_bottom(bottom); + builder_.add_top(top); + builder_.add_right(right); + builder_.add_left(left); + builder_.add_alignFlags(alignFlags); + builder_.add_isAbsVerticalCenter(isAbsVerticalCenter); + builder_.add_isAbsHorizontalCenter(isAbsHorizontalCenter); + builder_.add_isAbsBottom(isAbsBottom); + builder_.add_isAbsTop(isAbsTop); + builder_.add_isAbsRight(isAbsRight); + builder_.add_isAbsLeft(isAbsLeft); + builder_.add_isAlignOnce(isAlignOnce); + return builder_.Finish(); +} + struct DragonBones FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { enum { VT_NODE = 4, diff --git a/creator_project/packages/creator-luacpp-support/reader/collider/ColliderManager.cpp b/creator_project/packages/creator-luacpp-support/reader/collider/ColliderManager.cpp index 2f587869..edb7ca03 100644 --- a/creator_project/packages/creator-luacpp-support/reader/collider/ColliderManager.cpp +++ b/creator_project/packages/creator-luacpp-support/reader/collider/ColliderManager.cpp @@ -150,7 +150,7 @@ void ColliderManager::removeCollider(creator::Collider *collider) _colliders.erase(found); // don't emit exit event as creator since the collider is not running scene - for (auto iter = _contracts.begin(), end = _contracts.end(); iter != end;) + for (auto iter = _contracts.begin() ; iter != _contracts.end();) { if ((*iter)->getCollider1() == collider || (*iter)->getCollider2() == collider) iter = _contracts.erase(iter); diff --git a/creator_project/packages/creator-luacpp-support/reader/ui/WidgetExport.cpp b/creator_project/packages/creator-luacpp-support/reader/ui/WidgetExport.cpp new file mode 100644 index 00000000..3c14e1f9 --- /dev/null +++ b/creator_project/packages/creator-luacpp-support/reader/ui/WidgetExport.cpp @@ -0,0 +1,202 @@ +/**************************************************************************** + Copyright (c) 2017 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 "WidgetExport.h" + + +NS_CCR_BEGIN + +WidgetAdapter* WidgetAdapter::create() +{ + auto adapter = new (std::nothrow) WidgetAdapter; + if (adapter && adapter->init()) { + adapter->autorelease(); + return adapter; + } + return nullptr; +} + +bool WidgetAdapter::init() +{ + //_layoutNode = cocos2d::ui::Layout::create(); + // _layoutNode->setLayoutType(cocos2d::ui::Layout::Type::RELATIVE); + + //CC_SAFE_RETAIN(_layoutNode); + return true; +} + +WidgetAdapter::WidgetAdapter() +: _isAlignOnce(true) +, _layoutTarget(nullptr) +, _needAdaptNode(nullptr) +{ + +} + +WidgetAdapter::~WidgetAdapter() +{ + // CC_SAFE_RELEASE(_layoutNode); + CC_SAFE_RELEASE(_parameter); +} + +void WidgetAdapter::setIsAlignOnce(bool isAlignOnce) +{ + _isAlignOnce = isAlignOnce; +} +void WidgetAdapter::setAdaptNode(cocos2d::Node* needAdaptNode) +{ + _needAdaptNode = needAdaptNode; +} + +void WidgetAdapter::setLayoutTarget(cocos2d::Node* layoutTarget) +{ + _layoutTarget = layoutTarget; +} + +void WidgetAdapter::setLayoutParameter(cocos2d::ui::RelativeLayoutParameter *parameter) +{ + CC_SAFE_RETAIN(parameter); + _parameter = parameter; +} + +void WidgetAdapter::syncLayoutProperty() +{ + auto sDesignSize = cocos2d::Director::getInstance()->getOpenGLView()->getDesignResolutionSize(); + auto adaptSize = _needAdaptNode->getContentSize(); + auto anchorPoint = _needAdaptNode->getAnchorPoint(); + auto targetSize = _layoutTarget->getContentSize(); + + + if (_needAdaptNode->getName().compare("root") == 0){ + _needAdaptNode->setContentSize(sDesignSize); + return; + } + + float x = 0.0f, y = 0.0f; + + const auto& margin = _parameter->getMargin(); + auto alignComb = _parameter->getAlign(); + + switch (alignComb) { + case cocos2d::ui::RelativeLayoutParameter::RelativeAlign::PARENT_TOP_LEFT: + x = margin.left + adaptSize.width*anchorPoint.x; + y = targetSize.height - (margin.top + adaptSize.height*(1.0 - anchorPoint.y)); + break; + case cocos2d::ui::RelativeLayoutParameter::RelativeAlign::PARENT_TOP_RIGHT: + x = targetSize.width - (margin.right + adaptSize.width*(1.0 - anchorPoint.x)); + y = targetSize.height - (margin.top + adaptSize.height*(1.0 - anchorPoint.y)); + break; + case cocos2d::ui::RelativeLayoutParameter::RelativeAlign::PARENT_RIGHT_BOTTOM: + x = targetSize.width - (margin.right + adaptSize.width*(1.0 - anchorPoint.x)); + y = margin.bottom + adaptSize.height*anchorPoint.y; + break; + case cocos2d::ui::RelativeLayoutParameter::RelativeAlign::PARENT_LEFT_BOTTOM: + x = margin.left + adaptSize.width*anchorPoint.x; + y = margin.bottom + adaptSize.height*anchorPoint.y; + break; + case cocos2d::ui::RelativeLayoutParameter::RelativeAlign::PARENT_LEFT_CENTER_VERTICAL: + x = margin.left + adaptSize.width*anchorPoint.x; + y = targetSize.height*0.5 + ((anchorPoint.y - 0.5)*adaptSize.height); + break; + case cocos2d::ui::RelativeLayoutParameter::RelativeAlign::PARENT_RIGHT_CENTER_VERTICAL: + x = targetSize.width - (margin.right + adaptSize.width*(1.0 - anchorPoint.x)); + y = targetSize.height*0.5 + ((anchorPoint.y - 0.5)*adaptSize.height); + break; + case cocos2d::ui::RelativeLayoutParameter::RelativeAlign::PARENT_TOP_CENTER_HORIZONTAL: + + x = targetSize.width*0.5 + ((anchorPoint.x - 0.5)*adaptSize.width); + y = targetSize.height - (margin.top + adaptSize.height*(1.0 - anchorPoint.y)); + break; + case cocos2d::ui::RelativeLayoutParameter::RelativeAlign::PARENT_BOTTOM_CENTER_HORIZONTAL: + x = targetSize.width*0.5 + ((anchorPoint.x - 0.5)*adaptSize.width); + y = margin.bottom + adaptSize.height*anchorPoint.y; + break; + case cocos2d::ui::RelativeLayoutParameter::RelativeAlign::CENTER_IN_PARENT: + x = targetSize.width*0.5 + ((anchorPoint.x - 0.5)*adaptSize.width); + y = targetSize.height*0.5+ ((anchorPoint.y - 0.5)*adaptSize.height); + break; + default: + + break; + } + + _needAdaptNode->setPosition(x, y); +} + +void WidgetAdapter::setupLayout() +{ + auto parent = _needAdaptNode->getParent(); + CCASSERT(parent != nullptr, "adaptNode's parent can't be null"); + + // set default layout target to parent node + if (_layoutTarget == nullptr) { + _layoutTarget = parent; + } + // _needAdaptNode->removeFromParentAndCleanup(false); + // _layoutNode->setName(PLUGIN_EXTRA_LAYOUT_NAME); + // _layoutNode->addChild(_needAdaptNode); + // parent->addChild(_layoutNode); +} + +WidgetManager::WidgetManager() +: _forceAlignDirty(false) +{ + +} + +WidgetManager::~WidgetManager() +{ + +} + +void WidgetManager::update(float dt) +{ + doAlign(); +} + +void WidgetManager::forceDoAlign() +{ + _forceAlignDirty = true; + doAlign(); +} + +void WidgetManager::doAlign() +{ + for (auto& adapter:_needAdaptWidgets) { + if(_forceAlignDirty || !(adapter->_isAlignOnce)) + { + adapter->syncLayoutProperty(); + } + } + _forceAlignDirty = false; +} + +void WidgetManager::setupWidgets() +{ + for (auto& adapter:_needAdaptWidgets) { + adapter->setupLayout(); + adapter->syncLayoutProperty(); + } + scheduleUpdate(); +} +NS_CCR_END diff --git a/creator_project/packages/creator-luacpp-support/reader/ui/WidgetExport.h b/creator_project/packages/creator-luacpp-support/reader/ui/WidgetExport.h new file mode 100644 index 00000000..c4ac5050 --- /dev/null +++ b/creator_project/packages/creator-luacpp-support/reader/ui/WidgetExport.h @@ -0,0 +1,116 @@ +/**************************************************************************** + Copyright (c) 2017 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. + ****************************************************************************/ +#pragma once + +#include "cocos2d.h" +#include "ui/CocosGUI.h" +#include "CreatorReader_generated.h" + +#include "Macros.h" + +NS_CCR_BEGIN + +// name of extra layout Node +#define PLUGIN_EXTRA_LAYOUT_NAME "Creator Widget to Cocos2d-x Layout" + +// creator align flag, see: https://github.com/cocos-creator/engine/blob/master/cocos2d/core/base-ui/CCWidgetManager.js +#define CREATOR_ALIGN_TOP (1 << 0) +#define CREATOR_ALIGN_MID (1 << 1) +#define CREATOR_ALIGN_BOT (1 << 2) +#define CREATOR_ALIGN_LEFT (1 << 3) +#define CREATOR_ALIGN_CENTER (1 << 4) +#define CREATOR_ALIGN_RIGHT (1 << 5) + +// support export the creator widget component to cocos2d-x layout +class WidgetAdapter : public cocos2d::Ref +{ + +public: + // only 9 creator align combinations are supported by cocos2d-x + enum class AlignComb + { + TOP_LEFT = CREATOR_ALIGN_LEFT | CREATOR_ALIGN_TOP, + TOP_CENTER_HORIZONTAL = CREATOR_ALIGN_CENTER | CREATOR_ALIGN_TOP, + TOP_RIGHT = CREATOR_ALIGN_TOP | CREATOR_ALIGN_RIGHT, + LEFT_CENTER_VERTICAL = CREATOR_ALIGN_MID | CREATOR_ALIGN_LEFT, + + CENTER_IN_PARENT = CREATOR_ALIGN_CENTER | CREATOR_ALIGN_MID, + + RIGHT_CENTER_VERTICAL = CREATOR_ALIGN_MID | CREATOR_ALIGN_RIGHT, + LEFT_BOTTOM = CREATOR_ALIGN_BOT | CREATOR_ALIGN_LEFT, + BOTTOM_CENTER_HORIZONTAL = CREATOR_ALIGN_CENTER | CREATOR_ALIGN_BOT, + RIGHT_BOTTOM = CREATOR_ALIGN_RIGHT | CREATOR_ALIGN_BOT + }; + + static WidgetAdapter* create(); + WidgetAdapter(); + virtual ~WidgetAdapter(); + + bool init(); + void setIsAlignOnce(bool isAlignOnce); + void setAdaptNode(cocos2d::Node* needAdaptNode); + + + void setLayoutParameter(cocos2d::ui::RelativeLayoutParameter *parameter); + + // TODO: support the align target of a widget component, default target is parent Node + void setLayoutTarget(cocos2d::Node* layoutTarget); +private: + friend class WidgetManager; + // only do layout align once if true + bool _isAlignOnce; + // widget layout target, it's a Node, default target is _needAdaptNode's parent + cocos2d::Node* _layoutTarget; + // the node include a widget component, it must be a UI Widget? + cocos2d::Node* _needAdaptNode; + // insert the _layout between _nodeNeedWidget and its parent + // cocos2d::ui::Layout* _layoutNode; + + cocos2d::ui::RelativeLayoutParameter *_parameter; + + // insert Layout Node to support widget component. + void setupLayout(); + // adapt layout property depend on _layoutTarget + void syncLayoutProperty(); +}; + +// manager all the widget component align +class WidgetManager : public cocos2d::Node +{ +public: + // check widget component property AlignOnce every frame, update align if this property set to false + virtual void update(float dt) override; + // do layout align manually, you should call it when you make layout content size different from scene in Creator. + void forceDoAlign(); +private: + friend class CreatorReader; + + WidgetManager(); + virtual ~WidgetManager(); + void setupWidgets(); + void doAlign(); + bool _forceAlignDirty; + cocos2d::Vector _needAdaptWidgets; +}; +NS_CCR_END