Add support for centered horizontal layout (#946)

* Committing genbindings changes

* Add support for CENTER_HORIZONTAL layout type.
This commit is contained in:
RH 2022-11-01 22:02:04 +11:00 committed by GitHub
parent 7d1a911b91
commit 82bcb1ae5f
6 changed files with 247 additions and 17 deletions

View File

@ -643,6 +643,7 @@ void Layout::supplyTheLayoutParameterLackToChild(Widget* child)
case Type::HORIZONTAL: case Type::HORIZONTAL:
case Type::VERTICAL: case Type::VERTICAL:
case Type::CENTER_VERTICAL: case Type::CENTER_VERTICAL:
case Type::CENTER_HORIZONTAL:
{ {
LinearLayoutParameter* layoutParameter = dynamic_cast<LinearLayoutParameter*>(child->getLayoutParameter()); LinearLayoutParameter* layoutParameter = dynamic_cast<LinearLayoutParameter*>(child->getLayoutParameter());
if (!layoutParameter) if (!layoutParameter)
@ -934,6 +935,9 @@ LayoutManager* Layout::createLayoutManager()
case Type::CENTER_VERTICAL: case Type::CENTER_VERTICAL:
exe = LinearCenterVerticalLayoutManager::create(); exe = LinearCenterVerticalLayoutManager::create();
break; break;
case Type::CENTER_HORIZONTAL:
exe = LinearCenterHorizontalLayoutManager::create();
break;
case Type::HORIZONTAL: case Type::HORIZONTAL:
exe = LinearHorizontalLayoutManager::create(); exe = LinearHorizontalLayoutManager::create();
break; break;
@ -1049,7 +1053,7 @@ Vec2 Layout::getLayoutAccumulatedSize() const
// subtract extra size // subtract extra size
Type type = this->getLayoutType(); Type type = this->getLayoutType();
if (type == Type::HORIZONTAL) if (type == Type::HORIZONTAL || type == Type::CENTER_HORIZONTAL)
{ {
layoutSize = layoutSize - Vec2(0, layoutSize.height / widgetCount * (widgetCount - 1)); layoutSize = layoutSize - Vec2(0, layoutSize.height / widgetCount * (widgetCount - 1));
} }
@ -1725,7 +1729,7 @@ bool Layout::isWidgetAncestorSupportLoopFocus(Widget* widget, FocusDirection dir
if (parent->isLoopFocus()) if (parent->isLoopFocus())
{ {
const auto layoutType = parent->getLayoutType(); const auto layoutType = parent->getLayoutType();
if (layoutType == Type::HORIZONTAL) if (layoutType == Type::HORIZONTAL || _layoutType == Type::CENTER_HORIZONTAL)
{ {
if (direction == FocusDirection::LEFT || direction == FocusDirection::RIGHT) if (direction == FocusDirection::LEFT || direction == FocusDirection::RIGHT)
{ {
@ -1789,7 +1793,7 @@ Widget* Layout::findNextFocusedWidget(FocusDirection direction, Widget* current)
} }
else if (current->isFocused() || dynamic_cast<Layout*>(current)) else if (current->isFocused() || dynamic_cast<Layout*>(current))
{ {
if (_layoutType == Type::HORIZONTAL) if (_layoutType == Type::HORIZONTAL || _layoutType == Type::CENTER_HORIZONTAL)
{ {
switch (direction) switch (direction)
{ {

View File

@ -125,6 +125,7 @@ public:
HORIZONTAL, HORIZONTAL,
RELATIVE, RELATIVE,
CENTER_VERTICAL, CENTER_VERTICAL,
CENTER_HORIZONTAL,
}; };
/** /**

View File

@ -204,6 +204,74 @@ void LinearCenterVerticalLayoutManager::doLayout(LayoutProtocol* layout)
} }
} }
// LinearCenterHorizontalLayoutManager
LinearCenterHorizontalLayoutManager* LinearCenterHorizontalLayoutManager::create()
{
auto* ret = new LinearCenterHorizontalLayoutManager();
ret->autorelease();
return ret;
}
void LinearCenterHorizontalLayoutManager::doLayout(LayoutProtocol* layout)
{
const auto layoutSize = layout->getLayoutContentSize();
auto&& container = layout->getLayoutElements();
auto totalWidth = 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();
totalWidth += subWidget->getBoundingBox().size.width + mg.left + mg.right;
}
}
}
auto leftBoundary = (layoutSize.width - totalWidth) / 2.f;
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();
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;
switch (childGravity)
{
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;
}
Margin mg = layoutParameter->getMargin();
finalPosX += mg.left;
finalPosY -= mg.top;
child->setPosition(Vec2(finalPosX, finalPosY));
leftBoundary = child->getRightBoundary() + mg.right;
}
}
}
}
// RelativeLayoutManager // RelativeLayoutManager
RelativeLayoutManager* RelativeLayoutManager::create() RelativeLayoutManager* RelativeLayoutManager::create()

View File

@ -50,11 +50,11 @@ class RelativeLayoutParameter;
class AX_GUI_DLL LayoutManager : public Ref class AX_GUI_DLL LayoutManager : public Ref
{ {
public: public:
virtual ~LayoutManager(){}; virtual ~LayoutManager(){}
LayoutManager(){}; LayoutManager(){}
/** /**
* The interface does the actual layouting work. * The interface does the actual layout work.
*/ */
virtual void doLayout(LayoutProtocol* layout) = 0; virtual void doLayout(LayoutProtocol* layout) = 0;
@ -62,7 +62,7 @@ public:
}; };
/** /**
*@brief Linear vertical layouting class. *@brief Linear vertical layout class.
* Note: This class is used only by @see `Layout` class. * Note: This class is used only by @see `Layout` class.
* @lua NA * @lua NA
* @js NA * @js NA
@ -70,8 +70,8 @@ public:
class AX_GUI_DLL LinearVerticalLayoutManager : public LayoutManager class AX_GUI_DLL LinearVerticalLayoutManager : public LayoutManager
{ {
private: private:
LinearVerticalLayoutManager(){}; LinearVerticalLayoutManager(){}
virtual ~LinearVerticalLayoutManager(){}; virtual ~LinearVerticalLayoutManager(){}
static LinearVerticalLayoutManager* create(); static LinearVerticalLayoutManager* create();
virtual void doLayout(LayoutProtocol* layout) override; virtual void doLayout(LayoutProtocol* layout) override;
@ -79,7 +79,7 @@ private:
}; };
/** /**
*@brief Linear horizontal layouting class. *@brief Linear horizontal layout class.
*Note: This class is used only by @see `Layout` class. *Note: This class is used only by @see `Layout` class.
* @lua NA * @lua NA
* @js NA * @js NA
@ -87,8 +87,8 @@ private:
class AX_GUI_DLL LinearHorizontalLayoutManager : public LayoutManager class AX_GUI_DLL LinearHorizontalLayoutManager : public LayoutManager
{ {
private: private:
LinearHorizontalLayoutManager(){}; LinearHorizontalLayoutManager(){}
virtual ~LinearHorizontalLayoutManager(){}; virtual ~LinearHorizontalLayoutManager(){}
static LinearHorizontalLayoutManager* create(); static LinearHorizontalLayoutManager* create();
virtual void doLayout(LayoutProtocol* layout) override; virtual void doLayout(LayoutProtocol* layout) override;
@ -96,7 +96,7 @@ private:
}; };
/** /**
*@brief Linear vertical layouting class. *@brief Linear vertical layout class.
* Note: This class is used only by @see `Layout` class. * Note: This class is used only by @see `Layout` class.
* @lua NA * @lua NA
* @js NA * @js NA
@ -104,8 +104,8 @@ private:
class AX_GUI_DLL LinearCenterVerticalLayoutManager : public LayoutManager class AX_GUI_DLL LinearCenterVerticalLayoutManager : public LayoutManager
{ {
private: private:
LinearCenterVerticalLayoutManager(){}; LinearCenterVerticalLayoutManager(){}
virtual ~LinearCenterVerticalLayoutManager(){}; virtual ~LinearCenterVerticalLayoutManager(){}
static LinearCenterVerticalLayoutManager* create(); static LinearCenterVerticalLayoutManager* create();
virtual void doLayout(LayoutProtocol* layout) override; virtual void doLayout(LayoutProtocol* layout) override;
@ -113,7 +113,25 @@ private:
}; };
/** /**
*@brief Relative layouting class. *@brief Linear horizontal layout class.
* Note: This class is used only by @see `Layout` class.
* @lua NA
* @js NA
*/
class AX_GUI_DLL LinearCenterHorizontalLayoutManager : public LayoutManager
{
private:
LinearCenterHorizontalLayoutManager(){}
virtual ~LinearCenterHorizontalLayoutManager(){}
static LinearCenterHorizontalLayoutManager* create();
virtual void doLayout(LayoutProtocol* layout) override;
friend class Layout;
};
/**
*@brief Relative layout class.
*Note: This class is used only by `Layout` class. *Note: This class is used only by `Layout` class.
* @lua NA * @lua NA
* @js NA * @js NA
@ -128,7 +146,7 @@ private:
, _finalPositionY(0.0f) , _finalPositionY(0.0f)
, _relativeWidgetLP(nullptr) , _relativeWidgetLP(nullptr)
{} {}
virtual ~RelativeLayoutManager(){}; virtual ~RelativeLayoutManager(){}
static RelativeLayoutManager* create(); static RelativeLayoutManager* create();
virtual void doLayout(LayoutProtocol* layout) override; virtual void doLayout(LayoutProtocol* layout) override;

View File

@ -36,6 +36,8 @@ UILayoutTests::UILayoutTests()
ADD_TEST_CASE(UILayoutTest_BackGroundImage_Scale9); ADD_TEST_CASE(UILayoutTest_BackGroundImage_Scale9);
ADD_TEST_CASE(UILayoutTest_Layout_Linear_Vertical); ADD_TEST_CASE(UILayoutTest_Layout_Linear_Vertical);
ADD_TEST_CASE(UILayoutTest_Layout_Linear_Horizontal); ADD_TEST_CASE(UILayoutTest_Layout_Linear_Horizontal);
ADD_TEST_CASE(UILayoutTest_Layout_Linear_CenterVertical);
ADD_TEST_CASE(UILayoutTest_Layout_Linear_CenterHorizontal);
ADD_TEST_CASE(UILayoutTest_Layout_Relative_Align_Parent); ADD_TEST_CASE(UILayoutTest_Layout_Relative_Align_Parent);
ADD_TEST_CASE(UILayoutTest_Layout_Relative_Location); ADD_TEST_CASE(UILayoutTest_Layout_Relative_Location);
ADD_TEST_CASE(UILayoutTest_Layout_Scaled_Widget); ADD_TEST_CASE(UILayoutTest_Layout_Scaled_Widget);
@ -494,6 +496,122 @@ bool UILayoutTest_Layout_Linear_Horizontal::init()
return false; return false;
} }
// UILayoutTest_Layout_Linear_CenterVertical
UILayoutTest_Layout_Linear_CenterVertical::UILayoutTest_Layout_Linear_CenterVertical() {}
UILayoutTest_Layout_Linear_CenterVertical::~UILayoutTest_Layout_Linear_CenterVertical() {}
bool UILayoutTest_Layout_Linear_CenterVertical::init()
{
if (UIScene::init())
{
Size widgetSize = _widget->getContentSize();
// Add the alert
Text* alert = Text::create("Layout Linear Center Vertical", "fonts/Marker Felt.ttf", 20);
alert->setColor(Color3B(159, 168, 176));
alert->setPosition(
Vec2(widgetSize.width / 2.0f, widgetSize.height / 2.0f - alert->getContentSize().height * 4.5f));
_uiLayer->addChild(alert);
Layout* root = static_cast<Layout*>(_uiLayer->getChildByTag(81));
Layout* background = static_cast<Layout*>(root->getChildByName("background_Panel"));
// Create the layout
Layout* layout = Layout::create();
layout->setLayoutType(Layout::Type::CENTER_VERTICAL);
layout->setContentSize(Size(280, 150));
Size backgroundSize = background->getContentSize();
layout->setPosition(Vec2((widgetSize.width - backgroundSize.width) / 2.0f +
(backgroundSize.width - layout->getContentSize().width) / 2.0f,
(widgetSize.height - backgroundSize.height) / 2.0f +
(backgroundSize.height - layout->getContentSize().height) / 2.0f));
_uiLayer->addChild(layout);
Button* button = Button::create("cocosui/animationbuttonnormal.png", "cocosui/animationbuttonpressed.png");
layout->addChild(button);
LinearLayoutParameter* lp1 = LinearLayoutParameter::create();
button->setLayoutParameter(lp1);
lp1->setGravity(LinearLayoutParameter::LinearGravity::CENTER_HORIZONTAL);
lp1->setMargin(Margin(0.0f, 5.0f, 0.0f, 10.0f));
Button* titleButton = Button::create("cocosui/backtotopnormal.png", "cocosui/backtotoppressed.png");
titleButton->setTitleText("Title Button");
layout->addChild(titleButton);
LinearLayoutParameter* lp2 = LinearLayoutParameter::create();
titleButton->setLayoutParameter(lp2);
lp2->setGravity(LinearLayoutParameter::LinearGravity::CENTER_HORIZONTAL);
lp2->setMargin(Margin(0.0f, 10.0f, 0.0f, 10.0f));
return true;
}
return false;
}
// UILayoutTest_Layout_Linear_CenterHorizontal
UILayoutTest_Layout_Linear_CenterHorizontal::UILayoutTest_Layout_Linear_CenterHorizontal() {}
UILayoutTest_Layout_Linear_CenterHorizontal::~UILayoutTest_Layout_Linear_CenterHorizontal() {}
bool UILayoutTest_Layout_Linear_CenterHorizontal::init()
{
if (UIScene::init())
{
Size widgetSize = _widget->getContentSize();
// Add the alert
Text* alert = Text::create("Layout Linear Center Horizontal", "fonts/Marker Felt.ttf", 20);
alert->setColor(Color3B(159, 168, 176));
alert->setPosition(
Vec2(widgetSize.width / 2.0f, widgetSize.height / 2.0f - alert->getContentSize().height * 4.5f));
_uiLayer->addChild(alert);
Layout* root = static_cast<Layout*>(_uiLayer->getChildByTag(81));
Layout* background = dynamic_cast<Layout*>(root->getChildByName("background_Panel"));
// Create the layout
Layout* layout = Layout::create();
layout->setLayoutType(Layout::Type::CENTER_HORIZONTAL);
layout->setClippingEnabled(true);
layout->setContentSize(Size(280, 150));
Size backgroundSize = background->getContentSize();
layout->setPosition(Vec2((widgetSize.width - backgroundSize.width) / 2.0f +
(backgroundSize.width - layout->getContentSize().width) / 2.0f,
(widgetSize.height - backgroundSize.height) / 2.0f +
(backgroundSize.height - layout->getContentSize().height) / 2.0f));
_uiLayer->addChild(layout);
Button* button = Button::create("cocosui/animationbuttonnormal.png", "cocosui/animationbuttonpressed.png");
layout->addChild(button);
LinearLayoutParameter* lp1 = LinearLayoutParameter::create();
button->setLayoutParameter(lp1);
lp1->setGravity(LinearLayoutParameter::LinearGravity::CENTER_VERTICAL);
lp1->setMargin(Margin(10.0f, 10.0f, 10.0f, 10.0f));
Button* titleButton = Button::create("cocosui/backtotopnormal.png", "cocosui/backtotoppressed.png");
titleButton->setTitleText("Title Button");
layout->addChild(titleButton);
LinearLayoutParameter* lp2 = LinearLayoutParameter::create();
titleButton->setLayoutParameter(lp2);
lp2->setGravity(LinearLayoutParameter::LinearGravity::CENTER_VERTICAL);
lp2->setMargin(Margin(10.0f, 10.0f, 10.0f, 10.0f));
return true;
}
return false;
}
// UILayoutTest_Layout_Relative_Align_Parent // UILayoutTest_Layout_Relative_Align_Parent
UILayoutTest_Layout_Relative_Align_Parent::UILayoutTest_Layout_Relative_Align_Parent() {} UILayoutTest_Layout_Relative_Align_Parent::UILayoutTest_Layout_Relative_Align_Parent() {}

View File

@ -105,6 +105,27 @@ public:
CREATE_FUNC(UILayoutTest_Layout_Linear_Horizontal); CREATE_FUNC(UILayoutTest_Layout_Linear_Horizontal);
}; };
class UILayoutTest_Layout_Linear_CenterVertical : public UIScene
{
public:
UILayoutTest_Layout_Linear_CenterVertical();
~UILayoutTest_Layout_Linear_CenterVertical();
virtual bool init() override;
CREATE_FUNC(UILayoutTest_Layout_Linear_CenterVertical);
};
class UILayoutTest_Layout_Linear_CenterHorizontal : public UIScene
{
public:
UILayoutTest_Layout_Linear_CenterHorizontal();
~UILayoutTest_Layout_Linear_CenterHorizontal();
virtual bool init() override;
CREATE_FUNC(UILayoutTest_Layout_Linear_CenterHorizontal);
};
class UILayoutTest_Layout_Relative_Align_Parent : public UIScene class UILayoutTest_Layout_Relative_Align_Parent : public UIScene
{ {
public: public: