2019-11-23 20:27:39 +08:00
|
|
|
/****************************************************************************
|
|
|
|
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
|
|
|
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2019-11-23 20:27:39 +08:00
|
|
|
http://www.cocos2d-x.org
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2019-11-23 20:27:39 +08:00
|
|
|
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:
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2019-11-23 20:27:39 +08:00
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
|
|
all copies or substantial portions of the Software.
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2019-11-23 20:27:39 +08:00
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
|
THE SOFTWARE.
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#include "ui/UILayoutManager.h"
|
|
|
|
#include "ui/UILayout.h"
|
|
|
|
|
|
|
|
NS_CC_BEGIN
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
namespace ui
|
|
|
|
{
|
2019-11-23 20:27:39 +08:00
|
|
|
|
|
|
|
LinearHorizontalLayoutManager* LinearHorizontalLayoutManager::create()
|
|
|
|
{
|
2021-12-08 00:11:53 +08:00
|
|
|
LinearHorizontalLayoutManager* ret = new LinearHorizontalLayoutManager();
|
|
|
|
ret->autorelease();
|
|
|
|
return ret;
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2019-11-23 20:27:39 +08:00
|
|
|
void LinearHorizontalLayoutManager::doLayout(LayoutProtocol* layout)
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
Vec2 layoutSize = layout->getLayoutContentSize();
|
2019-11-23 20:27:39 +08:00
|
|
|
Vector<Node*> container = layout->getLayoutElements();
|
2021-12-25 10:04:45 +08:00
|
|
|
float leftBoundary = 0.0f;
|
2019-11-23 20:27:39 +08:00
|
|
|
for (auto& subWidget : container)
|
|
|
|
{
|
|
|
|
Widget* child = dynamic_cast<Widget*>(subWidget);
|
|
|
|
if (child)
|
|
|
|
{
|
|
|
|
LinearLayoutParameter* layoutParameter = dynamic_cast<LinearLayoutParameter*>(child->getLayoutParameter());
|
|
|
|
if (layoutParameter)
|
|
|
|
{
|
|
|
|
LinearLayoutParameter::LinearGravity childGravity = layoutParameter->getGravity();
|
2021-12-25 10:04:45 +08:00
|
|
|
Vec2 ap = child->getAnchorPoint();
|
|
|
|
Vec2 cs = child->getBoundingBox().size;
|
|
|
|
float finalPosX = leftBoundary + (ap.x * cs.width);
|
|
|
|
float finalPosY = layoutSize.height - (1.0f - ap.y) * cs.height;
|
2019-11-23 20:27:39 +08:00
|
|
|
switch (childGravity)
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
case LinearLayoutParameter::LinearGravity::NONE:
|
|
|
|
case LinearLayoutParameter::LinearGravity::TOP:
|
|
|
|
break;
|
|
|
|
case LinearLayoutParameter::LinearGravity::BOTTOM:
|
|
|
|
finalPosY = ap.y * cs.height;
|
|
|
|
break;
|
|
|
|
case LinearLayoutParameter::LinearGravity::CENTER_VERTICAL:
|
|
|
|
finalPosY = layoutSize.height / 2.0f - cs.height * (0.5f - ap.y);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
|
|
|
Margin mg = layoutParameter->getMargin();
|
|
|
|
finalPosX += mg.left;
|
|
|
|
finalPosY -= mg.top;
|
|
|
|
child->setPosition(Vec2(finalPosX, finalPosY));
|
|
|
|
leftBoundary = child->getRightBoundary() + mg.right;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
|
|
|
|
// LinearVerticalLayoutManager
|
2019-11-23 20:27:39 +08:00
|
|
|
LinearVerticalLayoutManager* LinearVerticalLayoutManager::create()
|
|
|
|
{
|
2021-12-08 00:11:53 +08:00
|
|
|
LinearVerticalLayoutManager* ret = new LinearVerticalLayoutManager();
|
|
|
|
ret->autorelease();
|
|
|
|
return ret;
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2019-11-23 20:27:39 +08:00
|
|
|
void LinearVerticalLayoutManager::doLayout(LayoutProtocol* layout)
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
Vec2 layoutSize = layout->getLayoutContentSize();
|
2019-11-23 20:27:39 +08:00
|
|
|
Vector<Node*> container = layout->getLayoutElements();
|
2021-12-25 10:04:45 +08:00
|
|
|
float topBoundary = layoutSize.height;
|
|
|
|
|
2019-11-23 20:27:39 +08:00
|
|
|
for (auto& subWidget : container)
|
|
|
|
{
|
|
|
|
LayoutParameterProtocol* child = dynamic_cast<LayoutParameterProtocol*>(subWidget);
|
|
|
|
if (child)
|
|
|
|
{
|
|
|
|
LinearLayoutParameter* layoutParameter = dynamic_cast<LinearLayoutParameter*>(child->getLayoutParameter());
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2019-11-23 20:27:39 +08:00
|
|
|
if (layoutParameter)
|
|
|
|
{
|
|
|
|
LinearLayoutParameter::LinearGravity childGravity = layoutParameter->getGravity();
|
2021-12-25 10:04:45 +08:00
|
|
|
Vec2 ap = subWidget->getAnchorPoint();
|
|
|
|
Vec2 cs = subWidget->getBoundingBox().size;
|
|
|
|
float finalPosX = ap.x * cs.width;
|
|
|
|
float finalPosY = topBoundary - ((1.0f - ap.y) * cs.height);
|
2019-11-23 20:27:39 +08:00
|
|
|
switch (childGravity)
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
case LinearLayoutParameter::LinearGravity::NONE:
|
|
|
|
case LinearLayoutParameter::LinearGravity::LEFT:
|
|
|
|
break;
|
|
|
|
case LinearLayoutParameter::LinearGravity::RIGHT:
|
|
|
|
finalPosX = layoutSize.width - ((1.0f - ap.x) * cs.width);
|
|
|
|
break;
|
|
|
|
case LinearLayoutParameter::LinearGravity::CENTER_HORIZONTAL:
|
|
|
|
finalPosX = layoutSize.width / 2.0f - cs.width * (0.5f - ap.x);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
|
|
|
Margin mg = layoutParameter->getMargin();
|
|
|
|
finalPosX += mg.left;
|
|
|
|
finalPosY -= mg.top;
|
|
|
|
subWidget->setPosition(finalPosX, finalPosY);
|
2021-12-25 10:04:45 +08:00
|
|
|
topBoundary = subWidget->getPosition().y -
|
|
|
|
subWidget->getAnchorPoint().y * subWidget->getBoundingBox().size.height - mg.bottom;
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-04-22 22:01:47 +08:00
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
// LinearCenterVerticalLayoutManager
|
2021-04-22 22:01:47 +08:00
|
|
|
LinearCenterVerticalLayoutManager* LinearCenterVerticalLayoutManager::create()
|
|
|
|
{
|
2021-12-08 00:11:53 +08:00
|
|
|
auto* ret = new LinearCenterVerticalLayoutManager();
|
|
|
|
ret->autorelease();
|
|
|
|
return ret;
|
2021-04-22 22:01:47 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void LinearCenterVerticalLayoutManager::doLayout(LayoutProtocol* layout)
|
|
|
|
{
|
|
|
|
const auto layoutSize = layout->getLayoutContentSize();
|
2021-12-25 10:04:45 +08:00
|
|
|
auto&& container = layout->getLayoutElements();
|
|
|
|
auto topBoundary = layoutSize.height;
|
2021-04-22 22:01:47 +08:00
|
|
|
|
|
|
|
auto totalHeight = 0.f;
|
|
|
|
// need to get total sub-widget height
|
|
|
|
for (auto&& subWidget : container)
|
|
|
|
{
|
|
|
|
auto* child = dynamic_cast<LayoutParameterProtocol*>(subWidget);
|
|
|
|
if (child)
|
|
|
|
{
|
|
|
|
auto* layoutParameter = dynamic_cast<LinearLayoutParameter*>(child->getLayoutParameter());
|
|
|
|
if (layoutParameter)
|
|
|
|
{
|
|
|
|
auto&& mg = layoutParameter->getMargin();
|
|
|
|
totalHeight += subWidget->getBoundingBox().size.height + mg.top + mg.bottom;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
topBoundary = topBoundary - (topBoundary - totalHeight) / 2.f;
|
|
|
|
|
|
|
|
for (auto&& subWidget : container)
|
|
|
|
{
|
|
|
|
auto* child = dynamic_cast<LayoutParameterProtocol*>(subWidget);
|
|
|
|
if (child)
|
|
|
|
{
|
|
|
|
auto* layoutParameter = dynamic_cast<LinearLayoutParameter*>(child->getLayoutParameter());
|
|
|
|
|
|
|
|
if (layoutParameter)
|
|
|
|
{
|
|
|
|
const auto childGravity = layoutParameter->getGravity();
|
2021-12-25 10:04:45 +08:00
|
|
|
const auto ap = subWidget->getAnchorPoint();
|
|
|
|
const auto cs = subWidget->getBoundingBox().size;
|
|
|
|
auto finalPosX = ap.x * cs.width;
|
|
|
|
auto finalPosY = topBoundary - ((1.0f - ap.y) * cs.height);
|
2021-04-22 22:01:47 +08:00
|
|
|
switch (childGravity)
|
|
|
|
{
|
|
|
|
case LinearLayoutParameter::LinearGravity::NONE:
|
|
|
|
case LinearLayoutParameter::LinearGravity::LEFT:
|
|
|
|
break;
|
|
|
|
case LinearLayoutParameter::LinearGravity::RIGHT:
|
|
|
|
finalPosX = layoutSize.width - ((1.0f - ap.x) * cs.width);
|
|
|
|
break;
|
|
|
|
case LinearLayoutParameter::LinearGravity::CENTER_HORIZONTAL:
|
|
|
|
finalPosX = layoutSize.width / 2.0f - cs.width * (0.5f - ap.x);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
auto&& mg = layoutParameter->getMargin();
|
|
|
|
finalPosX += mg.left;
|
|
|
|
finalPosY -= mg.top;
|
|
|
|
subWidget->setPosition(finalPosX, finalPosY);
|
2021-12-25 10:04:45 +08:00
|
|
|
topBoundary = subWidget->getPosition().y -
|
|
|
|
subWidget->getAnchorPoint().y * subWidget->getBoundingBox().size.height - mg.bottom;
|
2021-04-22 22:01:47 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
// RelativeLayoutManager
|
2019-11-23 20:27:39 +08:00
|
|
|
|
|
|
|
RelativeLayoutManager* RelativeLayoutManager::create()
|
|
|
|
{
|
2021-12-08 00:11:53 +08:00
|
|
|
RelativeLayoutManager* ret = new RelativeLayoutManager();
|
|
|
|
ret->autorelease();
|
|
|
|
return ret;
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
Vector<Widget*> RelativeLayoutManager::getAllWidgets(cocos2d::ui::LayoutProtocol* layout)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
|
|
|
Vector<Node*> container = layout->getLayoutElements();
|
|
|
|
Vector<Widget*> widgetChildren;
|
|
|
|
for (auto& subWidget : container)
|
|
|
|
{
|
|
|
|
Widget* child = dynamic_cast<Widget*>(subWidget);
|
|
|
|
if (child)
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
RelativeLayoutParameter* layoutParameter =
|
|
|
|
dynamic_cast<RelativeLayoutParameter*>(child->getLayoutParameter());
|
2019-11-23 20:27:39 +08:00
|
|
|
layoutParameter->_put = false;
|
|
|
|
_unlayoutChildCount++;
|
|
|
|
widgetChildren.pushBack(child);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return widgetChildren;
|
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2019-11-23 20:27:39 +08:00
|
|
|
Widget* RelativeLayoutManager::getRelativeWidget(Widget* widget)
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
Widget* relativeWidget = nullptr;
|
2019-11-23 20:27:39 +08:00
|
|
|
RelativeLayoutParameter* layoutParameter = dynamic_cast<RelativeLayoutParameter*>(widget->getLayoutParameter());
|
2021-12-28 11:00:34 +08:00
|
|
|
auto relativeName = layoutParameter->getRelativeToWidgetName();
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2019-11-23 20:27:39 +08:00
|
|
|
if (!relativeName.empty())
|
|
|
|
{
|
|
|
|
for (auto& sWidget : _widgetChildren)
|
|
|
|
{
|
|
|
|
if (sWidget)
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
RelativeLayoutParameter* rlayoutParameter =
|
|
|
|
dynamic_cast<RelativeLayoutParameter*>(sWidget->getLayoutParameter());
|
|
|
|
if (rlayoutParameter && rlayoutParameter->getRelativeName() == relativeName)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
relativeWidget = sWidget;
|
2019-11-23 20:27:39 +08:00
|
|
|
_relativeWidgetLP = rlayoutParameter;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return relativeWidget;
|
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
|
|
|
|
bool RelativeLayoutManager::calculateFinalPositionWithRelativeWidget(LayoutProtocol* layout)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
|
|
|
Vec2 ap = _widget->getAnchorPoint();
|
2021-10-23 23:27:14 +08:00
|
|
|
Vec2 cs = _widget->getBoundingBox().size;
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2019-11-23 20:27:39 +08:00
|
|
|
_finalPositionX = 0.0f;
|
|
|
|
_finalPositionY = 0.0f;
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2019-11-23 20:27:39 +08:00
|
|
|
Widget* relativeWidget = this->getRelativeWidget(_widget);
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2019-11-23 20:27:39 +08:00
|
|
|
RelativeLayoutParameter* layoutParameter = dynamic_cast<RelativeLayoutParameter*>(_widget->getLayoutParameter());
|
|
|
|
|
|
|
|
RelativeLayoutParameter::RelativeAlign align = layoutParameter->getAlign();
|
|
|
|
|
2021-10-23 23:27:14 +08:00
|
|
|
Vec2 layoutSize = layout->getLayoutContentSize();
|
2019-11-23 20:27:39 +08:00
|
|
|
|
|
|
|
switch (align)
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
case RelativeLayoutParameter::RelativeAlign::NONE:
|
|
|
|
case RelativeLayoutParameter::RelativeAlign::PARENT_TOP_LEFT:
|
|
|
|
_finalPositionX = ap.x * cs.width;
|
|
|
|
_finalPositionY = layoutSize.height - ((1.0f - ap.y) * cs.height);
|
|
|
|
break;
|
|
|
|
case RelativeLayoutParameter::RelativeAlign::PARENT_TOP_CENTER_HORIZONTAL:
|
|
|
|
_finalPositionX = layoutSize.width * 0.5f - cs.width * (0.5f - ap.x);
|
|
|
|
_finalPositionY = layoutSize.height - ((1.0f - ap.y) * cs.height);
|
|
|
|
break;
|
|
|
|
case RelativeLayoutParameter::RelativeAlign::PARENT_TOP_RIGHT:
|
|
|
|
_finalPositionX = layoutSize.width - ((1.0f - ap.x) * cs.width);
|
|
|
|
_finalPositionY = layoutSize.height - ((1.0f - ap.y) * cs.height);
|
|
|
|
break;
|
|
|
|
case RelativeLayoutParameter::RelativeAlign::PARENT_LEFT_CENTER_VERTICAL:
|
|
|
|
_finalPositionX = ap.x * cs.width;
|
|
|
|
_finalPositionY = layoutSize.height * 0.5f - cs.height * (0.5f - ap.y);
|
|
|
|
break;
|
|
|
|
case RelativeLayoutParameter::RelativeAlign::CENTER_IN_PARENT:
|
|
|
|
_finalPositionX = layoutSize.width * 0.5f - cs.width * (0.5f - ap.x);
|
|
|
|
_finalPositionY = layoutSize.height * 0.5f - cs.height * (0.5f - ap.y);
|
|
|
|
break;
|
|
|
|
case RelativeLayoutParameter::RelativeAlign::PARENT_RIGHT_CENTER_VERTICAL:
|
|
|
|
_finalPositionX = layoutSize.width - ((1.0f - ap.x) * cs.width);
|
|
|
|
_finalPositionY = layoutSize.height * 0.5f - cs.height * (0.5f - ap.y);
|
|
|
|
break;
|
|
|
|
case RelativeLayoutParameter::RelativeAlign::PARENT_LEFT_BOTTOM:
|
|
|
|
_finalPositionX = ap.x * cs.width;
|
|
|
|
_finalPositionY = ap.y * cs.height;
|
|
|
|
break;
|
|
|
|
case RelativeLayoutParameter::RelativeAlign::PARENT_BOTTOM_CENTER_HORIZONTAL:
|
|
|
|
_finalPositionX = layoutSize.width * 0.5f - cs.width * (0.5f - ap.x);
|
|
|
|
_finalPositionY = ap.y * cs.height;
|
|
|
|
break;
|
|
|
|
case RelativeLayoutParameter::RelativeAlign::PARENT_RIGHT_BOTTOM:
|
|
|
|
_finalPositionX = layoutSize.width - ((1.0f - ap.x) * cs.width);
|
|
|
|
_finalPositionY = ap.y * cs.height;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case RelativeLayoutParameter::RelativeAlign::LOCATION_ABOVE_LEFTALIGN:
|
|
|
|
if (relativeWidget)
|
|
|
|
{
|
|
|
|
if (_relativeWidgetLP && !_relativeWidgetLP->_put)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
return false;
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
float locationTop = relativeWidget->getTopBoundary();
|
|
|
|
float locationLeft = relativeWidget->getLeftBoundary();
|
|
|
|
_finalPositionY = locationTop + ap.y * cs.height;
|
|
|
|
_finalPositionX = locationLeft + ap.x * cs.width;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case RelativeLayoutParameter::RelativeAlign::LOCATION_ABOVE_CENTER:
|
|
|
|
if (relativeWidget)
|
|
|
|
{
|
|
|
|
if (_relativeWidgetLP && !_relativeWidgetLP->_put)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
return false;
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
Vec2 rbs = relativeWidget->getBoundingBox().size;
|
|
|
|
float locationTop = relativeWidget->getTopBoundary();
|
|
|
|
|
|
|
|
_finalPositionY = locationTop + ap.y * cs.height;
|
|
|
|
_finalPositionX = relativeWidget->getLeftBoundary() + rbs.width * 0.5f + ap.x * cs.width - cs.width * 0.5f;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case RelativeLayoutParameter::RelativeAlign::LOCATION_ABOVE_RIGHTALIGN:
|
|
|
|
if (relativeWidget)
|
|
|
|
{
|
|
|
|
if (_relativeWidgetLP && !_relativeWidgetLP->_put)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
return false;
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
float locationTop = relativeWidget->getTopBoundary();
|
|
|
|
float locationRight = relativeWidget->getRightBoundary();
|
|
|
|
_finalPositionY = locationTop + ap.y * cs.height;
|
|
|
|
_finalPositionX = locationRight - (1.0f - ap.x) * cs.width;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case RelativeLayoutParameter::RelativeAlign::LOCATION_LEFT_OF_TOPALIGN:
|
|
|
|
if (relativeWidget)
|
|
|
|
{
|
|
|
|
if (_relativeWidgetLP && !_relativeWidgetLP->_put)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
return false;
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
float locationTop = relativeWidget->getTopBoundary();
|
|
|
|
float locationLeft = relativeWidget->getLeftBoundary();
|
|
|
|
_finalPositionY = locationTop - (1.0f - ap.y) * cs.height;
|
|
|
|
_finalPositionX = locationLeft - (1.0f - ap.x) * cs.width;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case RelativeLayoutParameter::RelativeAlign::LOCATION_LEFT_OF_CENTER:
|
|
|
|
if (relativeWidget)
|
|
|
|
{
|
|
|
|
if (_relativeWidgetLP && !_relativeWidgetLP->_put)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
return false;
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
Vec2 rbs = relativeWidget->getBoundingBox().size;
|
|
|
|
float locationLeft = relativeWidget->getLeftBoundary();
|
|
|
|
_finalPositionX = locationLeft - (1.0f - ap.x) * cs.width;
|
|
|
|
|
|
|
|
_finalPositionY =
|
|
|
|
relativeWidget->getBottomBoundary() + rbs.height * 0.5f + ap.y * cs.height - cs.height * 0.5f;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case RelativeLayoutParameter::RelativeAlign::LOCATION_LEFT_OF_BOTTOMALIGN:
|
|
|
|
if (relativeWidget)
|
|
|
|
{
|
|
|
|
if (_relativeWidgetLP && !_relativeWidgetLP->_put)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
return false;
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
float locationBottom = relativeWidget->getBottomBoundary();
|
|
|
|
float locationLeft = relativeWidget->getLeftBoundary();
|
|
|
|
_finalPositionY = locationBottom + ap.y * cs.height;
|
|
|
|
_finalPositionX = locationLeft - (1.0f - ap.x) * cs.width;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case RelativeLayoutParameter::RelativeAlign::LOCATION_RIGHT_OF_TOPALIGN:
|
|
|
|
if (relativeWidget)
|
|
|
|
{
|
|
|
|
if (_relativeWidgetLP && !_relativeWidgetLP->_put)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
return false;
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
float locationTop = relativeWidget->getTopBoundary();
|
|
|
|
float locationRight = relativeWidget->getRightBoundary();
|
|
|
|
_finalPositionY = locationTop - (1.0f - ap.y) * cs.height;
|
|
|
|
_finalPositionX = locationRight + ap.x * cs.width;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case RelativeLayoutParameter::RelativeAlign::LOCATION_RIGHT_OF_CENTER:
|
|
|
|
if (relativeWidget)
|
|
|
|
{
|
|
|
|
if (_relativeWidgetLP && !_relativeWidgetLP->_put)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
return false;
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
Vec2 rbs = relativeWidget->getBoundingBox().size;
|
|
|
|
float locationRight = relativeWidget->getRightBoundary();
|
|
|
|
_finalPositionX = locationRight + ap.x * cs.width;
|
|
|
|
|
|
|
|
_finalPositionY =
|
|
|
|
relativeWidget->getBottomBoundary() + rbs.height * 0.5f + ap.y * cs.height - cs.height * 0.5f;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case RelativeLayoutParameter::RelativeAlign::LOCATION_RIGHT_OF_BOTTOMALIGN:
|
|
|
|
if (relativeWidget)
|
|
|
|
{
|
|
|
|
if (_relativeWidgetLP && !_relativeWidgetLP->_put)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
return false;
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
float locationBottom = relativeWidget->getBottomBoundary();
|
|
|
|
float locationRight = relativeWidget->getRightBoundary();
|
|
|
|
_finalPositionY = locationBottom + ap.y * cs.height;
|
|
|
|
_finalPositionX = locationRight + ap.x * cs.width;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case RelativeLayoutParameter::RelativeAlign::LOCATION_BELOW_LEFTALIGN:
|
|
|
|
if (relativeWidget)
|
|
|
|
{
|
|
|
|
if (_relativeWidgetLP && !_relativeWidgetLP->_put)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
return false;
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
float locationBottom = relativeWidget->getBottomBoundary();
|
|
|
|
float locationLeft = relativeWidget->getLeftBoundary();
|
|
|
|
_finalPositionY = locationBottom - (1.0f - ap.y) * cs.height;
|
|
|
|
_finalPositionX = locationLeft + ap.x * cs.width;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case RelativeLayoutParameter::RelativeAlign::LOCATION_BELOW_CENTER:
|
|
|
|
if (relativeWidget)
|
|
|
|
{
|
|
|
|
if (_relativeWidgetLP && !_relativeWidgetLP->_put)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
return false;
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
Vec2 rbs = relativeWidget->getBoundingBox().size;
|
|
|
|
float locationBottom = relativeWidget->getBottomBoundary();
|
|
|
|
|
|
|
|
_finalPositionY = locationBottom - (1.0f - ap.y) * cs.height;
|
|
|
|
_finalPositionX = relativeWidget->getLeftBoundary() + rbs.width * 0.5f + ap.x * cs.width - cs.width * 0.5f;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case RelativeLayoutParameter::RelativeAlign::LOCATION_BELOW_RIGHTALIGN:
|
|
|
|
if (relativeWidget)
|
|
|
|
{
|
|
|
|
if (_relativeWidgetLP && !_relativeWidgetLP->_put)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
return false;
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
float locationBottom = relativeWidget->getBottomBoundary();
|
|
|
|
float locationRight = relativeWidget->getRightBoundary();
|
|
|
|
_finalPositionY = locationBottom - (1.0f - ap.y) * cs.height;
|
|
|
|
_finalPositionX = locationRight - (1.0f - ap.x) * cs.width;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2019-11-23 20:27:39 +08:00
|
|
|
void RelativeLayoutManager::calculateFinalPositionWithRelativeAlign()
|
|
|
|
{
|
|
|
|
RelativeLayoutParameter* layoutParameter = dynamic_cast<RelativeLayoutParameter*>(_widget->getLayoutParameter());
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2019-11-23 20:27:39 +08:00
|
|
|
Margin mg = layoutParameter->getMargin();
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2019-11-23 20:27:39 +08:00
|
|
|
RelativeLayoutParameter::RelativeAlign align = layoutParameter->getAlign();
|
2021-12-25 10:04:45 +08:00
|
|
|
|
|
|
|
// handle margin
|
2019-11-23 20:27:39 +08:00
|
|
|
switch (align)
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
case RelativeLayoutParameter::RelativeAlign::NONE:
|
|
|
|
case RelativeLayoutParameter::RelativeAlign::PARENT_TOP_LEFT:
|
|
|
|
_finalPositionX += mg.left;
|
|
|
|
_finalPositionY -= mg.top;
|
|
|
|
break;
|
|
|
|
case RelativeLayoutParameter::RelativeAlign::PARENT_TOP_CENTER_HORIZONTAL:
|
|
|
|
_finalPositionY -= mg.top;
|
|
|
|
break;
|
|
|
|
case RelativeLayoutParameter::RelativeAlign::PARENT_TOP_RIGHT:
|
|
|
|
_finalPositionX -= mg.right;
|
|
|
|
_finalPositionY -= mg.top;
|
|
|
|
break;
|
|
|
|
case RelativeLayoutParameter::RelativeAlign::PARENT_LEFT_CENTER_VERTICAL:
|
|
|
|
_finalPositionX += mg.left;
|
|
|
|
break;
|
|
|
|
case RelativeLayoutParameter::RelativeAlign::CENTER_IN_PARENT:
|
|
|
|
break;
|
|
|
|
case RelativeLayoutParameter::RelativeAlign::PARENT_RIGHT_CENTER_VERTICAL:
|
|
|
|
_finalPositionX -= mg.right;
|
|
|
|
break;
|
|
|
|
case RelativeLayoutParameter::RelativeAlign::PARENT_LEFT_BOTTOM:
|
|
|
|
_finalPositionX += mg.left;
|
|
|
|
_finalPositionY += mg.bottom;
|
|
|
|
break;
|
|
|
|
case RelativeLayoutParameter::RelativeAlign::PARENT_BOTTOM_CENTER_HORIZONTAL:
|
|
|
|
_finalPositionY += mg.bottom;
|
|
|
|
break;
|
|
|
|
case RelativeLayoutParameter::RelativeAlign::PARENT_RIGHT_BOTTOM:
|
|
|
|
_finalPositionX -= mg.right;
|
|
|
|
_finalPositionY += mg.bottom;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case RelativeLayoutParameter::RelativeAlign::LOCATION_ABOVE_LEFTALIGN:
|
|
|
|
_finalPositionY += mg.bottom;
|
|
|
|
_finalPositionX += mg.left;
|
|
|
|
break;
|
|
|
|
case RelativeLayoutParameter::RelativeAlign::LOCATION_ABOVE_RIGHTALIGN:
|
|
|
|
_finalPositionY += mg.bottom;
|
|
|
|
_finalPositionX -= mg.right;
|
|
|
|
break;
|
|
|
|
case RelativeLayoutParameter::RelativeAlign::LOCATION_ABOVE_CENTER:
|
|
|
|
_finalPositionY += mg.bottom;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case RelativeLayoutParameter::RelativeAlign::LOCATION_LEFT_OF_TOPALIGN:
|
|
|
|
_finalPositionX -= mg.right;
|
|
|
|
_finalPositionY -= mg.top;
|
|
|
|
break;
|
|
|
|
case RelativeLayoutParameter::RelativeAlign::LOCATION_LEFT_OF_BOTTOMALIGN:
|
|
|
|
_finalPositionX -= mg.right;
|
|
|
|
_finalPositionY += mg.bottom;
|
|
|
|
break;
|
|
|
|
case RelativeLayoutParameter::RelativeAlign::LOCATION_LEFT_OF_CENTER:
|
|
|
|
_finalPositionX -= mg.right;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case RelativeLayoutParameter::RelativeAlign::LOCATION_RIGHT_OF_TOPALIGN:
|
|
|
|
_finalPositionX += mg.left;
|
|
|
|
_finalPositionY -= mg.top;
|
|
|
|
break;
|
|
|
|
case RelativeLayoutParameter::RelativeAlign::LOCATION_RIGHT_OF_BOTTOMALIGN:
|
|
|
|
_finalPositionX += mg.left;
|
|
|
|
_finalPositionY += mg.bottom;
|
|
|
|
break;
|
|
|
|
case RelativeLayoutParameter::RelativeAlign::LOCATION_RIGHT_OF_CENTER:
|
|
|
|
_finalPositionX += mg.left;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case RelativeLayoutParameter::RelativeAlign::LOCATION_BELOW_LEFTALIGN:
|
|
|
|
_finalPositionY -= mg.top;
|
|
|
|
_finalPositionX += mg.left;
|
|
|
|
break;
|
|
|
|
case RelativeLayoutParameter::RelativeAlign::LOCATION_BELOW_RIGHTALIGN:
|
|
|
|
_finalPositionY -= mg.top;
|
|
|
|
_finalPositionX -= mg.right;
|
|
|
|
break;
|
|
|
|
case RelativeLayoutParameter::RelativeAlign::LOCATION_BELOW_CENTER:
|
|
|
|
_finalPositionY -= mg.top;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
|
|
|
|
void RelativeLayoutManager::doLayout(LayoutProtocol* layout)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2019-11-23 20:27:39 +08:00
|
|
|
_widgetChildren = this->getAllWidgets(layout);
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2019-11-23 20:27:39 +08:00
|
|
|
while (_unlayoutChildCount > 0)
|
|
|
|
{
|
|
|
|
for (auto& subWidget : _widgetChildren)
|
|
|
|
{
|
|
|
|
_widget = static_cast<Widget*>(subWidget);
|
2021-12-25 10:04:45 +08:00
|
|
|
|
|
|
|
RelativeLayoutParameter* layoutParameter =
|
|
|
|
dynamic_cast<RelativeLayoutParameter*>(_widget->getLayoutParameter());
|
|
|
|
|
2019-11-23 20:27:39 +08:00
|
|
|
if (layoutParameter)
|
|
|
|
{
|
|
|
|
if (layoutParameter->_put)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2019-11-23 20:27:39 +08:00
|
|
|
bool ret = this->calculateFinalPositionWithRelativeWidget(layout);
|
2021-12-25 10:04:45 +08:00
|
|
|
if (!ret)
|
|
|
|
{
|
2019-11-23 20:27:39 +08:00
|
|
|
continue;
|
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2019-11-23 20:27:39 +08:00
|
|
|
this->calculateFinalPositionWithRelativeAlign();
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2019-11-23 20:27:39 +08:00
|
|
|
_widget->setPosition(Vec2(_finalPositionX, _finalPositionY));
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2019-11-23 20:27:39 +08:00
|
|
|
layoutParameter->_put = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_unlayoutChildCount--;
|
|
|
|
}
|
|
|
|
_widgetChildren.clear();
|
|
|
|
}
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
} // namespace ui
|
2019-11-23 20:27:39 +08:00
|
|
|
|
|
|
|
NS_CC_END
|