diff --git a/cocos/ui/UIHelper.cpp b/cocos/ui/UIHelper.cpp index 579a9cff5e..3fb3a92195 100644 --- a/cocos/ui/UIHelper.cpp +++ b/cocos/ui/UIHelper.cpp @@ -30,6 +30,8 @@ NS_CC_BEGIN namespace ui { +static bool _activeLayout = true; + Widget* Helper::seekWidgetByTag(Widget* root, int tag) { if (!root) @@ -147,37 +149,40 @@ std::string Helper::getSubStringOfUTF8String(const std::string& str, std::string return str.substr(min,max); } - void Helper::doLayout(cocos2d::Node *rootNode) - { - for(auto& node : rootNode->getChildren()) +void changeLayoutSystemActiveState(bool bActive) +{ + _activeLayout = bActive; +} +void Helper::doLayout(cocos2d::Node *rootNode) +{ + if(!_activeLayout) + { + return; + } + + for(auto& node : rootNode->getChildren()) + { + auto com = node->getComponent(__LAYOUT_COMPONENT_NAME); + Node *parent = node->getParent(); + if (nullptr != com && nullptr != parent) { + LayoutComponent* layoutComponent = (LayoutComponent*)com; + + if (layoutComponent->isUsingPercentPosition()) { - auto com = node->getComponent(__LAYOUT_COMPONENT_NAME); - Node *parent = node->getParent(); - if (nullptr != com && nullptr != parent) { - LayoutComponent* layoutComponent = (LayoutComponent*)com; + layoutComponent->setPercentPosition(layoutComponent->getPercentPosition()); + } + else if (layoutComponent->getReferencePoint() != LayoutComponent::ReferencePoint::BOTTOM_LEFT) + { + layoutComponent->setRelativePosition(layoutComponent->getRelativePosition()); + } - if (layoutComponent->isUsingPercentPosition()) - { - layoutComponent->RefreshLayoutPosition(LayoutComponent::PositionType::PreRelativePosition,layoutComponent->getPercentPosition()); - } - else if (layoutComponent->getReferencePoint() != LayoutComponent::ReferencePoint::BOTTOM_LEFT) - { - layoutComponent->RefreshLayoutPosition(LayoutComponent::PositionType::RelativePosition,layoutComponent->getRelativePosition()); - } - - if (layoutComponent->isUsingPercentContentSize()) - { - layoutComponent->RefreshLayoutSize(LayoutComponent::SizeType::PreSize,layoutComponent->getPercentContentSize()); - } - - Widget* uiWidget = dynamic_cast(node); - if ( nullptr == uiWidget ) - { - doLayout(node); - } - } + if (layoutComponent->isUsingPercentContentSize()) + { + layoutComponent->setPercentContentSize(layoutComponent->getPercentContentSize()); } } + } +} } NS_CC_END diff --git a/cocos/ui/UIHelper.h b/cocos/ui/UIHelper.h index 5d78a59fb1..072fcc79e8 100644 --- a/cocos/ui/UIHelper.h +++ b/cocos/ui/UIHelper.h @@ -81,6 +81,7 @@ public: static void doLayout(Node *rootNode); + static void changeLayoutSystemActiveState(bool bActive); }; } diff --git a/cocos/ui/UILayoutComponent.cpp b/cocos/ui/UILayoutComponent.cpp index 0dd4d3b5ef..61c0681ece 100644 --- a/cocos/ui/UILayoutComponent.cpp +++ b/cocos/ui/UILayoutComponent.cpp @@ -66,9 +66,24 @@ namespace ui { { return this->getOwner()->getContentSize(); } - void LayoutComponent::setOwnerContentSize(const Vec2& percent) + void LayoutComponent::setOwnerContentSize(const Vec2& size) { - this->RefreshLayoutSize(SizeType::Size,percent); + this->getOwner()->setContentSize(Size(size.x,size.y)); + + Node* parentNode = this->getOwner()->getParent(); + if (parentNode != NULL && _actived) + { + Size parentSize = parentNode->getContentSize(); + + if (parentSize.width != 0 && parentSize.height != 0) + { + _percentContentSize = Point(size.x/parentSize.width,size.y/parentSize.height); + } + else + { + _percentContentSize = Point(0,0); + } + } } const Vec2& LayoutComponent::getPercentContentSize()const @@ -78,7 +93,17 @@ namespace ui { void LayoutComponent::setPercentContentSize(const Vec2& percent) { - this->RefreshLayoutSize(SizeType::PreSize,percent); + _percentContentSize = percent; + + Node* parentNode = this->getOwner()->getParent(); + if (parentNode != NULL && _actived) + { + Size parentSize = parentNode->getContentSize(); + if (_usingPercentContentSize) + { + this->getOwner()->setContentSize(Size(percent.x*parentSize.width,percent.y*parentSize.height)); + } + } } bool LayoutComponent::isUsingPercentContentSize() @@ -89,79 +114,35 @@ namespace ui { void LayoutComponent::setUsingPercentContentSize(bool flag) { _usingPercentContentSize = flag; - this->RefreshLayoutSize(SizeType::PreSizeEnable,Vec2(0,0)); - } - void LayoutComponent::RefreshLayoutSize(SizeType sType, const Vec2& size) - { Node* parentNode = this->getOwner()->getParent(); if (parentNode != NULL && _actived) { Size parentSize = parentNode->getContentSize(); - - switch (sType) + if (_usingPercentContentSize) { - case SizeType::Size: - if (parentSize.width != 0 && parentSize.height != 0) + Size baseSize = this->getOwner()->getContentSize(); + if (parentSize.width != 0) { - _percentContentSize = Point(size.x/parentSize.width,size.y/parentSize.height); + _percentContentSize.x = baseSize.width/parentSize.width; } else { - _percentContentSize = Point(0,0); + _percentContentSize.x = 0; + baseSize.width = 0; } - this->getOwner()->setContentSize(Size(size.x,size.y)); - break; - case SizeType::PreSize: - _percentContentSize = size; - if (_usingPercentContentSize) - { - this->getOwner()->setContentSize(Size(size.x*parentSize.width,size.y*parentSize.height)); - } - break; - case SizeType::PreSizeEnable: - if (_usingPercentContentSize) - { - Size baseSize = this->getOwner()->getContentSize(); - if (parentSize.width != 0) - { - _percentContentSize.x = baseSize.width/parentSize.width; - } - else - { - _percentContentSize.x = 0; - baseSize.width = 0; - } - if (parentSize.height != 0) - { - _percentContentSize.y = baseSize.height/parentSize.height; - } - else - { - _percentContentSize.y = 0; - baseSize.height = 0; - } - - this->getOwner()->setContentSize(baseSize); + if (parentSize.height != 0) + { + _percentContentSize.y = baseSize.height/parentSize.height; } - break; - default: - break; - } - } - else - { - switch (sType) - { - case SizeType::Size: - this->getOwner()->setContentSize(Size(size.x,size.y)); - break; - case SizeType::PreSize: - _percentContentSize = size; - break; - default: - break; + else + { + _percentContentSize.y = 0; + baseSize.height = 0; + } + + this->getOwner()->setContentSize(baseSize); } } } @@ -174,7 +155,38 @@ namespace ui { void LayoutComponent::setUsingPercentPosition(bool flag) { _usingPercentPosition = flag; - this->RefreshLayoutPosition(PositionType::PreRelativePositionEnable,Vec2(0,0)); + + Node* parentNode = this->getOwner()->getParent(); + if (parentNode != NULL && _actived) + { + Size parentSize = parentNode->getContentSize(); + + if (_usingPercentPosition) + { + if (parentSize.width != 0) + { + _percentPosition.x = _relativePosition.x/parentSize.width; + } + else + { + _percentPosition.x = 0; + _relativePosition.x = 0; + } + + if (parentSize.height != 0) + { + _percentPosition.y = _relativePosition.y/parentSize.height; + } + else + { + _percentPosition.y = 0; + _relativePosition.y = 0; + } + } + + Point inversePoint = this->converPointWithReferencePointAndSize(_relativePosition,parentSize); + this->getOwner()->setPosition(inversePoint); + } } const Vec2& LayoutComponent::getPercentPosition() @@ -183,7 +195,16 @@ namespace ui { } void LayoutComponent::setPercentPosition(const Vec2& percent) { - this->RefreshLayoutPosition(PositionType::PreRelativePosition,percent); + _percentPosition = percent; + + Node* parentNode = this->getOwner()->getParent(); + if (parentNode != NULL && _actived) + { + Size parentSize = parentNode->getContentSize(); + _relativePosition = Point(_percentPosition.x*parentSize.width,_percentPosition.y*parentSize.height); + Point inversePoint = this->converPointWithReferencePointAndSize(_relativePosition,parentSize); + this->getOwner()->setPosition(inversePoint); + } } const Vec2& LayoutComponent::getOwnerPosition()const @@ -192,7 +213,32 @@ namespace ui { } void LayoutComponent::setOwnerPosition(const Vec2& point) { - this->RefreshLayoutPosition(PositionType::Position,point); + Node* parentNode = this->getOwner()->getParent(); + if (parentNode != NULL && _actived) + { + Size parentSize = parentNode->getContentSize(); + + Point inversePoint = this->converPointWithReferencePointAndSize(point,parentSize); + this->getOwner()->setPosition(point); + _relativePosition = inversePoint; + if (parentSize.width != 0 && parentSize.height != 0) + { + _percentPosition = Point(_relativePosition.x/parentSize.width,_relativePosition.y/parentSize.height); + } + else + { + _percentPosition = Point(0,0); + } + } + else + { + this->getOwner()->setPosition(point); + if (_referencePoint == ReferencePoint::BOTTOM_LEFT) + { + _relativePosition = point; + } + } + } const Vec2& LayoutComponent::getRelativePosition() @@ -201,7 +247,24 @@ namespace ui { } void LayoutComponent::setRelativePosition(const Vec2& position) { - this->RefreshLayoutPosition(PositionType::RelativePosition,position); + _relativePosition = position; + + Node* parentNode = this->getOwner()->getParent(); + if (parentNode != NULL && _actived) + { + Size parentSize = parentNode->getContentSize(); + + Point inversePoint = this->converPointWithReferencePointAndSize(_relativePosition,parentSize); + this->getOwner()->setPosition(inversePoint); + if (parentSize.width != 0 && parentSize.height != 0) + { + _percentPosition = Point(_relativePosition.x/parentSize.width,_relativePosition.y/parentSize.height); + } + else + { + _percentPosition = Point(0,0); + } + } } LayoutComponent::ReferencePoint LayoutComponent::getReferencePoint() @@ -211,131 +274,34 @@ namespace ui { void LayoutComponent::setReferencePoint(ReferencePoint point) { _referencePoint = point; - this->RefreshLayoutPosition(PositionType::RelativePosition,_relativePosition); + this->setRelativePosition(_relativePosition); } - void LayoutComponent::RefreshLayoutPosition(PositionType pType,const Vec2& point) - { - Node* parentNode = this->getOwner()->getParent(); - Point basePoint = point; - if (parentNode != NULL && _actived) - { - Size parentSize = parentNode->getContentSize(); - - if ( pType == PositionType::PreRelativePosition) - { - _percentPosition = point; - basePoint = Point(_percentPosition.x*parentSize.width,_percentPosition.y*parentSize.height); - } - else if(pType == PositionType::PreRelativePositionEnable) - { - if (_usingPercentPosition) - { - if (parentSize.width != 0) - { - _percentPosition.x = _relativePosition.x/parentSize.width; - } - else - { - _percentPosition.x = 0; - _relativePosition.x = 0; - } - - if (parentSize.height != 0) - { - _percentPosition.y = _relativePosition.y/parentSize.height; - } - else - { - _percentPosition.y = 0; - _relativePosition.y = 0; - } - } - basePoint = _relativePosition; - } - - Point inversePoint = basePoint; - switch (_referencePoint) - { - case ReferencePoint::TOP_LEFT: - inversePoint.y = parentSize.height - inversePoint.y; - break; - case ReferencePoint::BOTTOM_RIGHT: - inversePoint.x = parentSize.width - inversePoint.x; - break; - case ReferencePoint::TOP_RIGHT: - inversePoint.x = parentSize.width - inversePoint.x; - inversePoint.y = parentSize.height - inversePoint.y; - break; - default: - break; - } - - switch (pType) - { - case PositionType::Position: - this->getOwner()->setPosition(basePoint); - _relativePosition = inversePoint; - if (parentSize.width != 0 && parentSize.height != 0) - { - _percentPosition = Point(_relativePosition.x/parentSize.width,_relativePosition.y/parentSize.height); - } - else - { - _percentPosition = Point(0,0); - } - break; - case PositionType::RelativePosition: - this->getOwner()->setPosition(inversePoint); - _relativePosition = basePoint; - if (parentSize.width != 0 && parentSize.height != 0) - { - _percentPosition = Point(_relativePosition.x/parentSize.width,_relativePosition.y/parentSize.height); - } - else - { - _percentPosition = Point(0,0); - } - break; - case PositionType::PreRelativePosition: - this->getOwner()->setPosition(inversePoint); - _relativePosition = basePoint; - break; - case PositionType::PreRelativePositionEnable: - this->getOwner()->setPosition(inversePoint); - _relativePosition = basePoint; - break; - default: - break; - } - } - else - { - switch (pType) - { - case PositionType::Position: - this->getOwner()->setPosition(basePoint); - if (_referencePoint == ReferencePoint::BOTTOM_LEFT) - { - _relativePosition = basePoint; - } - break; - case PositionType::RelativePosition: - _relativePosition = basePoint; - break; - case PositionType::PreRelativePosition: - _percentPosition = basePoint; - break; - default: - break; - } - } - } - - void LayoutComponent::SetActiveEnable(bool enable) + void LayoutComponent::setActiveEnable(bool enable) { _actived = enable; } + + Vec2 LayoutComponent::converPointWithReferencePointAndSize(const Vec2& point,const Size& size) + { + Point inversePoint = point; + switch (_referencePoint) + { + case ReferencePoint::TOP_LEFT: + inversePoint.y = size.height - inversePoint.y; + break; + case ReferencePoint::BOTTOM_RIGHT: + inversePoint.x = size.width - inversePoint.x; + break; + case ReferencePoint::TOP_RIGHT: + inversePoint.x = size.width - inversePoint.x; + inversePoint.y = size.height - inversePoint.y; + break; + default: + break; + } + return inversePoint; + } } NS_CC_END \ No newline at end of file diff --git a/cocos/ui/UILayoutComponent.h b/cocos/ui/UILayoutComponent.h index 83c142b9a0..1c16bfc966 100644 --- a/cocos/ui/UILayoutComponent.h +++ b/cocos/ui/UILayoutComponent.h @@ -53,21 +53,6 @@ NS_CC_BEGIN TOP_RIGHT }; - enum class PositionType - { - Position, - RelativePosition, - PreRelativePosition, - PreRelativePositionEnable - }; - - enum class SizeType - { - Size, - PreSize, - PreSizeEnable - }; - bool isUsingPercentPosition(); void setUsingPercentPosition(bool flag); @@ -83,10 +68,8 @@ NS_CC_BEGIN const Vec2& getOwnerPosition()const; void setOwnerPosition(const Vec2& point); - void RefreshLayoutPosition(PositionType pType,const Vec2& point); - const Vec2& getOwnerContentSize()const; - void setOwnerContentSize(const Vec2& percent); + void setOwnerContentSize(const Vec2& size); const Vec2& getPercentContentSize()const; void setPercentContentSize(const Vec2& percent); @@ -94,9 +77,9 @@ NS_CC_BEGIN bool isUsingPercentContentSize(); void setUsingPercentContentSize(bool flag); - void RefreshLayoutSize(SizeType sType, const Vec2& size); - - void SetActiveEnable(bool enable); + void setActiveEnable(bool enable); + private: + Vec2 converPointWithReferencePointAndSize(const Vec2& point,const Size& size); private: Vec2 _percentContentSize; diff --git a/cocos/ui/UIWidget.cpp b/cocos/ui/UIWidget.cpp index 4ccdba0db0..c5a8275cd9 100644 --- a/cocos/ui/UIWidget.cpp +++ b/cocos/ui/UIWidget.cpp @@ -219,13 +219,8 @@ bool Widget::init() void Widget::onEnter() { + updateSizeAndPosition(); ProtectedNode::onEnter(); - if (_positionType == PositionType::PERCENT - || _sizeType == SizeType::PERCENT) { - if (_parent) { - Helper::doLayout(_parent); - } - } } void Widget::onExit() @@ -283,7 +278,30 @@ void Widget::setContentSize(const cocos2d::Size &contentSize) { _contentSize = getVirtualRendererSize(); } - + if (_running) + { + Widget* widgetParent = getWidgetParent(); + Size pSize; + if (widgetParent) + { + pSize = widgetParent->getContentSize(); + } + else + { + pSize = _parent->getContentSize(); + } + float spx = 0.0f; + float spy = 0.0f; + if (pSize.width > 0.0f) + { + spx = _customSize.width / pSize.width; + } + if (pSize.height > 0.0f) + { + spy = _customSize.height / pSize.height; + } + _sizePercent = Vec2(spx, spy); + } onSizeChanged(); } @@ -294,15 +312,29 @@ void Widget::setSize(const Size &size) void Widget::setSizePercent(const Vec2 &percent) { - - auto component = this->getOrCreateLayoutComponent(); - component->setUsingPercentContentSize(true); - component->setPercentContentSize(percent); - - if (nullptr != _parent) + _sizePercent = percent; + Size cSize = _customSize; + if (_running) { - Helper::doLayout(_parent); + Widget* widgetParent = getWidgetParent(); + if (widgetParent) + { + cSize = Size(widgetParent->getContentSize().width * percent.x , widgetParent->getContentSize().height * percent.y); + } + else + { + cSize = Size(_parent->getContentSize().width * percent.x , _parent->getContentSize().height * percent.y); + } } + if (_ignoreSize) + { + this->setContentSize(getVirtualRendererSize()); + } + else + { + this->setContentSize(cSize); + } + _customSize = cSize; } void Widget::updateSizeAndPosition() @@ -387,17 +419,6 @@ void Widget::updateSizeAndPosition(const cocos2d::Size &parentSize) void Widget::setSizeType(SizeType type) { _sizeType = type; - - auto component = this->getOrCreateLayoutComponent(); - - if (_sizeType == Widget::SizeType::PERCENT) - { - component->setUsingPercentContentSize(true); - } - else - { - component->setUsingPercentContentSize(false); - } } Widget::SizeType Widget::getSizeType() const @@ -445,9 +466,7 @@ const Size& Widget::getCustomSize() const const Vec2& Widget::getSizePercent() { - auto component = this->getOrCreateLayoutComponent(); - - return component->getPercentContentSize(); + return _sizePercent; } Vec2 Widget::getWorldPosition()const @@ -462,7 +481,14 @@ Node* Widget::getVirtualRenderer() void Widget::onSizeChanged() { - Helper::doLayout(this); + for (auto& child : getChildren()) + { + Widget* widgetChild = dynamic_cast(child); + if (widgetChild) + { + widgetChild->updateSizeAndPosition(); + } + } } Size Widget::getVirtualRendererSize() const @@ -914,36 +940,47 @@ void Widget::interceptTouchEvent(cocos2d::ui::Widget::TouchEventType event, coco void Widget::setPosition(const Vec2 &pos) { + if (_running) + { + Widget* widgetParent = getWidgetParent(); + if (widgetParent) + { + Size pSize = widgetParent->getContentSize(); + if (pSize.width <= 0.0f || pSize.height <= 0.0f) + { + _positionPercent = Vec2::ZERO; + } + else + { + _positionPercent = Vec2(pos.x / pSize.width, pos.y / pSize.height); + } + } + } ProtectedNode::setPosition(pos); - _positionType = PositionType::ABSOLUTE; - } void Widget::setPositionPercent(const Vec2 &percent) { - this->setNormalizedPosition(percent); - _positionType = PositionType::PERCENT; + _positionPercent = percent; + if (_running) + { + Widget* widgetParent = getWidgetParent(); + if (widgetParent) + { + Size parentSize = widgetParent->getContentSize(); + Vec2 absPos = Vec2(parentSize.width * _positionPercent.x, parentSize.height * _positionPercent.y); + setPosition(absPos); + } + } } const Vec2& Widget::getPositionPercent()const{ - return this->getNormalizedPosition(); + return _positionPercent; } void Widget::setPositionType(PositionType type) { _positionType = type; - if (type == Widget::PositionType::ABSOLUTE) - { - Vec2 oldPosition = this->getPosition(); - this->setPosition(this->getPosition() + Vec2(10,0)); - this->setPosition(oldPosition); - } - else - { - Vec2 oldNormalizedPosition = this->getNormalizedPosition(); - this->setNormalizedPosition(oldNormalizedPosition + Vec2(0.2,0.1)); - this->setNormalizedPosition(oldNormalizedPosition); - } } Widget::PositionType Widget::getPositionType() const