Merge pull request #8825 from liamcindy/v3

update for lay out
This commit is contained in:
minggo 2014-10-17 22:47:09 +08:00
commit 857f0c285c
5 changed files with 273 additions and 281 deletions

View File

@ -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<Widget*>(node);
if ( nullptr == uiWidget )
{
doLayout(node);
}
}
if (layoutComponent->isUsingPercentContentSize())
{
layoutComponent->setPercentContentSize(layoutComponent->getPercentContentSize());
}
}
}
}
}
NS_CC_END

View File

@ -81,6 +81,7 @@ public:
static void doLayout(Node *rootNode);
static void changeLayoutSystemActiveState(bool bActive);
};
}

View File

@ -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

View File

@ -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;

View File

@ -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<Widget*>(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