mirror of
https://github.com/geode-sdk/geode.git
synced 2025-03-24 03:39:56 -04:00
initial layout stuff
This commit is contained in:
parent
e6065b210f
commit
3f7a9ed8d3
12 changed files with 498 additions and 86 deletions
loader
|
@ -14,6 +14,7 @@ file(GLOB CORE_SOURCES
|
|||
src/cocos2d-ext/*.cpp
|
||||
src/core/*.cpp
|
||||
src/hooks/*.cpp
|
||||
src/ids/*.cpp
|
||||
src/internal/*.cpp
|
||||
src/internal/windows/*.cpp
|
||||
src/internal/mac/*.cpp
|
||||
|
|
|
@ -2,13 +2,17 @@
|
|||
|
||||
#include "ui/BasedButtonSprite.hpp"
|
||||
#include "ui/BasedButton.hpp"
|
||||
#include "ui/ColorPickPopup.hpp"
|
||||
#include "ui/EnterLayerEvent.hpp"
|
||||
#include "ui/IconButtonSprite.hpp"
|
||||
#include "ui/InputNode.hpp"
|
||||
#include "ui/ListView.hpp"
|
||||
#include "ui/MDPopup.hpp"
|
||||
#include "ui/MDTextArea.hpp"
|
||||
#include "ui/Notification.hpp"
|
||||
#include "ui/Popup.hpp"
|
||||
#include "ui/SceneManager.hpp"
|
||||
#include "ui/Scrollbar.hpp"
|
||||
#include "ui/ScrollLayer.hpp"
|
||||
#include "ui/SelectList.hpp"
|
||||
#include "ui/TextRenderer.hpp"
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "kazmath/kazmath.h"
|
||||
#include "script_support/CCScriptSupport.h"
|
||||
#include "CCProtocols.h"
|
||||
#include "Layout.hpp"
|
||||
|
||||
NS_CC_BEGIN
|
||||
|
||||
|
@ -875,6 +876,13 @@ public:
|
|||
* @returns The child, or nullptr if none was found
|
||||
*/
|
||||
CCNode* getChildByIDRecursive(std::string const& id);
|
||||
|
||||
void setLayout(Layout* layout, bool apply = true);
|
||||
Layout* getLayout();
|
||||
void updateLayout();
|
||||
|
||||
void setPositionHint(PositionHint hint);
|
||||
PositionHint getPositionHint();
|
||||
);
|
||||
|
||||
/// @{
|
||||
|
|
153
loader/include/Geode/cocos/cocos2dx/base_nodes/Layout.hpp
Normal file
153
loader/include/Geode/cocos/cocos2dx/base_nodes/Layout.hpp
Normal file
|
@ -0,0 +1,153 @@
|
|||
#pragma once
|
||||
|
||||
#include "ccMacros.h"
|
||||
#include "cocoa/CCAffineTransform.h"
|
||||
#include "cocoa/CCArray.h"
|
||||
#include <Geode/platform/platform.hpp>
|
||||
#include <optional>
|
||||
#include <unordered_map>
|
||||
|
||||
NS_CC_BEGIN
|
||||
|
||||
class CCNode;
|
||||
|
||||
/**
|
||||
* Layouts automatically handle the positioning of nodes. Use CCNode::setLayout
|
||||
* to apply a layout to a node, and then use CCNode::updateLayout to apply
|
||||
* the layout's positioning. Geode comes with a few default layouts like
|
||||
* RowLayout, ColumnLayout, and GridLayout, but if you need a different kind
|
||||
* of layout you can inherit from the Layout class.
|
||||
*/
|
||||
class Layout {
|
||||
public:
|
||||
/**
|
||||
* Automatically apply the layout's positioning on a set of nodes
|
||||
* @param nodes Nodes to position
|
||||
* @param availableSize Give hints to the layout about how much space is
|
||||
* available. Note that the layout may still overflow
|
||||
*/
|
||||
virtual void apply(CCArray* nodes, CCSize const& availableSize) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Determines how a node should be positioned within its parent, if that
|
||||
* parent has an automatically positioning layout
|
||||
*/
|
||||
enum class PositionHint {
|
||||
// The container can determine the best position
|
||||
// for this node
|
||||
Default,
|
||||
// The container's layout should not affect the
|
||||
// position of this node
|
||||
Absolute,
|
||||
};
|
||||
|
||||
/**
|
||||
* Specifies the alignment of something
|
||||
*/
|
||||
enum class Alignment {
|
||||
Begin,
|
||||
Center,
|
||||
End,
|
||||
};
|
||||
|
||||
/**
|
||||
* Simple layout for arranging nodes in a row (horizontal line)
|
||||
*/
|
||||
class GEODE_DLL RowLayout : public Layout {
|
||||
protected:
|
||||
Alignment m_alignment = Alignment::Center;
|
||||
std::optional<float> m_alignVertically;
|
||||
float m_gap;
|
||||
|
||||
public:
|
||||
void apply(CCArray* nodes, CCSize const& availableSize) override;
|
||||
|
||||
/**
|
||||
* Create a new RowLayout. Note that this class is not automatically
|
||||
* managed by default, so you must assign it to a CCNode or manually
|
||||
* manage the memory yourself.
|
||||
* @param gap Space between nodes
|
||||
* @param alignVertically Whether to align the nodes vertically, and if so,
|
||||
* what Y position to align them at
|
||||
* @returns Created RowLayout
|
||||
*/
|
||||
static RowLayout* create(
|
||||
float gap = 5.f,
|
||||
std::optional<float> alignVertically = std::nullopt
|
||||
);
|
||||
|
||||
RowLayout* setAlignment(Alignment align);
|
||||
RowLayout* setGap(float gap);
|
||||
RowLayout* setAlignVertically(std::optional<float> align);
|
||||
};
|
||||
|
||||
/**
|
||||
* Simple layout for arranging nodes in a column (vertical line)
|
||||
*/
|
||||
class GEODE_DLL ColumnLayout : public Layout {
|
||||
protected:
|
||||
Alignment m_alignment = Alignment::Center;
|
||||
std::optional<float> m_alignHorizontally;
|
||||
float m_gap;
|
||||
|
||||
public:
|
||||
void apply(CCArray* nodes, CCSize const& availableSize) override;
|
||||
|
||||
static ColumnLayout* create(
|
||||
float gap = 5.f,
|
||||
std::optional<float> alignHorizontally = std::nullopt
|
||||
);
|
||||
|
||||
ColumnLayout* setAlignment(Alignment align);
|
||||
ColumnLayout* setGap(float gap);
|
||||
ColumnLayout* setAlignHorizontally(std::optional<float> align);
|
||||
};
|
||||
|
||||
/**
|
||||
* Grid direction; which direction the grid should add its next row to if the
|
||||
* current row is full
|
||||
*/
|
||||
enum class GridDirection {
|
||||
// Downward
|
||||
Column,
|
||||
// Upward
|
||||
ReverseColumn,
|
||||
// Right
|
||||
Row,
|
||||
// Left
|
||||
ReverseRow,
|
||||
};
|
||||
|
||||
/**
|
||||
* Grid alignment; same as normal Alignment but also features the "Stretch"
|
||||
* option which will stretch the row out to be the same size as the others
|
||||
*/
|
||||
enum class GridAlignment {
|
||||
Begin,
|
||||
Center,
|
||||
Stretch,
|
||||
End,
|
||||
};
|
||||
|
||||
class GEODE_DLL GridLayout : public Layout {
|
||||
protected:
|
||||
GridDirection m_direction = GridDirection::Column;
|
||||
GridAlignment m_alignment = GridAlignment::Center;
|
||||
std::optional<size_t> m_rowSize;
|
||||
|
||||
public:
|
||||
void apply(CCArray* nodes, CCSize const& availableSize) override;
|
||||
|
||||
static GridLayout* create(
|
||||
std::optional<size_t> rowSize,
|
||||
GridAlignment alignment = GridAlignment::Center,
|
||||
GridDirection direction = GridDirection::Column
|
||||
);
|
||||
|
||||
GridLayout* setDirection(GridDirection direction);
|
||||
GridLayout* setAlignment(GridAlignment alignment);
|
||||
GridLayout* setRowSize(std::optional<size_t> rowSize);
|
||||
};
|
||||
|
||||
NS_CC_END
|
|
@ -173,14 +173,14 @@ typedef void (CCObject::*SEL_MenuHandler)(CCObject*);
|
|||
typedef void (CCObject::*SEL_EventHandler)(CCEvent*);
|
||||
typedef int (CCObject::*SEL_Compare)(CCObject*);
|
||||
|
||||
#define schedule_selector(_SELECTOR) (SEL_SCHEDULE)(&_SELECTOR)
|
||||
#define callfunc_selector(_SELECTOR) (SEL_CallFunc)(&_SELECTOR)
|
||||
#define callfuncN_selector(_SELECTOR) (SEL_CallFuncN)(&_SELECTOR)
|
||||
#define callfuncND_selector(_SELECTOR) (SEL_CallFuncND)(&_SELECTOR)
|
||||
#define callfuncO_selector(_SELECTOR) (SEL_CallFuncO)(&_SELECTOR)
|
||||
#define menu_selector(_SELECTOR) (SEL_MenuHandler)(&_SELECTOR)
|
||||
#define event_selector(_SELECTOR) (SEL_EventHandler)(&_SELECTOR)
|
||||
#define compare_selector(_SELECTOR) (SEL_Compare)(&_SELECTOR)
|
||||
#define schedule_selector(_SELECTOR) (cocos2d::SEL_SCHEDULE)(&_SELECTOR)
|
||||
#define callfunc_selector(_SELECTOR) (cocos2d::SEL_CallFunc)(&_SELECTOR)
|
||||
#define callfuncN_selector(_SELECTOR) (cocos2d::SEL_CallFuncN)(&_SELECTOR)
|
||||
#define callfuncND_selector(_SELECTOR) (cocos2d::SEL_CallFuncND)(&_SELECTOR)
|
||||
#define callfuncO_selector(_SELECTOR) (cocos2d::SEL_CallFuncO)(&_SELECTOR)
|
||||
#define menu_selector(_SELECTOR) (cocos2d::SEL_MenuHandler)(&_SELECTOR)
|
||||
#define event_selector(_SELECTOR) (cocos2d::SEL_EventHandler)(&_SELECTOR)
|
||||
#define compare_selector(_SELECTOR) (cocos2d::SEL_Compare)(&_SELECTOR)
|
||||
|
||||
// end of base_nodes group
|
||||
/// @}
|
||||
|
|
|
@ -19,7 +19,6 @@ if constexpr (derived##index::uuid != nullptr && (void*)base##index::uuid != (vo
|
|||
|
||||
|
||||
namespace geode::modifier {
|
||||
|
||||
template <class Derived, class Base>
|
||||
class Modify;
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
#include "Popup.hpp"
|
||||
#include "InputNode.hpp"
|
||||
|
||||
|
|
61
loader/include/Geode/ui/EnterLayerEvent.hpp
Normal file
61
loader/include/Geode/ui/EnterLayerEvent.hpp
Normal file
|
@ -0,0 +1,61 @@
|
|||
#pragma once
|
||||
|
||||
#include "../loader/Event.hpp"
|
||||
|
||||
namespace cocos2d {
|
||||
class CCNode;
|
||||
}
|
||||
|
||||
namespace geode {
|
||||
template<class T>
|
||||
concept InheritsCCNode = std::is_base_of_v<cocos2d::CCNode, T>;
|
||||
|
||||
template<InheritsCCNode T>
|
||||
class EnterLayerEvent : public Event {
|
||||
protected:
|
||||
std::string m_layerID;
|
||||
T* m_layer;
|
||||
|
||||
public:
|
||||
EnterLayerEvent(
|
||||
std::string const& layerID,
|
||||
T* layer
|
||||
) : m_layerID(layerID),
|
||||
m_layer(layer) {}
|
||||
|
||||
std::string getID() const {
|
||||
return m_layerID;
|
||||
}
|
||||
|
||||
T* getLayer() const {
|
||||
return m_layer;
|
||||
}
|
||||
};
|
||||
|
||||
template<class T, class N>
|
||||
concept InheritsEnterLayer = std::is_base_of_v<EnterLayerEvent<N>, T>;
|
||||
|
||||
template<class N, InheritsEnterLayer<N> T>
|
||||
class EnterLayerEventHandler : public EventHandler<EnterLayerEvent<N>> {
|
||||
public:
|
||||
using Consumer = void(*)(T*);
|
||||
|
||||
protected:
|
||||
Consumer m_consumer;
|
||||
std::optional<std::string> m_targetID;
|
||||
|
||||
public:
|
||||
PassThrough handle(EnterLayerEvent<N>* event) override {
|
||||
if (m_targetID == event->getID()) {
|
||||
m_consumer(static_cast<T*>(event));
|
||||
}
|
||||
return PassThrough::Propagate;
|
||||
}
|
||||
|
||||
EnterLayerEventHandler(
|
||||
std::optional<std::string> const& id,
|
||||
Consumer handler
|
||||
) : m_targetID(id),
|
||||
m_consumer(handler) {}
|
||||
};
|
||||
}
|
138
loader/src/cocos2d-ext/Layout.cpp
Normal file
138
loader/src/cocos2d-ext/Layout.cpp
Normal file
|
@ -0,0 +1,138 @@
|
|||
#include <cocos2d.h>
|
||||
#include <Geode/utils/WackyGeodeMacros.hpp>
|
||||
|
||||
using namespace cocos2d;
|
||||
|
||||
void RowLayout::apply(CCArray* nodes, CCSize const& availableSize) {
|
||||
float totalWidth = .0f;
|
||||
CCARRAY_FOREACH_B_BASE(nodes, node, CCNode*, ix) {
|
||||
totalWidth += node->getScaledContentSize().width;
|
||||
if (ix) {
|
||||
totalWidth += m_gap;
|
||||
}
|
||||
}
|
||||
|
||||
float pos;
|
||||
switch (m_alignment) {
|
||||
default:
|
||||
case Alignment::Center: pos = -totalWidth / 2; break;
|
||||
case Alignment::Begin: pos = -totalWidth; break;
|
||||
case Alignment::End: pos = 0.f; break;
|
||||
}
|
||||
CCARRAY_FOREACH_B_TYPE(nodes, node, CCNode) {
|
||||
auto sw = node->getScaledContentSize().width;
|
||||
node->setPositionX(pos + sw / 2);
|
||||
if (m_alignVertically) {
|
||||
node->setPositionY(m_alignVertically.value());
|
||||
}
|
||||
pos += sw + m_gap;
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout* RowLayout::create(
|
||||
float gap,
|
||||
std::optional<float> alignVertically
|
||||
) {
|
||||
auto ret = new RowLayout;
|
||||
ret->m_gap = gap;
|
||||
ret->m_alignVertically = alignVertically;
|
||||
return ret;
|
||||
}
|
||||
|
||||
RowLayout* RowLayout::setAlignment(Alignment align) {
|
||||
m_alignment = align;
|
||||
return this;
|
||||
}
|
||||
|
||||
RowLayout* RowLayout::setGap(float gap) {
|
||||
m_gap = gap;
|
||||
return this;
|
||||
}
|
||||
|
||||
RowLayout* RowLayout::setAlignVertically(std::optional<float> align) {
|
||||
m_alignVertically = align;
|
||||
return this;
|
||||
}
|
||||
|
||||
void ColumnLayout::apply(CCArray* nodes, CCSize const& availableSize) {
|
||||
float totalHeight = .0f;
|
||||
CCARRAY_FOREACH_B_BASE(nodes, node, CCNode*, ix) {
|
||||
totalHeight += node->getScaledContentSize().height;
|
||||
if (ix) {
|
||||
totalHeight += m_gap;
|
||||
}
|
||||
}
|
||||
|
||||
float pos;
|
||||
switch (m_alignment) {
|
||||
default:
|
||||
case Alignment::Center: pos = -totalHeight / 2; break;
|
||||
case Alignment::Begin: pos = -totalHeight; break;
|
||||
case Alignment::End: pos = 0.f; break;
|
||||
}
|
||||
CCARRAY_FOREACH_B_TYPE(nodes, node, CCNode) {
|
||||
auto sw = node->getScaledContentSize().height;
|
||||
node->setPositionY(pos + sw / 2);
|
||||
if (m_alignHorizontally) {
|
||||
node->setPositionX(m_alignHorizontally.value());
|
||||
}
|
||||
pos += sw + m_gap;
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout* ColumnLayout::create(
|
||||
float gap,
|
||||
std::optional<float> alignHorizontally
|
||||
) {
|
||||
auto ret = new ColumnLayout;
|
||||
ret->m_gap = gap;
|
||||
ret->m_alignHorizontally = alignHorizontally;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ColumnLayout* ColumnLayout::setAlignment(Alignment align) {
|
||||
m_alignment = align;
|
||||
return this;
|
||||
}
|
||||
|
||||
ColumnLayout* ColumnLayout::setGap(float gap) {
|
||||
m_gap = gap;
|
||||
return this;
|
||||
}
|
||||
|
||||
ColumnLayout* ColumnLayout::setAlignHorizontally(std::optional<float> align) {
|
||||
m_alignHorizontally = align;
|
||||
return this;
|
||||
}
|
||||
|
||||
void GridLayout::apply(CCArray* nodes, CCSize const& availableSize) {
|
||||
// todo
|
||||
}
|
||||
|
||||
GridLayout* GridLayout::create(
|
||||
std::optional<size_t> rowSize,
|
||||
GridAlignment alignment,
|
||||
GridDirection direction
|
||||
) {
|
||||
auto ret = new GridLayout;
|
||||
ret->m_rowSize = rowSize;
|
||||
ret->m_alignment = alignment;
|
||||
ret->m_direction = direction;
|
||||
return ret;
|
||||
}
|
||||
|
||||
GridLayout* GridLayout::setDirection(GridDirection direction) {
|
||||
m_direction = direction;
|
||||
return this;
|
||||
}
|
||||
|
||||
GridLayout* GridLayout::setAlignment(GridAlignment alignment) {
|
||||
m_alignment = alignment;
|
||||
return this;
|
||||
}
|
||||
|
||||
GridLayout* GridLayout::setRowSize(std::optional<size_t> rowSize) {
|
||||
m_rowSize = rowSize;
|
||||
return this;
|
||||
}
|
||||
|
|
@ -18,6 +18,8 @@ private:
|
|||
FieldContainer* m_fieldContainer;
|
||||
Ref<cocos2d::CCObject> m_userObject;
|
||||
std::string m_id = "";
|
||||
std::unique_ptr<Layout> m_layout = nullptr;
|
||||
PositionHint m_positionHint = PositionHint::Default;
|
||||
|
||||
friend class ProxyCCNode;
|
||||
friend class cocos2d::CCNode;
|
||||
|
@ -102,4 +104,37 @@ CCNode* CCNode::getChildByIDRecursive(std::string const& id) {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
void CCNode::setLayout(Layout* layout, bool apply) {
|
||||
GeodeNodeMetadata::set(this)->m_layout.reset(layout);
|
||||
if (apply) {
|
||||
this->updateLayout();
|
||||
}
|
||||
}
|
||||
|
||||
Layout* CCNode::getLayout() {
|
||||
return GeodeNodeMetadata::set(this)->m_layout.get();
|
||||
}
|
||||
|
||||
void CCNode::updateLayout() {
|
||||
if (auto layout = GeodeNodeMetadata::set(this)->m_layout.get()) {
|
||||
// nodes with absolute position should never be rearranged
|
||||
auto filtered = CCArray::createWithCapacity(m_pChildren->capacity());
|
||||
CCARRAY_FOREACH_B_TYPE(m_pChildren, child, CCNode) {
|
||||
if (child->getPositionHint() != PositionHint::Absolute) {
|
||||
filtered->addObject(child);
|
||||
}
|
||||
}
|
||||
layout->apply(filtered, m_obContentSize);
|
||||
filtered->release();
|
||||
}
|
||||
}
|
||||
|
||||
void CCNode::setPositionHint(PositionHint hint) {
|
||||
GeodeNodeMetadata::set(this)->m_positionHint = hint;
|
||||
}
|
||||
|
||||
PositionHint CCNode::getPositionHint() {
|
||||
return GeodeNodeMetadata::set(this)->m_positionHint;
|
||||
}
|
||||
|
||||
#pragma warning(pop)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include <Geode/Geode.hpp>
|
||||
#include <Geode/Bindings.hpp>
|
||||
#include <Geode/utils/WackyGeodeMacros.hpp>
|
||||
#include <Geode/ui/BasedButtonSprite.hpp>
|
||||
#include <Geode/ui/Notification.hpp>
|
||||
|
@ -139,77 +139,12 @@ class $modify(CustomMenuLayer, MenuLayer) {
|
|||
bool init() {
|
||||
if (!MenuLayer::init())
|
||||
return false;
|
||||
|
||||
|
||||
Loader::get()->updateResourcePaths();
|
||||
|
||||
auto setIDSafe = +[](CCNode* node, int index, const char* id) {
|
||||
if (auto child = getChild(node, index)) {
|
||||
child->setID(id);
|
||||
}
|
||||
};
|
||||
|
||||
// set IDs to everything
|
||||
this->setID("main-menu-layer");
|
||||
setIDSafe(this, 0, "main-menu-bg");
|
||||
getChildOfType<CCSprite>(this, 0)->setID("main-title");
|
||||
|
||||
if (PlatformToolbox::isControllerConnected()) {
|
||||
getChildOfType<CCSprite>(this, 1)->setID("play-gamepad-icon");
|
||||
getChildOfType<CCSprite>(this, 2)->setID("editor-gamepad-icon");
|
||||
getChildOfType<CCSprite>(this, 3)->setID("icon-kit-gamepad-icon");
|
||||
|
||||
getChildOfType<CCSprite>(this, 4)->setID("settings-gamepad-icon");
|
||||
getChildOfType<CCSprite>(this, 5)->setID("mouse-gamepad-icon");
|
||||
getChildOfType<CCSprite>(this, 6)->setID("click-gamepad-icon");
|
||||
|
||||
getChildOfType<CCLabelBMFont>(this, 0)->setID("mouse-gamepad-label");
|
||||
getChildOfType<CCLabelBMFont>(this, 1)->setID("click-gamepad-label");
|
||||
|
||||
getChildOfType<CCLabelBMFont>(this, 2)->setID("player-username");
|
||||
} else {
|
||||
getChildOfType<CCLabelBMFont>(this, 0)->setID("player-username");
|
||||
}
|
||||
if (auto menu = getChildOfType<CCMenu>(this, 0)) {
|
||||
menu->setID("main-menu");
|
||||
setIDSafe(menu, 0, "play-button");
|
||||
setIDSafe(menu, 1, "icon-kit-button");
|
||||
setIDSafe(menu, 2, "editor-button");
|
||||
setIDSafe(menu, 3, "profile-button");
|
||||
}
|
||||
if (auto menu = getChildOfType<CCMenu>(this, 1)) {
|
||||
menu->setID("bottom-menu");
|
||||
setIDSafe(menu, 0, "achievements-button");
|
||||
setIDSafe(menu, 1, "settings-button");
|
||||
setIDSafe(menu, 2, "stats-button");
|
||||
setIDSafe(menu, 3, "newgrounds-button");
|
||||
setIDSafe(menu, -1,"daily-chest-button");
|
||||
}
|
||||
if (auto menu = getChildOfType<CCMenu>(this, 2)) {
|
||||
menu->setID("social-media-menu");
|
||||
setIDSafe(menu, 0, "robtop-logo-button");
|
||||
setIDSafe(menu, 1, "facebook-button");
|
||||
setIDSafe(menu, 2, "twitter-button");
|
||||
setIDSafe(menu, 3, "youtube-button");
|
||||
}
|
||||
if (auto menu = getChildOfType<CCMenu>(this, 3)) {
|
||||
menu->setID("more-games-menu");
|
||||
setIDSafe(menu, 0, "more-games-button");
|
||||
setIDSafe(menu, 1, "close-button");
|
||||
}
|
||||
|
||||
auto winSize = CCDirector::sharedDirector()->getWinSize();
|
||||
|
||||
// add geode button
|
||||
auto bottomMenu = static_cast<CCMenu*>(this->getChildByID("bottom-menu"));
|
||||
|
||||
// keep chest in the same position
|
||||
auto chest = bottomMenu->getChildByID("daily-chest-button");
|
||||
if (chest) {
|
||||
chest->retain();
|
||||
chest->removeFromParent();
|
||||
}
|
||||
|
||||
auto y = getChild(bottomMenu, 0)->getPositionY();
|
||||
|
||||
g_geodeButton = SafeCreate<CCSprite>()
|
||||
.with(CircleButtonSprite::createWithSpriteFrameName(
|
||||
|
@ -221,21 +156,16 @@ class $modify(CustomMenuLayer, MenuLayer) {
|
|||
.orMake<ButtonSprite>("!!");
|
||||
|
||||
addUpdateIcon();
|
||||
|
||||
auto bottomMenu = static_cast<CCMenu*>(this->getChildByID("bottom-menu"));
|
||||
|
||||
auto btn = CCMenuItemSpriteExtra::create(
|
||||
g_geodeButton.data(), this, menu_selector(CustomMenuLayer::onGeode)
|
||||
);
|
||||
btn->setID("geode-button");
|
||||
bottomMenu->addChild(btn);
|
||||
|
||||
bottomMenu->alignItemsHorizontallyWithPadding(3.f);
|
||||
|
||||
CCARRAY_FOREACH_B_TYPE(bottomMenu->getChildren(), node, CCNode) {
|
||||
node->setPositionY(y);
|
||||
}
|
||||
if (chest) {
|
||||
bottomMenu->addChild(chest);
|
||||
chest->release();
|
||||
}
|
||||
bottomMenu->updateLayout();
|
||||
|
||||
if (auto node = this->getChildByID("settings-gamepad-icon")) {
|
||||
node->setPositionX(bottomMenu->getChildByID(
|
||||
|
@ -286,7 +216,7 @@ class $modify(CustomMenuLayer, MenuLayer) {
|
|||
|
||||
Index::get()->updateIndex(updateIndexProgress);
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
81
loader/src/ids/MenuLayer.cpp
Normal file
81
loader/src/ids/MenuLayer.cpp
Normal file
|
@ -0,0 +1,81 @@
|
|||
#include <Geode/Modify.hpp>
|
||||
#include <Geode/Bindings.hpp>
|
||||
#include <Geode/utils/cocos.hpp>
|
||||
#include <Geode/ui/EnterLayerEvent.hpp>
|
||||
|
||||
USE_GEODE_NAMESPACE();
|
||||
|
||||
class $modify(MenuLayer) {
|
||||
bool init() {
|
||||
auto setIDSafe = +[](CCNode* node, int index, const char* id) -> CCNode* {
|
||||
if (auto child = getChild(node, index)) {
|
||||
child->setID(id);
|
||||
return child;
|
||||
}
|
||||
return nullptr;
|
||||
};
|
||||
|
||||
// set IDs to everything
|
||||
this->setID("main-menu-layer");
|
||||
setIDSafe(this, 0, "main-menu-bg");
|
||||
getChildOfType<CCSprite>(this, 0)->setID("main-title");
|
||||
|
||||
if (PlatformToolbox::isControllerConnected()) {
|
||||
getChildOfType<CCSprite>(this, 1)->setID("play-gamepad-icon");
|
||||
getChildOfType<CCSprite>(this, 2)->setID("editor-gamepad-icon");
|
||||
getChildOfType<CCSprite>(this, 3)->setID("icon-kit-gamepad-icon");
|
||||
|
||||
getChildOfType<CCSprite>(this, 4)->setID("settings-gamepad-icon");
|
||||
getChildOfType<CCSprite>(this, 5)->setID("mouse-gamepad-icon");
|
||||
getChildOfType<CCSprite>(this, 6)->setID("click-gamepad-icon");
|
||||
|
||||
getChildOfType<CCLabelBMFont>(this, 0)->setID("mouse-gamepad-label");
|
||||
getChildOfType<CCLabelBMFont>(this, 1)->setID("click-gamepad-label");
|
||||
|
||||
getChildOfType<CCLabelBMFont>(this, 2)->setID("player-username");
|
||||
} else {
|
||||
getChildOfType<CCLabelBMFont>(this, 0)->setID("player-username");
|
||||
}
|
||||
if (auto menu = getChildOfType<CCMenu>(this, 0)) {
|
||||
menu->setID("main-menu");
|
||||
setIDSafe(menu, 0, "play-button");
|
||||
auto iconKit = setIDSafe(menu, 1, "icon-kit-button");
|
||||
setIDSafe(menu, 2, "editor-button");
|
||||
|
||||
if (auto pfp = setIDSafe(menu, 3, "profile-button")) {
|
||||
pfp->setPositionHint(PositionHint::Absolute);
|
||||
}
|
||||
|
||||
menu->setLayout(RowLayout::create(5.f, 0.f));
|
||||
}
|
||||
if (auto menu = getChildOfType<CCMenu>(this, 1)) {
|
||||
menu->setID("bottom-menu");
|
||||
auto ach = setIDSafe(menu, 0, "achievements-button");
|
||||
setIDSafe(menu, 1, "settings-button");
|
||||
setIDSafe(menu, 2, "stats-button");
|
||||
setIDSafe(menu, 3, "newgrounds-button");
|
||||
|
||||
if (auto dailyChest = setIDSafe(menu, -1, "daily-chest-button")) {
|
||||
dailyChest->setPositionHint(PositionHint::Absolute);
|
||||
}
|
||||
|
||||
menu->setLayout(RowLayout::create(5.f, ach->getPositionY()));
|
||||
}
|
||||
if (auto menu = getChildOfType<CCMenu>(this, 2)) {
|
||||
menu->setID("social-media-menu");
|
||||
setIDSafe(menu, 0, "robtop-logo-button");
|
||||
setIDSafe(menu, 1, "facebook-button");
|
||||
setIDSafe(menu, 2, "twitter-button");
|
||||
setIDSafe(menu, 3, "youtube-button");
|
||||
}
|
||||
if (auto menu = getChildOfType<CCMenu>(this, 3)) {
|
||||
menu->setID("more-games-menu");
|
||||
setIDSafe(menu, 0, "more-games-button");
|
||||
setIDSafe(menu, 1, "close-button");
|
||||
}
|
||||
|
||||
EnterLayerEvent("MenuLayer", this).post();
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
Loading…
Add table
Reference in a new issue