finished design for AnchorLayout

This commit is contained in:
HJfod 2024-01-31 23:11:43 +02:00
parent 7654f6e7cd
commit aa949aed39
11 changed files with 261 additions and 129 deletions

View file

@ -995,14 +995,11 @@ public:
*/
GEODE_DLL LayoutOptions* getLayoutOptions();
/**
* Set the position of this node relative to its parent. **This requires
* the parent node to have AnchorLayout set as its layout** - this function
* will set it if the parent has no layout enabled, but if the parent has
* something else, this function does nothing.
* @param anchor The position of this node relative to its parent
* @param offset Offset from the anchored position
* Adds a child at an anchored position
* Overrides the current layout to AnchorLayout!
* @note Geode addition
*/
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

View file

@ -410,6 +410,23 @@ public:
void apply(CCNode* on) 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)

View file

@ -13,15 +13,19 @@ namespace geode {
cocos2d::extension::CCScale9Sprite* m_bgSprite;
cocos2d::CCLabelBMFont* m_title = nullptr;
CCMenuItemSpriteExtra* m_closeBtn;
bool m_dynamic;
~Popup() override {
cocos2d::CCTouchDispatcher::get()->unregisterForcePrio(this);
}
bool init(
float width, float height, InitArgs... args, char const* bg = "GJ_square01.png",
cocos2d::CCRect bgRect = { 0, 0, 80, 80 }
private:
bool initBase(
float width, float height, InitArgs... args, char const* bg,
cocos2d::CCRect bgRect, bool dynamic
) {
m_dynamic = dynamic;
auto winSize = cocos2d::CCDirector::sharedDirector()->getWinSize();
m_size = cocos2d::CCSize { width, height };
@ -38,6 +42,17 @@ namespace geode {
m_buttonMenu->setZOrder(100);
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);
auto closeSpr = cocos2d::CCSprite::createWithSpriteFrameName("GJ_closeBtn_001.png");
@ -46,8 +61,13 @@ namespace geode {
m_closeBtn = CCMenuItemSpriteExtra::create(
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);
}
if (!setup(std::forward<InitArgs>(args)...)) {
return false;
@ -63,6 +83,22 @@ namespace geode {
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;
void keyDown(cocos2d::enumKeyCodes key) {
@ -84,11 +120,17 @@ namespace geode {
) {
if (m_title) {
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->setAnchoredPosition(cocos2d::Anchor::Top, ccp(0, -offset));
m_mainLayer->addChild(m_title, 2);
m_title->setZOrder(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);
}

View file

@ -38,7 +38,7 @@ AnchorLayout* AnchorLayout::create() {
void AnchorLayout::apply(CCNode* on) {
on->ignoreAnchorPointForPosition(false);
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 size = on->getContentSize();
switch (opts->getAnchor()) {
@ -60,6 +60,23 @@ void AnchorLayout::apply(CCNode* on) {
}
CCSize AnchorLayout::getSizeHint(CCNode* on) const {
// AnchorLayout doesn't resize its target in any way
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;
}

View 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();
}

View file

@ -237,17 +237,16 @@ size_t CCNode::getEventListenerCount() {
GeodeNodeMetadata::set(this)->m_eventListeners.size();
}
void CCNode::setAnchoredPosition(Anchor anchor, CCPoint const& offset) {
auto parent = this->getParent();
// If this node's parent doesn't have any layout, then set it as AnchorLayout
if (parent && parent->getLayout() == nullptr) {
parent->setLayout(AnchorLayout::create());
void CCNode::addChildAtPosition(CCNode* child, Anchor anchor, CCPoint const& offset) {
auto layout = this->getLayout();
if (!layout) {
this->setLayout(AnchorLayout::create());
}
// Otherwise require that it already has AnchorLayout (or AnchorLayout-derived class)
else if (parent && !typeinfo_cast<AnchorLayout*>(parent->getLayout())) {
return;
}
this->setLayoutOptions(AnchorLayoutOptions::create()->setAnchor(anchor)->setOffset(offset));
// Setting the layout options always (even if the parent isn't AnchorLayout)
// so if it set as AnchorLayout later it will auto-update
child->setPosition(AnchorLayout::getAnchoredPosition(this, anchor, offset));
child->setLayoutOptions(AnchorLayoutOptions::create()->setAnchor(anchor)->setOffset(offset));
this->addChild(child);
}
#pragma warning(pop)

View file

@ -37,16 +37,15 @@ bool ModInfoPopup::setup(ModMetadata const& metadata, ModListLayer* list) {
constexpr float logoOffset = 10.f;
auto topNode = CCNode::create();
topNode->setContentSize({350.f, 80.f});
topNode->setAnchorPoint({ .5f, .5f });
topNode->setContentSize({ 350.f, 80.f });
topNode->setLayout(
RowLayout::create()
->setAxisAlignment(AxisAlignment::Center)
->setAutoScale(false)
->setCrossAxisOverflow(true)
);
m_mainLayer->addChild(topNode);
topNode->setAnchorPoint({.5f, .5f});
topNode->setPosition(winSize.width / 2, winSize.height / 2 + 115.f);
m_mainLayer->addChildAtPosition(topNode, Anchor::Top, ccp(0, -30));
auto logoSpr = this->createLogo({logoSize, logoSize});
topNode->addChild(logoSpr);
@ -88,18 +87,13 @@ bool ModInfoPopup::setup(ModMetadata const& metadata, ModListLayer* list) {
(metadata.getDetails() ? metadata.getDetails().value() : "### No description provided."),
{ 350.f, 137.5f }
);
m_detailsArea->setPosition(
winSize.width / 2 - m_detailsArea->getScaledContentSize().width / 2,
winSize.height / 2 - m_detailsArea->getScaledContentSize().height / 2 - 20.f
);
m_mainLayer->addChild(m_detailsArea);
m_mainLayer->addChildAtPosition(m_detailsArea, Anchor::Center, ccp(0, -20));
m_scrollbar = Scrollbar::create(m_detailsArea->getScrollLayer());
m_scrollbar->setPosition(
winSize.width / 2 + m_detailsArea->getScaledContentSize().width / 2 + 20.f,
winSize.height / 2 - 20.f
m_mainLayer->addChildAtPosition(
m_scrollbar, Anchor::Center,
ccp(m_detailsArea->getScaledContentSize().width / 2 + 20.f, -20)
);
m_mainLayer->addChild(m_scrollbar);
// changelog
if (metadata.getChangelog()) {
@ -127,10 +121,10 @@ bool ModInfoPopup::setup(ModMetadata const& metadata, ModListLayer* list) {
changelogBtnOnSpr->setScale(.65f);
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->addChild(changelogBtn);
m_buttonMenu->addChildAtPosition(changelogBtn, Anchor::Left, ccp(21.5f, 0));
}
// mod metadata
@ -138,8 +132,7 @@ bool ModInfoPopup::setup(ModMetadata const& metadata, ModListLayer* list) {
infoSpr->setScale(.85f);
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->addChild(m_infoBtn);
m_buttonMenu->addChildAtPosition(m_infoBtn, Anchor::TopRight, ccp(-25, -25));
// repo button
if (metadata.getRepository()) {
@ -148,8 +141,7 @@ bool ModInfoPopup::setup(ModMetadata const& metadata, ModListLayer* list) {
this,
menu_selector(ModInfoPopup::onRepository)
);
repoBtn->setPosition(LAYER_SIZE.width / 2 - 25.f, -LAYER_SIZE.height / 2 + 25.f);
m_buttonMenu->addChild(repoBtn);
m_buttonMenu->addChildAtPosition(repoBtn, Anchor::BottomRight, ccp(-25, 25));
}
// support button
@ -159,8 +151,7 @@ bool ModInfoPopup::setup(ModMetadata const& metadata, ModListLayer* list) {
this,
menu_selector(ModInfoPopup::onSupport)
);
supportBtn->setPosition(LAYER_SIZE.width / 2 - 60.f, -LAYER_SIZE.height / 2 + 25.f);
m_buttonMenu->addChild(supportBtn);
m_buttonMenu->addChildAtPosition(supportBtn, Anchor::BottomRight, ccp(-60, 25));
}
return true;
@ -204,40 +195,12 @@ void ModInfoPopup::onInfo(CCObject*) {
}
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);
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(
m_detailsArea->setString((
toggle->isToggled() ?
m_detailsArea->getScrollLayer() :
m_changelogArea->getScrollLayer()
);
this->getMetadata().getDetails().value() :
this->getMetadata().getChangelog().value()
).c_str());
}
void ModInfoPopup::setInstallStatus(std::optional<UpdateProgress> const& progress) {
@ -349,14 +312,15 @@ LocalModInfoPopup::LocalModInfoPopup()
ModInstallFilter("")
) {}
bool LocalModInfoPopup::init(Mod* mod, ModListLayer* list) {
m_item = Index::get()->getMajorItem(mod->getMetadata().getID());
if (m_item)
if (m_item) {
m_installListener.setFilter(m_item->getMetadata().getID());
}
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();
@ -364,10 +328,10 @@ bool LocalModInfoPopup::init(Mod* mod, ModListLayer* list) {
auto settingsSpr = CCSprite::createWithSpriteFrameName("GJ_optionsBtn_001.png");
settingsSpr->setScale(.65f);
auto settingsBtn =
CCMenuItemSpriteExtra::create(settingsSpr, this, menu_selector(LocalModInfoPopup::onSettings));
settingsBtn->setPosition(-LAYER_SIZE.width / 2 + 25.f, -LAYER_SIZE.height / 2 + 25.f);
m_buttonMenu->addChild(settingsBtn);
auto settingsBtn = CCMenuItemSpriteExtra::create(
settingsSpr, this, menu_selector(LocalModInfoPopup::onSettings)
);
m_buttonMenu->addChildAtPosition(settingsBtn, Anchor::BottomLeft, ccp(25, 25));
// Check if a config directory for the mod exists
if (ghc::filesystem::exists(mod->getConfigDir(false))) {
@ -379,8 +343,7 @@ bool LocalModInfoPopup::init(Mod* mod, ModListLayer* list) {
auto configBtn = CCMenuItemSpriteExtra::create(
configSpr, this, menu_selector(LocalModInfoPopup::onOpenConfigDir)
);
configBtn->setPosition(-LAYER_SIZE.width / 2 + 65.f, -LAYER_SIZE.height / 2 + 25.f);
m_buttonMenu->addChild(configBtn);
m_buttonMenu->addChildAtPosition(configBtn, Anchor::BottomLeft, ccp(65, 25));
}
if (!mod->hasSettings()) {
@ -397,9 +360,8 @@ bool LocalModInfoPopup::init(Mod* mod, ModListLayer* list) {
auto enableBtn = CCMenuItemToggler::create(
disableBtnSpr, enableBtnSpr, this, menu_selector(LocalModInfoPopup::onEnableMod)
);
enableBtn->setPosition(-155.f, 75.f);
enableBtn->toggle(!mod->shouldLoad());
m_buttonMenu->addChild(enableBtn);
m_buttonMenu->addChildAtPosition(enableBtn, Anchor::Center, ccp(-155, 75));
if (mod->isInternal()) {
enableBtn->setTarget(this, menu_selector(LocalModInfoPopup::onDisablingNotSupported));
@ -420,8 +382,7 @@ bool LocalModInfoPopup::init(Mod* mod, ModListLayer* list) {
auto uninstallBtn = CCMenuItemSpriteExtra::create(
uninstallBtnSpr, this, menu_selector(LocalModInfoPopup::onUninstall)
);
uninstallBtn->setPosition(-85.f, 75.f);
m_buttonMenu->addChild(uninstallBtn);
m_buttonMenu->addChildAtPosition(uninstallBtn, Anchor::Center, ccp(-85, 75));
// todo: show update button on loader that invokes the installer
if (m_item && Index::get()->isUpdateAvailable(m_item)) {
@ -434,20 +395,21 @@ bool LocalModInfoPopup::init(Mod* mod, ModListLayer* list) {
m_installBtnSpr->setScale(.6f);
m_installBtn = CCMenuItemSpriteExtra::create(m_installBtnSpr, this, menu_selector(LocalModInfoPopup::onUpdate));
m_installBtn->setPosition(-8.0f, 75.f);
m_buttonMenu->addChild(m_installBtn);
m_buttonMenu->addChildAtPosition(m_installBtn, Anchor::Center, ccp(-8, 75));
m_installStatus = DownloadStatusNode::create();
m_installStatus->setPosition(winSize.width / 2 + 105.f, winSize.height / 2 + 75.f);
m_installStatus->setVisible(false);
m_mainLayer->addChild(m_installStatus);
m_mainLayer->addChildAtPosition(m_installStatus, Anchor::Center, ccp(105, 75));
auto minorIndexItem = Index::get()->getItem(
mod->getMetadata().getID(),
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()) {
// has major update
@ -458,8 +420,7 @@ bool LocalModInfoPopup::init(Mod* mod, ModListLayer* list) {
m_latestVersionLabel->setScale(.35f);
m_latestVersionLabel->setAnchorPoint({.0f, .5f});
m_latestVersionLabel->setColor({94, 219, 255});
m_latestVersionLabel->setPosition(winSize.width / 2 + 35.f, winSize.height / 2 + 75.f);
m_mainLayer->addChild(m_latestVersionLabel);
availableContainer->addChild(m_latestVersionLabel);
}
if (minorIndexItem->getMetadata().getVersion() > mod->getMetadata().getVersion()) {
@ -471,20 +432,11 @@ bool LocalModInfoPopup::init(Mod* mod, ModListLayer* list) {
m_minorVersionLabel->setScale(.35f);
m_minorVersionLabel->setAnchorPoint({.0f, .5f});
m_minorVersionLabel->setColor({94, 219, 255});
if (m_latestVersionLabel) {
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->addChild(m_minorVersionLabel);
}
availableContainer->updateLayout();
m_mainLayer->addChildAtPosition(availableContainer, Anchor::Center, ccp(35, 75));
}
}
if (mod == Mod::get()) {
@ -494,11 +446,10 @@ bool LocalModInfoPopup::init(Mod* mod, ModListLayer* list) {
"chatFont.fnt"
);
label->setAlignment(kCCTextAlignmentRight);
label->setAnchorPoint(ccp(1, 0));
label->setScale(0.6f);
label->setPosition(winSize.width - 3.f, 3.f);
label->setAnchorPoint({ .0f, .5f });
label->setScale(.5f);
label->setOpacity(89);
m_mainLayer->addChild(label);
m_mainLayer->addChildAtPosition(label, Anchor::BottomRight, ccp(5, 0));
}
// issue report button
@ -511,8 +462,7 @@ bool LocalModInfoPopup::init(Mod* mod, ModListLayer* list) {
auto issuesBtn = CCMenuItemSpriteExtra::create(
issuesBtnSpr, this, menu_selector(LocalModInfoPopup::onIssues)
);
issuesBtn->setPosition(0.f, -LAYER_SIZE.height / 2 + 25.f);
m_buttonMenu->addChild(issuesBtn);
m_buttonMenu->addChildAtPosition(issuesBtn, Anchor::Bottom, ccp(0, 25));
}
return true;
@ -685,7 +635,7 @@ bool IndexItemInfoPopup::init(IndexItemHandle item, ModListLayer* list) {
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
// if (item->isInstalled()) return true;
@ -701,13 +651,11 @@ bool IndexItemInfoPopup::init(IndexItemHandle item, ModListLayer* list) {
m_installBtn = CCMenuItemSpriteExtra::create(
m_installBtnSpr, this, menu_selector(IndexItemInfoPopup::onInstall)
);
m_installBtn->setPosition(-143.0f, 75.f);
m_buttonMenu->addChild(m_installBtn);
m_buttonMenu->addChildAtPosition(m_installBtn, Anchor::Center, ccp(-143, 75));
m_installStatus = DownloadStatusNode::create();
m_installStatus->setPosition(winSize.width / 2 - 25.f, winSize.height / 2 + 75.f);
m_installStatus->setVisible(false);
m_mainLayer->addChild(m_installStatus);
m_mainLayer->addChildAtPosition(m_installStatus, Anchor::Center, ccp(-25, 75));
return true;
}

View file

@ -36,7 +36,6 @@ protected:
CCLabelBMFont* m_latestVersionLabel = nullptr;
CCLabelBMFont* m_minorVersionLabel = nullptr;
MDTextArea* m_detailsArea;
MDTextArea* m_changelogArea = nullptr;
Scrollbar* m_scrollbar;
IndexItemHandle m_item;

View file

@ -19,7 +19,7 @@ bool MDPopup::setup(
m_size.height - 120.f,
};
auto content = MDTextArea::create(info, contentSize);
content->setPosition(winSize / 2 - contentSize / 2);
content->setPosition(winSize / 2);
m_mainLayer->addChild(content);
auto btnSpr = ButtonSprite::create(btn1Text);

View file

@ -108,6 +108,9 @@ Result<ccColor3B> colorForIdentifier(std::string const& tag) {
bool MDTextArea::init(std::string const& str, CCSize const& size) {
if (!CCLayer::init()) return false;
this->ignoreAnchorPointForPosition(false);
this->setAnchorPoint({ .5f, .5f });
m_text = str;
m_size = size - CCSize { 15.f, 0.f };
this->setContentSize(m_size);
@ -726,7 +729,6 @@ void MDTextArea::updateLabel() {
m_content->setPositionY(-2.5f);
}
m_scrollLayer->moveToTop();
}

View file

@ -2,6 +2,71 @@
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 {
protected:
MiniFunction<void(FLAlertLayer*, bool)> m_selected;