Replace MenuLayer with SimpleAxisLayout

This commit is contained in:
altalk23 2025-01-18 15:18:16 +03:00 committed by alk
parent 81e6247d0b
commit 7a05601732
4 changed files with 73 additions and 24 deletions

View file

@ -17,6 +17,7 @@
#include "ui/SceneManager.hpp"
#include "ui/ScrollLayer.hpp"
#include "ui/SelectList.hpp"
#include "ui/SimpleAxisLayout.hpp"
#include "ui/Scrollbar.hpp"
#include "ui/TextArea.hpp"
#include "ui/TextRenderer.hpp"

View file

@ -14,6 +14,8 @@ enum class AxisScaling {
Grow,
// Fits the layout to the items
Fit,
// Shrinks gaps if needed to fit, then scales down items
ScaleDownGaps,
};
enum class ScalingPriority {

View file

@ -48,9 +48,9 @@ ScalingPriority SimpleAxisLayoutOptions::getScalingPriority() const {
class SimpleAxisLayout::Impl {
public:
Axis m_axis = Axis::Column;
AxisScaling m_mainAxisScaling = AxisScaling::None;
AxisScaling m_mainAxisScaling = AxisScaling::ScaleDownGaps;
AxisScaling m_crossAxisScaling = AxisScaling::None;
MainAxisAlignment m_mainAxisAlignment = MainAxisAlignment::Start;
MainAxisAlignment m_mainAxisAlignment = MainAxisAlignment::Center;
CrossAxisAlignment m_crossAxisAlignment = CrossAxisAlignment::Center;
AxisDirection m_mainAxisDirection = AxisDirection::FrontToBack;
AxisDirection m_crossAxisDirection = AxisDirection::FrontToBack;
@ -78,7 +78,7 @@ public:
std::unordered_map<CCNode*, float> calculateMainScaling(CCNode* layout, std::vector<CCNode*> const& nodes, float totalGap);
void applyCrossPositioning(CCNode* layout, std::vector<CCNode*> const& nodes);
void applyMainPositioning(CCNode* layout, std::vector<CCNode*> const& nodes, std::vector<SpacerNode*> const& spacers);
void applyMainPositioning(CCNode* layout, std::vector<CCNode*> const& nodes, std::vector<SpacerNode*> const& spacers, float totalGap);
void apply(cocos2d::CCNode* on);
@ -230,6 +230,7 @@ std::unordered_map<CCNode*, float> SimpleAxisLayout::Impl::calculateCrossScaling
// get the scales we need for current limits
for (auto node : nodes) {
switch (m_crossAxisScaling) {
case AxisScaling::ScaleDownGaps:
case AxisScaling::ScaleDown: {
auto const width = this->getContentWidth(node) * this->getScale(node);
auto const minScale = this->getMinScale(node);
@ -279,6 +280,15 @@ std::unordered_map<CCNode*, float> SimpleAxisLayout::Impl::calculateMainScaling(
// fit the layout to all the nodes
layoutHeight = totalHeight;
break;
case AxisScaling::ScaleDownGaps:
// remove gaps if needed to fit the layout
if (totalHeight > layoutHeight && totalHeight - totalGap <= layoutHeight) {
totalHeight = layoutHeight;
}
else if (totalHeight > layoutHeight) {
// remove as much as we can
totalHeight -= totalGap;
}
default:
break;
}
@ -297,6 +307,7 @@ std::unordered_map<CCNode*, float> SimpleAxisLayout::Impl::calculateMainScaling(
sortedNodes[scalingPriority].push_back(node);
switch (m_mainAxisScaling) {
case AxisScaling::ScaleDownGaps:
case AxisScaling::ScaleDown: {
auto const height = this->getContentHeight(node) * this->getScale(node);
auto const minScale = this->getMinScale(node);
@ -327,8 +338,13 @@ std::unordered_map<CCNode*, float> SimpleAxisLayout::Impl::calculateMainScaling(
}
}
if (m_mainAxisScaling != AxisScaling::ScaleDown && m_mainAxisScaling != AxisScaling::Scale) {
return scales;
switch (m_mainAxisScaling) {
case AxisScaling::None:
case AxisScaling::Grow:
case AxisScaling::Fit:
return scales;
default:
break;
}
// sort the nodes by priority
@ -410,7 +426,7 @@ std::unordered_map<CCNode*, float> SimpleAxisLayout::Impl::calculateMainScaling(
totalHeight -= reducedHeight;
}
else {
if (m_mainAxisScaling == AxisScaling::ScaleDown) {
if (m_mainAxisScaling != AxisScaling::Scale) {
break;
}
// scale up the nodes, we are under the limit
@ -525,14 +541,29 @@ void SimpleAxisLayout::Impl::applyCrossPositioning(CCNode* layout, std::vector<C
}
}
}
void SimpleAxisLayout::Impl::applyMainPositioning(CCNode* layout, std::vector<CCNode*> const& nodes, std::vector<SpacerNode*> const& spacers) {
void SimpleAxisLayout::Impl::applyMainPositioning(CCNode* layout, std::vector<CCNode*> const& nodes, std::vector<SpacerNode*> const& spacers, float totalGap) {
// get the limits we are working with
auto totalHeight = 0.f;
auto totalHeight = totalGap;
for (auto node : nodes) {
auto const height = this->getContentHeight(node) * this->getScale(node);
totalHeight += height;
}
auto const layoutHeight = this->getContentHeight(layout);
auto gapPercentage = 1.f;
if (m_mainAxisScaling == AxisScaling::ScaleDownGaps) {
if (totalHeight > layoutHeight && totalHeight - totalGap <= layoutHeight) {
auto const difference = totalHeight - layoutHeight;
gapPercentage = 1.f - difference / totalGap;
totalHeight = layoutHeight;
}
else if (totalHeight > layoutHeight) {
// remove as much as we can
gapPercentage = 0.f;
totalHeight -= totalGap;
}
}
auto const remainingHeight = layoutHeight - totalHeight;
auto extraGap = remainingHeight;
@ -606,13 +637,13 @@ void SimpleAxisLayout::Impl::applyMainPositioning(CCNode* layout, std::vector<CC
for (auto node : nodes) {
// apply the gap between the nodes
if (auto gap = typeinfo_cast<AxisGap*>(node)) {
offset += gap->getGap();
offset += gap->getGap() * gapPercentage;
lastChild = nullptr;
continue;
}
// otherwise use the default gap
if (lastChild) {
offset += m_gap;
offset += m_gap * gapPercentage;
}
auto const height = this->getContentHeight(node) * this->getScale(node);
@ -720,7 +751,7 @@ void SimpleAxisLayout::Impl::apply(cocos2d::CCNode* layout) {
// apply positions
this->applyCrossPositioning(layout, realChildren);
this->applyMainPositioning(layout, positionChildren, spacers);
this->applyMainPositioning(layout, positionChildren, spacers, totalGap);
}
SimpleAxisLayout::SimpleAxisLayout(Axis axis) : m_impl(std::make_unique<Impl>(axis)) {}

View file

@ -63,8 +63,9 @@ $register_ids(MenuLayer) {
if (auto pfp = setIDSafe(menu, 3, "profile-button")) {
auto profileMenu = detachAndCreateMenu(
this, "profile-menu",
RowLayout::create()
->setAxisAlignment(AxisAlignment::Start),
SimpleRowLayout::create()
->setMainAxisAlignment(MainAxisAlignment::Start)
->setGap(5.f),
pfp
);
profileMenu->setContentSize({ 150.f, 50.f });
@ -81,9 +82,9 @@ $register_ids(MenuLayer) {
menu->setContentSize({ winSize.width - 140.f, 65.f });
menu->setLayout(
RowLayout::create()
SimpleRowLayout::create()
->setGap(18.f)
->setCrossAxisOverflow(true)
->setCrossAxisScaling(AxisScaling::Grow)
);
}
@ -108,9 +109,20 @@ $register_ids(MenuLayer) {
menu->updateLayout();
}
for (int i = 0; i < 5; ++i) {
auto myButton = CCMenuItemSpriteExtra::create(
CCSprite::createWithSpriteFrameName("GJ_likeBtn_001.png"),
this,
nullptr
);
menu->addChild(myButton);
}
menu->setContentSize({ winSize.width - 220.f, 65.f });
menu->setLayout(
RowLayout::create()
SimpleRowLayout::create()
->setGap(5.f)
);
}
@ -136,8 +148,9 @@ $register_ids(MenuLayer) {
auto closeMenu = detachAndCreateMenu(
this,
"close-menu",
RowLayout::create()
->setAxisAlignment(AxisAlignment::Start),
SimpleRowLayout::create()
->setMainAxisAlignment(MainAxisAlignment::Start)
->setGap(5.f),
closeBtn
);
closeMenu->setContentSize({ 200.f, 50.f });
@ -154,9 +167,10 @@ $register_ids(MenuLayer) {
getSizeSafe(moreGamesBtn).width / 2
);
menu->setLayout(
RowLayout::create()
->setAxisAlignment(AxisAlignment::End)
->setAxisReverse(true)
SimpleRowLayout::create()
->setMainAxisAlignment(MainAxisAlignment::Start)
->setMainAxisDirection(AxisDirection::RightToLeft)
->setGap(5.f)
);
}
@ -168,9 +182,10 @@ $register_ids(MenuLayer) {
topRightMenu->setID("top-right-menu");
topRightMenu->setContentSize({ 200.f, 50.f });
topRightMenu->setLayout(
RowLayout::create()
->setAxisReverse(true)
->setAxisAlignment(AxisAlignment::End)
SimpleRowLayout::create()
->setMainAxisDirection(AxisDirection::RightToLeft)
->setMainAxisAlignment(MainAxisAlignment::Start)
->setGap(5.f)
);
this->addChild(topRightMenu);