diff --git a/loader/include/Geode/cocos/base_nodes/CCNode.h b/loader/include/Geode/cocos/base_nodes/CCNode.h index 212e9f84..ce22271e 100644 --- a/loader/include/Geode/cocos/base_nodes/CCNode.h +++ b/loader/include/Geode/cocos/base_nodes/CCNode.h @@ -995,11 +995,17 @@ public: */ GEODE_DLL LayoutOptions* getLayoutOptions(); /** - * Adds a child at an anchored position - * Overrides the current layout to AnchorLayout! + * Adds a child at an anchored position with an offset. The node is placed + * in its parent where the anchor specifies, and then the offset is used to + * relatively adjust the node's position + * @param child The child to add + * @param anchor Where the place the child relative to this node + * @param offset Where to place the child relative to the anchor + * @param useAnchorLayout If true, sets this node's layout to `AnchorLayout` + * if no other layout is already specified * @note Geode addition */ - GEODE_DLL void addChildAtPosition(CCNode* child, Anchor anchor, CCPoint const& offset = CCPointZero); + GEODE_DLL void addChildAtPosition(CCNode* child, Anchor anchor, CCPoint const& offset = CCPointZero, bool useAnchorLayout = true); /** * Swap two children diff --git a/loader/include/Geode/cocos/base_nodes/Layout.hpp b/loader/include/Geode/cocos/base_nodes/Layout.hpp index 19846993..5a14dc1f 100644 --- a/loader/include/Geode/cocos/base_nodes/Layout.hpp +++ b/loader/include/Geode/cocos/base_nodes/Layout.hpp @@ -387,7 +387,7 @@ enum class Anchor { }; /** - * Options for customizing AnchorLayout + * Options for customizing a node's position in an AnchorLayout */ class GEODE_DLL AnchorLayoutOptions : public LayoutOptions { protected: @@ -404,6 +404,12 @@ public: AnchorLayoutOptions* setOffset(CCPoint const& offset); }; +/** + * A layout for positioning nodes at specific positions relative to their + * parent's content size. See `Anchor` for available anchoring options. Useful + * for example for popups, where a popup using `AnchorLayout` can be + * automatically resized without needing to manually shuffle nodes around + */ class GEODE_DLL AnchorLayout : public Layout { public: static AnchorLayout* create(); @@ -411,9 +417,22 @@ public: void apply(CCNode* on) override; CCSize getSizeHint(CCNode* on) const override; + /** + * Get a position according to anchoring rules, with the same algorithm as + * `AnchorLayout` uses to position its nodes + * @param in The node whose content size to use as a reference + * @param anchor The anchor position + * @param offset Offset from the anchor + * @returns A position in `in` for the anchored and offsetted location + */ static CCPoint getAnchoredPosition(CCNode* in, Anchor anchor, CCPoint const& offset); }; +/** + * A layout for automatically copying the content size of a node to other nodes. + * Basically main use case is for FLAlertLayers (setting the size of the + * background and `m_buttonMenu` based on `m_mainLayer`) + */ class AutoSizeLayout : public cocos2d::AnchorLayout { protected: cocos2d::CCArray* m_targets; @@ -422,7 +441,14 @@ public: static AutoSizeLayout* create(); virtual ~AutoSizeLayout(); + /** + * Add a target to be automatically resized. Any targets' layouts will + * also be updated when this layout is updated + */ AutoSizeLayout* add(cocos2d::CCNode* target); + /** + * Remove a target from being automatically resized + */ AutoSizeLayout* remove(cocos2d::CCNode* target); void apply(cocos2d::CCNode* in) override; diff --git a/loader/include/Geode/ui/Popup.hpp b/loader/include/Geode/ui/Popup.hpp index 7aee8e65..b512e05e 100644 --- a/loader/include/Geode/ui/Popup.hpp +++ b/loader/include/Geode/ui/Popup.hpp @@ -22,7 +22,7 @@ namespace geode { void registerWithTouchDispatcher() override { cocos2d::CCTouchDispatcher::get()->addTargetedDelegate(this, -500, true); } - + private: bool initBase( float width, float height, InitArgs... args, char const* bg, @@ -94,6 +94,11 @@ namespace geode { return this->initBase(width, height, std::forward(args)..., bg, bgRect, false); } + /** + * Init with AnchorLayout and the content size of `m_buttonMenu` and + * `m_bgSprite` being tied to the size of `m_mainLayer` (rather than + * being the size of the window) + */ bool initDynamic( float width, float height, InitArgs... args, char const* bg = "GJ_square01.png", cocos2d::CCRect bgRect = { 0, 0, 80, 80 } diff --git a/loader/src/hooks/GeodeNodeMetadata.cpp b/loader/src/hooks/GeodeNodeMetadata.cpp index dadd3f30..9ff19e5b 100644 --- a/loader/src/hooks/GeodeNodeMetadata.cpp +++ b/loader/src/hooks/GeodeNodeMetadata.cpp @@ -237,15 +237,15 @@ size_t CCNode::getEventListenerCount() { GeodeNodeMetadata::set(this)->m_eventListeners.size(); } -void CCNode::addChildAtPosition(CCNode* child, Anchor anchor, CCPoint const& offset) { +void CCNode::addChildAtPosition(CCNode* child, Anchor anchor, CCPoint const& offset, bool useAnchorLayout) { auto layout = this->getLayout(); - if (!layout) { + if (!layout && useAnchorLayout) { this->setLayout(AnchorLayout::create()); } - // 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)); + if (useAnchorLayout) { + child->setLayoutOptions(AnchorLayoutOptions::create()->setAnchor(anchor)->setOffset(offset)); + } this->addChild(child); }