initial ideas, going to sleep for today

This commit is contained in:
HJfod 2024-01-30 00:08:53 +02:00
parent ea81897d5b
commit 7654f6e7cd
8 changed files with 1198 additions and 1056 deletions

View file

@ -994,6 +994,15 @@ public:
* @note Geode addition
*/
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
*/
GEODE_DLL void setAnchoredPosition(Anchor anchor, CCPoint const& offset = CCPointZero);
/**
* Swap two children

View file

@ -371,6 +371,47 @@ public:
static ColumnLayout* create();
};
/**
* The relative position of a node to its parent in an AnchorLayout
*/
enum class Anchor {
Center,
TopLeft,
Top,
TopRight,
Right,
BottomRight,
Bottom,
BottomLeft,
Left,
};
/**
* Options for customizing AnchorLayout
*/
class GEODE_DLL AnchorLayoutOptions : public LayoutOptions {
protected:
Anchor m_anchor = Anchor::Center;
CCPoint m_offset = CCPointZero;
public:
static AnchorLayoutOptions* create();
Anchor getAnchor() const;
CCPoint getOffset() const;
AnchorLayoutOptions* setAnchor(Anchor anchor);
AnchorLayoutOptions* setOffset(CCPoint const& offset);
};
class GEODE_DLL AnchorLayout : public Layout {
public:
static AnchorLayout* create();
void apply(CCNode* on) override;
CCSize getSizeHint(CCNode* on) const override;
};
#pragma warning(pop)
NS_CC_END

View file

@ -46,7 +46,7 @@ namespace geode {
m_closeBtn = CCMenuItemSpriteExtra::create(
closeSpr, this, (cocos2d::SEL_MenuHandler)(&Popup::onClose)
);
m_closeBtn->setPosition(-m_size.width / 2 + 3.f, m_size.height / 2 - 3.f);
m_closeBtn->setAnchoredPosition(cocos2d::Anchor::TopLeft);
m_buttonMenu->addChild(m_closeBtn);
if (!setup(std::forward<InitArgs>(args)...)) {
@ -87,9 +87,7 @@ namespace geode {
} else {
auto winSize = cocos2d::CCDirector::sharedDirector()->getWinSize();
m_title = cocos2d::CCLabelBMFont::create(title.c_str(), font);
m_title->setPosition(
winSize.width / 2, winSize.height / 2 + m_size.height / 2 - offset
);
m_title->setAnchoredPosition(cocos2d::Anchor::Top, ccp(0, -offset));
m_mainLayer->addChild(m_title, 2);
}
m_title->limitLabelWidth(m_size.width - 20.f, scale, .1f);

View file

@ -0,0 +1,65 @@
#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;
AnchorLayoutOptions* AnchorLayoutOptions::create() {
return new AnchorLayoutOptions();
}
Anchor AnchorLayoutOptions::getAnchor() const {
return m_anchor;
}
CCPoint AnchorLayoutOptions::getOffset() const {
return m_offset;
}
AnchorLayoutOptions* AnchorLayoutOptions::setAnchor(Anchor anchor) {
m_anchor = anchor;
return this;
}
AnchorLayoutOptions* AnchorLayoutOptions::setOffset(CCPoint const& offset) {
m_offset = offset;
return this;
}
AnchorLayout* AnchorLayout::create() {
auto ret = new AnchorLayout();
ret->autorelease();
return ret;
}
void AnchorLayout::apply(CCNode* on) {
on->ignoreAnchorPointForPosition(false);
for (auto node : CCArrayExt<CCNode*>(this->getNodesToPosition(on))) {
if (auto opts = typeinfo_cast<AnchorLayoutOptions*>(node)) {
auto pos = opts->getOffset();
auto size = on->getContentSize();
switch (opts->getAnchor()) {
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;
}
node->ignoreAnchorPointForPosition(false);
node->setPosition(pos);
}
}
}
CCSize AnchorLayout::getSizeHint(CCNode* on) const {
// AnchorLayout doesn't resize its target in any way
return on->getContentSize();
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,66 @@
#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;
bool SpacerNode::init(size_t grow) {
if (!CCNode::init())
return false;
m_grow = grow;
return true;
}
SpacerNode* SpacerNode::create(size_t grow) {
auto ret = new SpacerNode;
if (ret && ret->init(grow)) {
ret->autorelease();
return ret;
}
CC_SAFE_DELETE(ret);
return nullptr;
}
void SpacerNode::setGrow(size_t grow) {
m_grow = grow;
}
size_t SpacerNode::getGrow() const {
return m_grow;
}
bool SpacerNodeChild::init(CCNode* child, size_t grow) {
if (!SpacerNode::init(grow))
return false;
if (child) {
this->addChild(child);
m_child = child;
}
return true;
}
SpacerNodeChild* SpacerNodeChild::create(CCNode* child, size_t grow) {
auto ret = new SpacerNodeChild;
if (ret && ret->init(child, grow)) {
ret->autorelease();
return ret;
}
CC_SAFE_DELETE(ret);
return nullptr;
}
void SpacerNodeChild::setContentSize(CCSize const& size) {
CCNode::setContentSize(size);
if (m_child) {
m_child->setPosition(CCPointZero);
m_child->setContentSize(size);
m_child->setAnchorPoint(CCPointZero);
}
}

View file

@ -237,4 +237,17 @@ 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());
}
// 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));
}
#pragma warning(pop)