mirror of
https://github.com/geode-sdk/geode.git
synced 2024-11-26 17:36:05 -05:00
finished design for AnchorLayout
This commit is contained in:
parent
7654f6e7cd
commit
aa949aed39
11 changed files with 261 additions and 129 deletions
11
loader/include/Geode/cocos/base_nodes/CCNode.h
vendored
11
loader/include/Geode/cocos/base_nodes/CCNode.h
vendored
|
@ -995,14 +995,11 @@ public:
|
||||||
*/
|
*/
|
||||||
GEODE_DLL LayoutOptions* getLayoutOptions();
|
GEODE_DLL LayoutOptions* getLayoutOptions();
|
||||||
/**
|
/**
|
||||||
* Set the position of this node relative to its parent. **This requires
|
* Adds a child at an anchored position
|
||||||
* the parent node to have AnchorLayout set as its layout** - this function
|
* Overrides the current layout to AnchorLayout!
|
||||||
* will set it if the parent has no layout enabled, but if the parent has
|
* @note Geode addition
|
||||||
* something else, this function does nothing.
|
|
||||||
* @param anchor The position of this node relative to its parent
|
|
||||||
* @param offset Offset from the anchored position
|
|
||||||
*/
|
*/
|
||||||
GEODE_DLL void setAnchoredPosition(Anchor anchor, CCPoint const& offset = CCPointZero);
|
GEODE_DLL void addChildAtPosition(CCNode* child, Anchor anchor, CCPoint const& offset = CCPointZero);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Swap two children
|
* Swap two children
|
||||||
|
|
17
loader/include/Geode/cocos/base_nodes/Layout.hpp
vendored
17
loader/include/Geode/cocos/base_nodes/Layout.hpp
vendored
|
@ -410,6 +410,23 @@ public:
|
||||||
|
|
||||||
void apply(CCNode* on) override;
|
void apply(CCNode* on) override;
|
||||||
CCSize getSizeHint(CCNode* on) const override;
|
CCSize getSizeHint(CCNode* on) const override;
|
||||||
|
|
||||||
|
static CCPoint getAnchoredPosition(CCNode* in, Anchor anchor, CCPoint const& offset);
|
||||||
|
};
|
||||||
|
|
||||||
|
class AutoSizeLayout : public cocos2d::AnchorLayout {
|
||||||
|
protected:
|
||||||
|
cocos2d::CCArray* m_targets;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static AutoSizeLayout* create();
|
||||||
|
virtual ~AutoSizeLayout();
|
||||||
|
|
||||||
|
AutoSizeLayout* add(cocos2d::CCNode* target);
|
||||||
|
AutoSizeLayout* remove(cocos2d::CCNode* target);
|
||||||
|
|
||||||
|
void apply(cocos2d::CCNode* in) override;
|
||||||
|
cocos2d::CCSize getSizeHint(cocos2d::CCNode* in) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
|
|
|
@ -13,15 +13,19 @@ namespace geode {
|
||||||
cocos2d::extension::CCScale9Sprite* m_bgSprite;
|
cocos2d::extension::CCScale9Sprite* m_bgSprite;
|
||||||
cocos2d::CCLabelBMFont* m_title = nullptr;
|
cocos2d::CCLabelBMFont* m_title = nullptr;
|
||||||
CCMenuItemSpriteExtra* m_closeBtn;
|
CCMenuItemSpriteExtra* m_closeBtn;
|
||||||
|
bool m_dynamic;
|
||||||
|
|
||||||
~Popup() override {
|
~Popup() override {
|
||||||
cocos2d::CCTouchDispatcher::get()->unregisterForcePrio(this);
|
cocos2d::CCTouchDispatcher::get()->unregisterForcePrio(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool init(
|
private:
|
||||||
float width, float height, InitArgs... args, char const* bg = "GJ_square01.png",
|
bool initBase(
|
||||||
cocos2d::CCRect bgRect = { 0, 0, 80, 80 }
|
float width, float height, InitArgs... args, char const* bg,
|
||||||
|
cocos2d::CCRect bgRect, bool dynamic
|
||||||
) {
|
) {
|
||||||
|
m_dynamic = dynamic;
|
||||||
|
|
||||||
auto winSize = cocos2d::CCDirector::sharedDirector()->getWinSize();
|
auto winSize = cocos2d::CCDirector::sharedDirector()->getWinSize();
|
||||||
m_size = cocos2d::CCSize { width, height };
|
m_size = cocos2d::CCSize { width, height };
|
||||||
|
|
||||||
|
@ -38,6 +42,17 @@ namespace geode {
|
||||||
m_buttonMenu->setZOrder(100);
|
m_buttonMenu->setZOrder(100);
|
||||||
m_mainLayer->addChild(m_buttonMenu);
|
m_mainLayer->addChild(m_buttonMenu);
|
||||||
|
|
||||||
|
if (dynamic) {
|
||||||
|
m_mainLayer->ignoreAnchorPointForPosition(false);
|
||||||
|
m_mainLayer->setPosition(winSize / 2);
|
||||||
|
m_mainLayer->setContentSize(m_size);
|
||||||
|
m_mainLayer->setLayout(
|
||||||
|
cocos2d::AutoSizeLayout::create()
|
||||||
|
->add(m_buttonMenu)
|
||||||
|
->add(m_bgSprite)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
this->setTouchEnabled(true);
|
this->setTouchEnabled(true);
|
||||||
|
|
||||||
auto closeSpr = cocos2d::CCSprite::createWithSpriteFrameName("GJ_closeBtn_001.png");
|
auto closeSpr = cocos2d::CCSprite::createWithSpriteFrameName("GJ_closeBtn_001.png");
|
||||||
|
@ -46,8 +61,13 @@ namespace geode {
|
||||||
m_closeBtn = CCMenuItemSpriteExtra::create(
|
m_closeBtn = CCMenuItemSpriteExtra::create(
|
||||||
closeSpr, this, (cocos2d::SEL_MenuHandler)(&Popup::onClose)
|
closeSpr, this, (cocos2d::SEL_MenuHandler)(&Popup::onClose)
|
||||||
);
|
);
|
||||||
m_closeBtn->setAnchoredPosition(cocos2d::Anchor::TopLeft);
|
if (dynamic) {
|
||||||
|
m_buttonMenu->addChildAtPosition(m_closeBtn, cocos2d::Anchor::TopLeft, { 3.f, -3.f });
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_closeBtn->setPosition(-m_size.width / 2 + 3.f, m_size.height / 2 - 3.f);
|
||||||
m_buttonMenu->addChild(m_closeBtn);
|
m_buttonMenu->addChild(m_closeBtn);
|
||||||
|
}
|
||||||
|
|
||||||
if (!setup(std::forward<InitArgs>(args)...)) {
|
if (!setup(std::forward<InitArgs>(args)...)) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -63,6 +83,22 @@ namespace geode {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
[[deprecated("Use Popup::initDynamic instead, as it has more reasonable menu and layer content sizes")]]
|
||||||
|
bool init(
|
||||||
|
float width, float height, InitArgs... args, char const* bg = "GJ_square01.png",
|
||||||
|
cocos2d::CCRect bgRect = { 0, 0, 80, 80 }
|
||||||
|
) {
|
||||||
|
return this->initBase(width, height, std::forward<InitArgs>(args)..., bg, bgRect, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool initDynamic(
|
||||||
|
float width, float height, InitArgs... args, char const* bg = "GJ_square01.png",
|
||||||
|
cocos2d::CCRect bgRect = { 0, 0, 80, 80 }
|
||||||
|
) {
|
||||||
|
return this->initBase(width, height, std::forward<InitArgs>(args)..., bg, bgRect, true);
|
||||||
|
}
|
||||||
|
|
||||||
virtual bool setup(InitArgs... args) = 0;
|
virtual bool setup(InitArgs... args) = 0;
|
||||||
|
|
||||||
void keyDown(cocos2d::enumKeyCodes key) {
|
void keyDown(cocos2d::enumKeyCodes key) {
|
||||||
|
@ -84,11 +120,17 @@ namespace geode {
|
||||||
) {
|
) {
|
||||||
if (m_title) {
|
if (m_title) {
|
||||||
m_title->setString(title.c_str());
|
m_title->setString(title.c_str());
|
||||||
} else {
|
}
|
||||||
auto winSize = cocos2d::CCDirector::sharedDirector()->getWinSize();
|
else {
|
||||||
m_title = cocos2d::CCLabelBMFont::create(title.c_str(), font);
|
m_title = cocos2d::CCLabelBMFont::create(title.c_str(), font);
|
||||||
m_title->setAnchoredPosition(cocos2d::Anchor::Top, ccp(0, -offset));
|
m_title->setZOrder(2);
|
||||||
m_mainLayer->addChild(m_title, 2);
|
if (m_dynamic) {
|
||||||
|
m_mainLayer->addChildAtPosition(m_title, cocos2d::Anchor::Top, ccp(0, -offset));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
auto winSize = cocos2d::CCDirector::get()->getWinSize();
|
||||||
|
m_title->setPosition(winSize / 2 + ccp(0, m_size.height / 2 - offset));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
m_title->limitLabelWidth(m_size.width - 20.f, scale, .1f);
|
m_title->limitLabelWidth(m_size.width - 20.f, scale, .1f);
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,7 @@ AnchorLayout* AnchorLayout::create() {
|
||||||
void AnchorLayout::apply(CCNode* on) {
|
void AnchorLayout::apply(CCNode* on) {
|
||||||
on->ignoreAnchorPointForPosition(false);
|
on->ignoreAnchorPointForPosition(false);
|
||||||
for (auto node : CCArrayExt<CCNode*>(this->getNodesToPosition(on))) {
|
for (auto node : CCArrayExt<CCNode*>(this->getNodesToPosition(on))) {
|
||||||
if (auto opts = typeinfo_cast<AnchorLayoutOptions*>(node)) {
|
if (auto opts = typeinfo_cast<AnchorLayoutOptions*>(node->getLayoutOptions())) {
|
||||||
auto pos = opts->getOffset();
|
auto pos = opts->getOffset();
|
||||||
auto size = on->getContentSize();
|
auto size = on->getContentSize();
|
||||||
switch (opts->getAnchor()) {
|
switch (opts->getAnchor()) {
|
||||||
|
@ -60,6 +60,23 @@ void AnchorLayout::apply(CCNode* on) {
|
||||||
}
|
}
|
||||||
|
|
||||||
CCSize AnchorLayout::getSizeHint(CCNode* on) const {
|
CCSize AnchorLayout::getSizeHint(CCNode* on) const {
|
||||||
// AnchorLayout doesn't resize its target in any way
|
|
||||||
return on->getContentSize();
|
return on->getContentSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CCPoint AnchorLayout::getAnchoredPosition(CCNode* in, Anchor anchor, CCPoint const& offset) {
|
||||||
|
auto pos = offset;
|
||||||
|
auto size = in->getContentSize();
|
||||||
|
switch (anchor) {
|
||||||
|
default:
|
||||||
|
case Anchor::Center: pos += size / 2; break;
|
||||||
|
case Anchor::TopLeft: pos += ccp(0, size.height); break;
|
||||||
|
case Anchor::Top: pos += ccp(size.width / 2, size.height); break;
|
||||||
|
case Anchor::TopRight: pos += ccp(size.width, size.height); break;
|
||||||
|
case Anchor::Right: pos += ccp(size.width, size.height / 2); break;
|
||||||
|
case Anchor::BottomRight: pos += ccp(size.width, 0); break;
|
||||||
|
case Anchor::Bottom: pos += ccp(size.width / 2, 0); break;
|
||||||
|
case Anchor::BottomLeft: pos += ccp(0, 0); break;
|
||||||
|
case Anchor::Left: pos += ccp(0, size.height / 2); break;
|
||||||
|
}
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
46
loader/src/cocos2d-ext/AutoSizeLayout.cpp
Normal file
46
loader/src/cocos2d-ext/AutoSizeLayout.cpp
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
#include <cocos2d.h>
|
||||||
|
#include <Geode/utils/cocos.hpp>
|
||||||
|
#include <Geode/utils/ranges.hpp>
|
||||||
|
#include <Geode/loader/Log.hpp>
|
||||||
|
#include <Geode/binding/CCMenuItemSpriteExtra.hpp>
|
||||||
|
#include <Geode/binding/CCMenuItemToggler.hpp>
|
||||||
|
|
||||||
|
using namespace geode::prelude;
|
||||||
|
|
||||||
|
AutoSizeLayout* AutoSizeLayout::create() {
|
||||||
|
auto ret = new AutoSizeLayout();
|
||||||
|
ret->m_targets = CCArray::create();
|
||||||
|
ret->m_targets->retain();
|
||||||
|
ret->autorelease();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
AutoSizeLayout::~AutoSizeLayout() {
|
||||||
|
m_targets->release();
|
||||||
|
}
|
||||||
|
|
||||||
|
AutoSizeLayout* AutoSizeLayout::add(CCNode* target) {
|
||||||
|
m_targets->addObject(target);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
AutoSizeLayout* AutoSizeLayout::remove(CCNode* target) {
|
||||||
|
m_targets->removeObject(target);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AutoSizeLayout::apply(CCNode* in) {
|
||||||
|
AnchorLayout::apply(in);
|
||||||
|
for (auto& node : CCArrayExt<CCNode*>(m_targets)) {
|
||||||
|
// Prevent accidental infinite loop
|
||||||
|
if (node == in) continue;
|
||||||
|
node->ignoreAnchorPointForPosition(false);
|
||||||
|
node->setContentSize(in->getContentSize());
|
||||||
|
node->setPosition(in->getContentSize() / 2);
|
||||||
|
node->updateLayout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CCSize AutoSizeLayout::getSizeHint(CCNode* in) const {
|
||||||
|
return in->getContentSize();
|
||||||
|
}
|
|
@ -237,17 +237,16 @@ size_t CCNode::getEventListenerCount() {
|
||||||
GeodeNodeMetadata::set(this)->m_eventListeners.size();
|
GeodeNodeMetadata::set(this)->m_eventListeners.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCNode::setAnchoredPosition(Anchor anchor, CCPoint const& offset) {
|
void CCNode::addChildAtPosition(CCNode* child, Anchor anchor, CCPoint const& offset) {
|
||||||
auto parent = this->getParent();
|
auto layout = this->getLayout();
|
||||||
// If this node's parent doesn't have any layout, then set it as AnchorLayout
|
if (!layout) {
|
||||||
if (parent && parent->getLayout() == nullptr) {
|
this->setLayout(AnchorLayout::create());
|
||||||
parent->setLayout(AnchorLayout::create());
|
|
||||||
}
|
}
|
||||||
// Otherwise require that it already has AnchorLayout (or AnchorLayout-derived class)
|
// Setting the layout options always (even if the parent isn't AnchorLayout)
|
||||||
else if (parent && !typeinfo_cast<AnchorLayout*>(parent->getLayout())) {
|
// so if it set as AnchorLayout later it will auto-update
|
||||||
return;
|
child->setPosition(AnchorLayout::getAnchoredPosition(this, anchor, offset));
|
||||||
}
|
child->setLayoutOptions(AnchorLayoutOptions::create()->setAnchor(anchor)->setOffset(offset));
|
||||||
this->setLayoutOptions(AnchorLayoutOptions::create()->setAnchor(anchor)->setOffset(offset));
|
this->addChild(child);
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
|
|
|
@ -37,16 +37,15 @@ bool ModInfoPopup::setup(ModMetadata const& metadata, ModListLayer* list) {
|
||||||
constexpr float logoOffset = 10.f;
|
constexpr float logoOffset = 10.f;
|
||||||
|
|
||||||
auto topNode = CCNode::create();
|
auto topNode = CCNode::create();
|
||||||
topNode->setContentSize({350.f, 80.f});
|
topNode->setAnchorPoint({ .5f, .5f });
|
||||||
|
topNode->setContentSize({ 350.f, 80.f });
|
||||||
topNode->setLayout(
|
topNode->setLayout(
|
||||||
RowLayout::create()
|
RowLayout::create()
|
||||||
->setAxisAlignment(AxisAlignment::Center)
|
->setAxisAlignment(AxisAlignment::Center)
|
||||||
->setAutoScale(false)
|
->setAutoScale(false)
|
||||||
->setCrossAxisOverflow(true)
|
->setCrossAxisOverflow(true)
|
||||||
);
|
);
|
||||||
m_mainLayer->addChild(topNode);
|
m_mainLayer->addChildAtPosition(topNode, Anchor::Top, ccp(0, -30));
|
||||||
topNode->setAnchorPoint({.5f, .5f});
|
|
||||||
topNode->setPosition(winSize.width / 2, winSize.height / 2 + 115.f);
|
|
||||||
|
|
||||||
auto logoSpr = this->createLogo({logoSize, logoSize});
|
auto logoSpr = this->createLogo({logoSize, logoSize});
|
||||||
topNode->addChild(logoSpr);
|
topNode->addChild(logoSpr);
|
||||||
|
@ -88,18 +87,13 @@ bool ModInfoPopup::setup(ModMetadata const& metadata, ModListLayer* list) {
|
||||||
(metadata.getDetails() ? metadata.getDetails().value() : "### No description provided."),
|
(metadata.getDetails() ? metadata.getDetails().value() : "### No description provided."),
|
||||||
{ 350.f, 137.5f }
|
{ 350.f, 137.5f }
|
||||||
);
|
);
|
||||||
m_detailsArea->setPosition(
|
m_mainLayer->addChildAtPosition(m_detailsArea, Anchor::Center, ccp(0, -20));
|
||||||
winSize.width / 2 - m_detailsArea->getScaledContentSize().width / 2,
|
|
||||||
winSize.height / 2 - m_detailsArea->getScaledContentSize().height / 2 - 20.f
|
|
||||||
);
|
|
||||||
m_mainLayer->addChild(m_detailsArea);
|
|
||||||
|
|
||||||
m_scrollbar = Scrollbar::create(m_detailsArea->getScrollLayer());
|
m_scrollbar = Scrollbar::create(m_detailsArea->getScrollLayer());
|
||||||
m_scrollbar->setPosition(
|
m_mainLayer->addChildAtPosition(
|
||||||
winSize.width / 2 + m_detailsArea->getScaledContentSize().width / 2 + 20.f,
|
m_scrollbar, Anchor::Center,
|
||||||
winSize.height / 2 - 20.f
|
ccp(m_detailsArea->getScaledContentSize().width / 2 + 20.f, -20)
|
||||||
);
|
);
|
||||||
m_mainLayer->addChild(m_scrollbar);
|
|
||||||
|
|
||||||
// changelog
|
// changelog
|
||||||
if (metadata.getChangelog()) {
|
if (metadata.getChangelog()) {
|
||||||
|
@ -127,10 +121,10 @@ bool ModInfoPopup::setup(ModMetadata const& metadata, ModListLayer* list) {
|
||||||
changelogBtnOnSpr->setScale(.65f);
|
changelogBtnOnSpr->setScale(.65f);
|
||||||
|
|
||||||
auto changelogBtn = CCMenuItemToggler::create(
|
auto changelogBtn = CCMenuItemToggler::create(
|
||||||
changelogBtnOffSpr, changelogBtnOnSpr, this, menu_selector(ModInfoPopup::onChangelog)
|
changelogBtnOffSpr, changelogBtnOnSpr,
|
||||||
|
this, menu_selector(ModInfoPopup::onChangelog)
|
||||||
);
|
);
|
||||||
changelogBtn->setPosition(-LAYER_SIZE.width / 2 + 21.5f, .0f);
|
m_buttonMenu->addChildAtPosition(changelogBtn, Anchor::Left, ccp(21.5f, 0));
|
||||||
m_buttonMenu->addChild(changelogBtn);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// mod metadata
|
// mod metadata
|
||||||
|
@ -138,8 +132,7 @@ bool ModInfoPopup::setup(ModMetadata const& metadata, ModListLayer* list) {
|
||||||
infoSpr->setScale(.85f);
|
infoSpr->setScale(.85f);
|
||||||
|
|
||||||
m_infoBtn = CCMenuItemSpriteExtra::create(infoSpr, this, menu_selector(ModInfoPopup::onInfo));
|
m_infoBtn = CCMenuItemSpriteExtra::create(infoSpr, this, menu_selector(ModInfoPopup::onInfo));
|
||||||
m_infoBtn->setPosition(LAYER_SIZE.width / 2 - 25.f, LAYER_SIZE.height / 2 - 25.f);
|
m_buttonMenu->addChildAtPosition(m_infoBtn, Anchor::TopRight, ccp(-25, -25));
|
||||||
m_buttonMenu->addChild(m_infoBtn);
|
|
||||||
|
|
||||||
// repo button
|
// repo button
|
||||||
if (metadata.getRepository()) {
|
if (metadata.getRepository()) {
|
||||||
|
@ -148,8 +141,7 @@ bool ModInfoPopup::setup(ModMetadata const& metadata, ModListLayer* list) {
|
||||||
this,
|
this,
|
||||||
menu_selector(ModInfoPopup::onRepository)
|
menu_selector(ModInfoPopup::onRepository)
|
||||||
);
|
);
|
||||||
repoBtn->setPosition(LAYER_SIZE.width / 2 - 25.f, -LAYER_SIZE.height / 2 + 25.f);
|
m_buttonMenu->addChildAtPosition(repoBtn, Anchor::BottomRight, ccp(-25, 25));
|
||||||
m_buttonMenu->addChild(repoBtn);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// support button
|
// support button
|
||||||
|
@ -159,8 +151,7 @@ bool ModInfoPopup::setup(ModMetadata const& metadata, ModListLayer* list) {
|
||||||
this,
|
this,
|
||||||
menu_selector(ModInfoPopup::onSupport)
|
menu_selector(ModInfoPopup::onSupport)
|
||||||
);
|
);
|
||||||
supportBtn->setPosition(LAYER_SIZE.width / 2 - 60.f, -LAYER_SIZE.height / 2 + 25.f);
|
m_buttonMenu->addChildAtPosition(supportBtn, Anchor::BottomRight, ccp(-60, 25));
|
||||||
m_buttonMenu->addChild(supportBtn);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -204,40 +195,12 @@ void ModInfoPopup::onInfo(CCObject*) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModInfoPopup::onChangelog(CCObject* sender) {
|
void ModInfoPopup::onChangelog(CCObject* sender) {
|
||||||
auto winSize = CCDirector::get()->getWinSize();
|
|
||||||
|
|
||||||
if (!m_changelogArea) {
|
|
||||||
m_changelogArea = MDTextArea::create(this->getMetadata().getChangelog().value(), { 350.f, 137.5f });
|
|
||||||
m_changelogArea->setPosition(
|
|
||||||
-5000.f, winSize.height / 2 - m_changelogArea->getScaledContentSize().height / 2 - 20.f
|
|
||||||
);
|
|
||||||
m_changelogArea->setVisible(false);
|
|
||||||
m_mainLayer->addChild(m_changelogArea);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto toggle = static_cast<CCMenuItemToggler*>(sender);
|
auto toggle = static_cast<CCMenuItemToggler*>(sender);
|
||||||
|
m_detailsArea->setString((
|
||||||
m_detailsArea->setVisible(toggle->isToggled());
|
|
||||||
// as it turns out, cocos2d is stupid and still passes touch
|
|
||||||
// events to invisible nodes
|
|
||||||
m_detailsArea->setPositionX(
|
|
||||||
toggle->isToggled() ? winSize.width / 2 - m_detailsArea->getScaledContentSize().width / 2 :
|
|
||||||
-5000.f
|
|
||||||
);
|
|
||||||
|
|
||||||
m_changelogArea->setVisible(!toggle->isToggled());
|
|
||||||
// as it turns out, cocos2d is stupid and still passes touch
|
|
||||||
// events to invisible nodes
|
|
||||||
m_changelogArea->setPositionX(
|
|
||||||
!toggle->isToggled() ? winSize.width / 2 - m_changelogArea->getScaledContentSize().width / 2 :
|
|
||||||
-5000.f
|
|
||||||
);
|
|
||||||
|
|
||||||
m_scrollbar->setTarget(
|
|
||||||
toggle->isToggled() ?
|
toggle->isToggled() ?
|
||||||
m_detailsArea->getScrollLayer() :
|
this->getMetadata().getDetails().value() :
|
||||||
m_changelogArea->getScrollLayer()
|
this->getMetadata().getChangelog().value()
|
||||||
);
|
).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModInfoPopup::setInstallStatus(std::optional<UpdateProgress> const& progress) {
|
void ModInfoPopup::setInstallStatus(std::optional<UpdateProgress> const& progress) {
|
||||||
|
@ -349,14 +312,15 @@ LocalModInfoPopup::LocalModInfoPopup()
|
||||||
ModInstallFilter("")
|
ModInstallFilter("")
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
|
|
||||||
bool LocalModInfoPopup::init(Mod* mod, ModListLayer* list) {
|
bool LocalModInfoPopup::init(Mod* mod, ModListLayer* list) {
|
||||||
m_item = Index::get()->getMajorItem(mod->getMetadata().getID());
|
m_item = Index::get()->getMajorItem(mod->getMetadata().getID());
|
||||||
if (m_item)
|
if (m_item) {
|
||||||
m_installListener.setFilter(m_item->getMetadata().getID());
|
m_installListener.setFilter(m_item->getMetadata().getID());
|
||||||
|
}
|
||||||
|
|
||||||
m_mod = mod;
|
m_mod = mod;
|
||||||
|
|
||||||
if (!ModInfoPopup::init(LAYER_SIZE.width, LAYER_SIZE.height, mod->getMetadata(), list)) return false;
|
if (!ModInfoPopup::initDynamic(LAYER_SIZE.width, LAYER_SIZE.height, mod->getMetadata(), list)) return false;
|
||||||
|
|
||||||
auto winSize = CCDirector::sharedDirector()->getWinSize();
|
auto winSize = CCDirector::sharedDirector()->getWinSize();
|
||||||
|
|
||||||
|
@ -364,10 +328,10 @@ bool LocalModInfoPopup::init(Mod* mod, ModListLayer* list) {
|
||||||
auto settingsSpr = CCSprite::createWithSpriteFrameName("GJ_optionsBtn_001.png");
|
auto settingsSpr = CCSprite::createWithSpriteFrameName("GJ_optionsBtn_001.png");
|
||||||
settingsSpr->setScale(.65f);
|
settingsSpr->setScale(.65f);
|
||||||
|
|
||||||
auto settingsBtn =
|
auto settingsBtn = CCMenuItemSpriteExtra::create(
|
||||||
CCMenuItemSpriteExtra::create(settingsSpr, this, menu_selector(LocalModInfoPopup::onSettings));
|
settingsSpr, this, menu_selector(LocalModInfoPopup::onSettings)
|
||||||
settingsBtn->setPosition(-LAYER_SIZE.width / 2 + 25.f, -LAYER_SIZE.height / 2 + 25.f);
|
);
|
||||||
m_buttonMenu->addChild(settingsBtn);
|
m_buttonMenu->addChildAtPosition(settingsBtn, Anchor::BottomLeft, ccp(25, 25));
|
||||||
|
|
||||||
// Check if a config directory for the mod exists
|
// Check if a config directory for the mod exists
|
||||||
if (ghc::filesystem::exists(mod->getConfigDir(false))) {
|
if (ghc::filesystem::exists(mod->getConfigDir(false))) {
|
||||||
|
@ -379,8 +343,7 @@ bool LocalModInfoPopup::init(Mod* mod, ModListLayer* list) {
|
||||||
auto configBtn = CCMenuItemSpriteExtra::create(
|
auto configBtn = CCMenuItemSpriteExtra::create(
|
||||||
configSpr, this, menu_selector(LocalModInfoPopup::onOpenConfigDir)
|
configSpr, this, menu_selector(LocalModInfoPopup::onOpenConfigDir)
|
||||||
);
|
);
|
||||||
configBtn->setPosition(-LAYER_SIZE.width / 2 + 65.f, -LAYER_SIZE.height / 2 + 25.f);
|
m_buttonMenu->addChildAtPosition(configBtn, Anchor::BottomLeft, ccp(65, 25));
|
||||||
m_buttonMenu->addChild(configBtn);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mod->hasSettings()) {
|
if (!mod->hasSettings()) {
|
||||||
|
@ -397,9 +360,8 @@ bool LocalModInfoPopup::init(Mod* mod, ModListLayer* list) {
|
||||||
auto enableBtn = CCMenuItemToggler::create(
|
auto enableBtn = CCMenuItemToggler::create(
|
||||||
disableBtnSpr, enableBtnSpr, this, menu_selector(LocalModInfoPopup::onEnableMod)
|
disableBtnSpr, enableBtnSpr, this, menu_selector(LocalModInfoPopup::onEnableMod)
|
||||||
);
|
);
|
||||||
enableBtn->setPosition(-155.f, 75.f);
|
|
||||||
enableBtn->toggle(!mod->shouldLoad());
|
enableBtn->toggle(!mod->shouldLoad());
|
||||||
m_buttonMenu->addChild(enableBtn);
|
m_buttonMenu->addChildAtPosition(enableBtn, Anchor::Center, ccp(-155, 75));
|
||||||
|
|
||||||
if (mod->isInternal()) {
|
if (mod->isInternal()) {
|
||||||
enableBtn->setTarget(this, menu_selector(LocalModInfoPopup::onDisablingNotSupported));
|
enableBtn->setTarget(this, menu_selector(LocalModInfoPopup::onDisablingNotSupported));
|
||||||
|
@ -420,8 +382,7 @@ bool LocalModInfoPopup::init(Mod* mod, ModListLayer* list) {
|
||||||
auto uninstallBtn = CCMenuItemSpriteExtra::create(
|
auto uninstallBtn = CCMenuItemSpriteExtra::create(
|
||||||
uninstallBtnSpr, this, menu_selector(LocalModInfoPopup::onUninstall)
|
uninstallBtnSpr, this, menu_selector(LocalModInfoPopup::onUninstall)
|
||||||
);
|
);
|
||||||
uninstallBtn->setPosition(-85.f, 75.f);
|
m_buttonMenu->addChildAtPosition(uninstallBtn, Anchor::Center, ccp(-85, 75));
|
||||||
m_buttonMenu->addChild(uninstallBtn);
|
|
||||||
|
|
||||||
// todo: show update button on loader that invokes the installer
|
// todo: show update button on loader that invokes the installer
|
||||||
if (m_item && Index::get()->isUpdateAvailable(m_item)) {
|
if (m_item && Index::get()->isUpdateAvailable(m_item)) {
|
||||||
|
@ -434,20 +395,21 @@ bool LocalModInfoPopup::init(Mod* mod, ModListLayer* list) {
|
||||||
m_installBtnSpr->setScale(.6f);
|
m_installBtnSpr->setScale(.6f);
|
||||||
|
|
||||||
m_installBtn = CCMenuItemSpriteExtra::create(m_installBtnSpr, this, menu_selector(LocalModInfoPopup::onUpdate));
|
m_installBtn = CCMenuItemSpriteExtra::create(m_installBtnSpr, this, menu_selector(LocalModInfoPopup::onUpdate));
|
||||||
m_installBtn->setPosition(-8.0f, 75.f);
|
m_buttonMenu->addChildAtPosition(m_installBtn, Anchor::Center, ccp(-8, 75));
|
||||||
m_buttonMenu->addChild(m_installBtn);
|
|
||||||
|
|
||||||
m_installStatus = DownloadStatusNode::create();
|
m_installStatus = DownloadStatusNode::create();
|
||||||
m_installStatus->setPosition(winSize.width / 2 + 105.f, winSize.height / 2 + 75.f);
|
|
||||||
m_installStatus->setVisible(false);
|
m_installStatus->setVisible(false);
|
||||||
m_mainLayer->addChild(m_installStatus);
|
m_mainLayer->addChildAtPosition(m_installStatus, Anchor::Center, ccp(105, 75));
|
||||||
|
|
||||||
auto minorIndexItem = Index::get()->getItem(
|
auto minorIndexItem = Index::get()->getItem(
|
||||||
mod->getMetadata().getID(),
|
mod->getMetadata().getID(),
|
||||||
ComparableVersionInfo(mod->getMetadata().getVersion(), VersionCompare::MoreEq)
|
ComparableVersionInfo(mod->getMetadata().getVersion(), VersionCompare::MoreEq)
|
||||||
);
|
);
|
||||||
|
|
||||||
// TODO: use column layout here?
|
auto availableContainer = CCNode::create();
|
||||||
|
availableContainer->setLayout(ColumnLayout::create()->setGap(2));
|
||||||
|
availableContainer->setAnchorPoint({ .0f, .5f });
|
||||||
|
availableContainer->setContentSize({ 200.f, 45.f });
|
||||||
|
|
||||||
if (m_item->getMetadata().getVersion().getMajor() > minorIndexItem->getMetadata().getVersion().getMajor()) {
|
if (m_item->getMetadata().getVersion().getMajor() > minorIndexItem->getMetadata().getVersion().getMajor()) {
|
||||||
// has major update
|
// has major update
|
||||||
|
@ -458,8 +420,7 @@ bool LocalModInfoPopup::init(Mod* mod, ModListLayer* list) {
|
||||||
m_latestVersionLabel->setScale(.35f);
|
m_latestVersionLabel->setScale(.35f);
|
||||||
m_latestVersionLabel->setAnchorPoint({.0f, .5f});
|
m_latestVersionLabel->setAnchorPoint({.0f, .5f});
|
||||||
m_latestVersionLabel->setColor({94, 219, 255});
|
m_latestVersionLabel->setColor({94, 219, 255});
|
||||||
m_latestVersionLabel->setPosition(winSize.width / 2 + 35.f, winSize.height / 2 + 75.f);
|
availableContainer->addChild(m_latestVersionLabel);
|
||||||
m_mainLayer->addChild(m_latestVersionLabel);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (minorIndexItem->getMetadata().getVersion() > mod->getMetadata().getVersion()) {
|
if (minorIndexItem->getMetadata().getVersion() > mod->getMetadata().getVersion()) {
|
||||||
|
@ -471,20 +432,11 @@ bool LocalModInfoPopup::init(Mod* mod, ModListLayer* list) {
|
||||||
m_minorVersionLabel->setScale(.35f);
|
m_minorVersionLabel->setScale(.35f);
|
||||||
m_minorVersionLabel->setAnchorPoint({.0f, .5f});
|
m_minorVersionLabel->setAnchorPoint({.0f, .5f});
|
||||||
m_minorVersionLabel->setColor({94, 219, 255});
|
m_minorVersionLabel->setColor({94, 219, 255});
|
||||||
if (m_latestVersionLabel) {
|
availableContainer->addChild(m_minorVersionLabel);
|
||||||
m_latestVersionLabel->setPosition(
|
|
||||||
winSize.width / 2 + 35.f, winSize.height / 2 + 81.f
|
|
||||||
);
|
|
||||||
m_minorVersionLabel->setPosition(
|
|
||||||
winSize.width / 2 + 35.f, winSize.height / 2 + 69.f
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
m_minorVersionLabel->setPosition(
|
|
||||||
winSize.width / 2 + 35.f, winSize.height / 2 + 75.f
|
|
||||||
);
|
|
||||||
}
|
|
||||||
m_mainLayer->addChild(m_minorVersionLabel);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
availableContainer->updateLayout();
|
||||||
|
m_mainLayer->addChildAtPosition(availableContainer, Anchor::Center, ccp(35, 75));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mod == Mod::get()) {
|
if (mod == Mod::get()) {
|
||||||
|
@ -494,11 +446,10 @@ bool LocalModInfoPopup::init(Mod* mod, ModListLayer* list) {
|
||||||
"chatFont.fnt"
|
"chatFont.fnt"
|
||||||
);
|
);
|
||||||
label->setAlignment(kCCTextAlignmentRight);
|
label->setAlignment(kCCTextAlignmentRight);
|
||||||
label->setAnchorPoint(ccp(1, 0));
|
label->setAnchorPoint({ .0f, .5f });
|
||||||
label->setScale(0.6f);
|
label->setScale(.5f);
|
||||||
label->setPosition(winSize.width - 3.f, 3.f);
|
|
||||||
label->setOpacity(89);
|
label->setOpacity(89);
|
||||||
m_mainLayer->addChild(label);
|
m_mainLayer->addChildAtPosition(label, Anchor::BottomRight, ccp(5, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
// issue report button
|
// issue report button
|
||||||
|
@ -511,8 +462,7 @@ bool LocalModInfoPopup::init(Mod* mod, ModListLayer* list) {
|
||||||
auto issuesBtn = CCMenuItemSpriteExtra::create(
|
auto issuesBtn = CCMenuItemSpriteExtra::create(
|
||||||
issuesBtnSpr, this, menu_selector(LocalModInfoPopup::onIssues)
|
issuesBtnSpr, this, menu_selector(LocalModInfoPopup::onIssues)
|
||||||
);
|
);
|
||||||
issuesBtn->setPosition(0.f, -LAYER_SIZE.height / 2 + 25.f);
|
m_buttonMenu->addChildAtPosition(issuesBtn, Anchor::Bottom, ccp(0, 25));
|
||||||
m_buttonMenu->addChild(issuesBtn);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -685,7 +635,7 @@ bool IndexItemInfoPopup::init(IndexItemHandle item, ModListLayer* list) {
|
||||||
|
|
||||||
auto winSize = CCDirector::sharedDirector()->getWinSize();
|
auto winSize = CCDirector::sharedDirector()->getWinSize();
|
||||||
|
|
||||||
if (!ModInfoPopup::init(LAYER_SIZE.width, LAYER_SIZE.height, item->getMetadata(), list)) return false;
|
if (!ModInfoPopup::initDynamic(LAYER_SIZE.width, LAYER_SIZE.height, item->getMetadata(), list)) return false;
|
||||||
|
|
||||||
// bruh why is this here if we are allowing for browsing already installed mods
|
// bruh why is this here if we are allowing for browsing already installed mods
|
||||||
// if (item->isInstalled()) return true;
|
// if (item->isInstalled()) return true;
|
||||||
|
@ -701,13 +651,11 @@ bool IndexItemInfoPopup::init(IndexItemHandle item, ModListLayer* list) {
|
||||||
m_installBtn = CCMenuItemSpriteExtra::create(
|
m_installBtn = CCMenuItemSpriteExtra::create(
|
||||||
m_installBtnSpr, this, menu_selector(IndexItemInfoPopup::onInstall)
|
m_installBtnSpr, this, menu_selector(IndexItemInfoPopup::onInstall)
|
||||||
);
|
);
|
||||||
m_installBtn->setPosition(-143.0f, 75.f);
|
m_buttonMenu->addChildAtPosition(m_installBtn, Anchor::Center, ccp(-143, 75));
|
||||||
m_buttonMenu->addChild(m_installBtn);
|
|
||||||
|
|
||||||
m_installStatus = DownloadStatusNode::create();
|
m_installStatus = DownloadStatusNode::create();
|
||||||
m_installStatus->setPosition(winSize.width / 2 - 25.f, winSize.height / 2 + 75.f);
|
|
||||||
m_installStatus->setVisible(false);
|
m_installStatus->setVisible(false);
|
||||||
m_mainLayer->addChild(m_installStatus);
|
m_mainLayer->addChildAtPosition(m_installStatus, Anchor::Center, ccp(-25, 75));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,6 @@ protected:
|
||||||
CCLabelBMFont* m_latestVersionLabel = nullptr;
|
CCLabelBMFont* m_latestVersionLabel = nullptr;
|
||||||
CCLabelBMFont* m_minorVersionLabel = nullptr;
|
CCLabelBMFont* m_minorVersionLabel = nullptr;
|
||||||
MDTextArea* m_detailsArea;
|
MDTextArea* m_detailsArea;
|
||||||
MDTextArea* m_changelogArea = nullptr;
|
|
||||||
Scrollbar* m_scrollbar;
|
Scrollbar* m_scrollbar;
|
||||||
IndexItemHandle m_item;
|
IndexItemHandle m_item;
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ bool MDPopup::setup(
|
||||||
m_size.height - 120.f,
|
m_size.height - 120.f,
|
||||||
};
|
};
|
||||||
auto content = MDTextArea::create(info, contentSize);
|
auto content = MDTextArea::create(info, contentSize);
|
||||||
content->setPosition(winSize / 2 - contentSize / 2);
|
content->setPosition(winSize / 2);
|
||||||
m_mainLayer->addChild(content);
|
m_mainLayer->addChild(content);
|
||||||
|
|
||||||
auto btnSpr = ButtonSprite::create(btn1Text);
|
auto btnSpr = ButtonSprite::create(btn1Text);
|
||||||
|
|
|
@ -108,6 +108,9 @@ Result<ccColor3B> colorForIdentifier(std::string const& tag) {
|
||||||
bool MDTextArea::init(std::string const& str, CCSize const& size) {
|
bool MDTextArea::init(std::string const& str, CCSize const& size) {
|
||||||
if (!CCLayer::init()) return false;
|
if (!CCLayer::init()) return false;
|
||||||
|
|
||||||
|
this->ignoreAnchorPointForPosition(false);
|
||||||
|
this->setAnchorPoint({ .5f, .5f });
|
||||||
|
|
||||||
m_text = str;
|
m_text = str;
|
||||||
m_size = size - CCSize { 15.f, 0.f };
|
m_size = size - CCSize { 15.f, 0.f };
|
||||||
this->setContentSize(m_size);
|
this->setContentSize(m_size);
|
||||||
|
@ -726,7 +729,6 @@ void MDTextArea::updateLabel() {
|
||||||
m_content->setPositionY(-2.5f);
|
m_content->setPositionY(-2.5f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
m_scrollLayer->moveToTop();
|
m_scrollLayer->moveToTop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,71 @@
|
||||||
|
|
||||||
using namespace geode::prelude;
|
using namespace geode::prelude;
|
||||||
|
|
||||||
|
// static void fixChildPositions(CCNode* in, CCSize const& size) {
|
||||||
|
// auto winSize = CCDirector::get()->getWinSize();
|
||||||
|
// auto offset = size / 2 - in->getContentSize() / 2;
|
||||||
|
|
||||||
|
// for (auto node : CCArrayExt<CCNode*>(in->getChildren())) {
|
||||||
|
// node->setPosition(node->getPosition() + offset);
|
||||||
|
|
||||||
|
// if (node->isIgnoreAnchorPointForPosition()) {
|
||||||
|
// node->setPosition(node->getPosition() + node->getScaledContentSize() * node->getAnchorPoint());
|
||||||
|
// node->ignoreAnchorPointForPosition(false);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// constexpr int LEFT = 0b0001;
|
||||||
|
// constexpr int RIGHT = 0b0010;
|
||||||
|
// constexpr int BOTTOM = 0b0100;
|
||||||
|
// constexpr int TOP = 0b1000;
|
||||||
|
|
||||||
|
// int p = 0b0000;
|
||||||
|
// if (node->getPositionX() <= winSize.width / 2 - size.width * 0.25) {
|
||||||
|
// p |= LEFT;
|
||||||
|
// }
|
||||||
|
// else if (node->getPositionX() >= winSize.width / 2 + size.width * 0.25) {
|
||||||
|
// p |= RIGHT;
|
||||||
|
// }
|
||||||
|
// if (node->getPositionY() <= winSize.height / 2 - size.height * 0.25) {
|
||||||
|
// p |= BOTTOM;
|
||||||
|
// }
|
||||||
|
// else if (node->getPositionY() >= winSize.height / 2 + size.height * 0.25) {
|
||||||
|
// p |= TOP;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Anchor anchor = Anchor::Center;
|
||||||
|
// switch (p) {
|
||||||
|
// case LEFT | BOTTOM: anchor = Anchor::BottomLeft; break;
|
||||||
|
// case LEFT | TOP: anchor = Anchor::TopLeft; break;
|
||||||
|
// case LEFT: anchor = Anchor::Left; break;
|
||||||
|
// case RIGHT | BOTTOM: anchor = Anchor::BottomRight; break;
|
||||||
|
// case RIGHT | TOP: anchor = Anchor::TopRight; break;
|
||||||
|
// case RIGHT: anchor = Anchor::Right; break;
|
||||||
|
// case TOP: anchor = Anchor::Top; break;
|
||||||
|
// case BOTTOM: anchor = Anchor::Bottom; break;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// auto anchorPos = AnchorLayout::getAnchoredPosition(in, anchor, ccp(0, 0));
|
||||||
|
// node->setLayoutOptions(
|
||||||
|
// AnchorLayoutOptions::create()
|
||||||
|
// ->setAnchor(anchor)
|
||||||
|
// ->setOffset(node->getPosition() - anchorPos)
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
|
||||||
|
// in->ignoreAnchorPointForPosition(false);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// void geode::enableDynamicLayoutForPopup(FLAlertLayer* alert, CCNode* bg) {
|
||||||
|
// auto winSize = CCDirector::get()->getWinSize();
|
||||||
|
|
||||||
|
// auto size = bg->getContentSize();
|
||||||
|
|
||||||
|
// alert->m_mainLayer->ignoreAnchorPointForPosition(false);
|
||||||
|
// alert->m_mainLayer->setContentSize(size);
|
||||||
|
// alert->m_mainLayer->setPosition(winSize / 2);
|
||||||
|
// alert->m_mainLayer->setLayout(AutoPopupLayout::create(alert->m_buttonMenu, bg));
|
||||||
|
// }
|
||||||
|
|
||||||
class QuickPopup : public FLAlertLayer, public FLAlertLayerProtocol {
|
class QuickPopup : public FLAlertLayer, public FLAlertLayerProtocol {
|
||||||
protected:
|
protected:
|
||||||
MiniFunction<void(FLAlertLayer*, bool)> m_selected;
|
MiniFunction<void(FLAlertLayer*, bool)> m_selected;
|
||||||
|
|
Loading…
Reference in a new issue