Merge pull request #286 from rh101/add-center-vertical-layout-support

Add support for center vertical layout
This commit is contained in:
halx99 2020-11-26 23:43:25 -08:00 committed by GitHub
parent cc7366845e
commit 315e42b126
4 changed files with 106 additions and 8 deletions

View File

@ -632,6 +632,7 @@ void Layout::supplyTheLayoutParameterLackToChild(Widget *child)
break;
case Type::HORIZONTAL:
case Type::VERTICAL:
case Type::CENTER_VERTICAL:
{
LinearLayoutParameter* layoutParameter = dynamic_cast<LinearLayoutParameter*>(child->getLayoutParameter());
if (!layoutParameter)
@ -922,6 +923,9 @@ LayoutManager* Layout::createLayoutManager()
case Type::VERTICAL:
exe = LinearVerticalLayoutManager::create();
break;
case Type::CENTER_VERTICAL:
exe = LinearCenterVerticalLayoutManager::create();
break;
case Type::HORIZONTAL:
exe = LinearHorizontalLayoutManager::create();
break;
@ -1043,7 +1047,7 @@ Size Layout::getLayoutAccumulatedSize()const
{
layoutSize = layoutSize - Size(0, layoutSize.height/widgetCount * (widgetCount-1));
}
if (type == Type::VERTICAL)
if (type == Type::VERTICAL || type == Type::CENTER_VERTICAL)
{
layoutSize = layoutSize - Size(layoutSize.width/widgetCount * (widgetCount-1), 0);
}
@ -1634,7 +1638,8 @@ bool Layout::isLastWidgetInContainer(Widget* widget, FocusDirection direction)c
auto& container = parent->getChildren();
ssize_t index = container.getIndex(widget);
if (parent->getLayoutType() == Type::HORIZONTAL)
const auto parentLayoutType = parent->getLayoutType();
if (parentLayoutType == Type::HORIZONTAL)
{
if (direction == FocusDirection::LEFT)
{
@ -1668,7 +1673,7 @@ bool Layout::isLastWidgetInContainer(Widget* widget, FocusDirection direction)c
return isLastWidgetInContainer(parent, direction);
}
}
else if(parent->getLayoutType() == Type::VERTICAL)
else if (parentLayoutType == Type::VERTICAL || parentLayoutType == Type::CENTER_VERTICAL)
{
if (direction == FocusDirection::UP)
{
@ -1721,7 +1726,7 @@ bool Layout::isWidgetAncestorSupportLoopFocus(Widget* widget, FocusDirection di
}
if (parent->isLoopFocus())
{
auto layoutType = parent->getLayoutType();
const auto layoutType = parent->getLayoutType();
if (layoutType == Type::HORIZONTAL)
{
if (direction == FocusDirection::LEFT || direction == FocusDirection::RIGHT)
@ -1733,7 +1738,7 @@ bool Layout::isWidgetAncestorSupportLoopFocus(Widget* widget, FocusDirection di
return isWidgetAncestorSupportLoopFocus(parent, direction);
}
}
if (layoutType == Type::VERTICAL)
if (layoutType == Type::VERTICAL || layoutType == Type::CENTER_VERTICAL)
{
if (direction == FocusDirection::DOWN || direction == FocusDirection::UP)
{
@ -1823,7 +1828,7 @@ Widget* Layout::findNextFocusedWidget(FocusDirection direction, Widget* current)
break;
}
}
else if (_layoutType == Type::VERTICAL)
else if (_layoutType == Type::VERTICAL || _layoutType == Type::CENTER_VERTICAL)
{
switch (direction)
{

View File

@ -120,6 +120,7 @@ public:
{
ABSOLUTE,
VERTICAL,
CENTER_VERTICAL,
HORIZONTAL,
RELATIVE
};

View File

@ -85,7 +85,6 @@ void LinearHorizontalLayoutManager::doLayout(LayoutProtocol* layout)
}
}
//LinearVerticalLayoutManager
LinearVerticalLayoutManager* LinearVerticalLayoutManager::create()
{
@ -142,7 +141,83 @@ void LinearVerticalLayoutManager::doLayout(LayoutProtocol* layout)
}
}
}
//LinearCenterVerticalLayoutManager
LinearCenterVerticalLayoutManager* LinearCenterVerticalLayoutManager::create()
{
auto* exe = new (std::nothrow) LinearCenterVerticalLayoutManager();
if (exe)
{
exe->autorelease();
return exe;
}
CC_SAFE_DELETE(exe);
return nullptr;
}
void LinearCenterVerticalLayoutManager::doLayout(LayoutProtocol* layout)
{
const auto layoutSize = layout->getLayoutContentSize();
auto&& container = layout->getLayoutElements();
auto topBoundary = layoutSize.height;
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();
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);
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);
topBoundary = subWidget->getPosition().y - subWidget->getAnchorPoint().y * subWidget->getBoundingBox().size.height - mg.bottom;
}
}
}
}
//RelativeLayoutManager
RelativeLayoutManager* RelativeLayoutManager::create()

View File

@ -94,6 +94,23 @@ private:
friend class Layout;
};
/**
*@brief Linear vertical layouting class.
* Note: This class is used only by @see `Layout` class.
* @lua NA
* @js NA
*/
class CC_GUI_DLL LinearCenterVerticalLayoutManager : public LayoutManager
{
private:
LinearCenterVerticalLayoutManager() {};
virtual ~LinearCenterVerticalLayoutManager() {};
static LinearCenterVerticalLayoutManager* create();
virtual void doLayout(LayoutProtocol* layout) override;
friend class Layout;
};
/**
*@brief Relative layouting class.
*Note: This class is used only by `Layout` class.