mirror of
https://github.com/geode-sdk/geode.git
synced 2025-03-25 04:11:42 -04:00
View buttons!
This commit is contained in:
parent
1f6335ce17
commit
e452f482a8
19 changed files with 168 additions and 29 deletions
loader
include/Geode
resources
blanks
baseCircle_BigAlt_DarkPurple.pngbaseCircle_Big_DarkPurple.pngbaseCircle_Big_Green.pngbaseCircle_Large_DarkPurple.pngbaseCircle_MediumAlt_DarkPurple.pngbaseCircle_Medium_DarkPurple.pngbaseCircle_SmallAlt_DarkPurple.pngbaseCircle_Small_DarkPurple.pngbaseCircle_Tiny_DarkPurple.png
images
reload.pngsrc
42
loader/include/Geode/cocos/base_nodes/CCNode.h
vendored
42
loader/include/Geode/cocos/base_nodes/CCNode.h
vendored
|
@ -1013,6 +1013,48 @@ public:
|
|||
* @note Geode addition
|
||||
*/
|
||||
GEODE_DLL void addChildAtPosition(CCNode* child, Anchor anchor, CCPoint const& offset = CCPointZero, bool useAnchorLayout = true);
|
||||
/**
|
||||
* 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 nodeAnchor The child's anchor position
|
||||
* @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& nodeAnchor,
|
||||
CCPoint const& offset,
|
||||
bool useAnchorLayout = true
|
||||
);
|
||||
/**
|
||||
* Updates the anchored position of a child. Requires the child to already
|
||||
* have a parent; if the child already has AnchorLayoutOptions set, those
|
||||
* are updated, otherwise nothing is done
|
||||
* @param anchor Where the place the child relative to its parent
|
||||
* @param offset Where to place the child relative to the anchor
|
||||
* @note Geode addition
|
||||
*/
|
||||
GEODE_DLL void updateAnchoredPosition(Anchor anchor, CCPoint const& offset = CCPointZero);
|
||||
/**
|
||||
* Updates the anchored position of a child. Requires the child to already
|
||||
* have a parent; if the child already has AnchorLayoutOptions set, those
|
||||
* are updated, otherwise nothing is done
|
||||
* @param anchor Where the place the child relative to its parent
|
||||
* @param offset Where to place the child relative to the anchor
|
||||
* @param nodeAnchor The child's anchor position
|
||||
* @note Geode addition
|
||||
*/
|
||||
GEODE_DLL void updateAnchoredPosition(
|
||||
Anchor anchor,
|
||||
CCPoint const& offset,
|
||||
CCPoint const& nodeAnchor = { .5f, .5f }
|
||||
);
|
||||
|
||||
/**
|
||||
* Swap two children
|
||||
|
|
|
@ -28,7 +28,7 @@ namespace geode {
|
|||
Gray = 2,
|
||||
Blue = 3,
|
||||
Cyan = 4,
|
||||
Geode = 5,
|
||||
DarkPurple = 5, // Geode-added color, used in Geode UIs
|
||||
};
|
||||
GEODE_DLL const char* baseEnumToString(CircleBaseColor);
|
||||
|
||||
|
|
BIN
loader/resources/blanks/baseCircle_BigAlt_DarkPurple.png
Normal file
BIN
loader/resources/blanks/baseCircle_BigAlt_DarkPurple.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 19 KiB |
BIN
loader/resources/blanks/baseCircle_Big_DarkPurple.png
Normal file
BIN
loader/resources/blanks/baseCircle_Big_DarkPurple.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 16 KiB |
Binary file not shown.
Before ![]() (image error) Size: 43 KiB After ![]() (image error) Size: 23 KiB ![]() ![]() |
BIN
loader/resources/blanks/baseCircle_Large_DarkPurple.png
Normal file
BIN
loader/resources/blanks/baseCircle_Large_DarkPurple.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 26 KiB |
BIN
loader/resources/blanks/baseCircle_MediumAlt_DarkPurple.png
Normal file
BIN
loader/resources/blanks/baseCircle_MediumAlt_DarkPurple.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 15 KiB |
BIN
loader/resources/blanks/baseCircle_Medium_DarkPurple.png
Normal file
BIN
loader/resources/blanks/baseCircle_Medium_DarkPurple.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 14 KiB |
BIN
loader/resources/blanks/baseCircle_SmallAlt_DarkPurple.png
Normal file
BIN
loader/resources/blanks/baseCircle_SmallAlt_DarkPurple.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 12 KiB |
BIN
loader/resources/blanks/baseCircle_Small_DarkPurple.png
Normal file
BIN
loader/resources/blanks/baseCircle_Small_DarkPurple.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 12 KiB |
BIN
loader/resources/blanks/baseCircle_Tiny_DarkPurple.png
Normal file
BIN
loader/resources/blanks/baseCircle_Tiny_DarkPurple.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 7.8 KiB |
BIN
loader/resources/images/GE_button_05.png
Normal file
BIN
loader/resources/images/GE_button_05.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 2.6 KiB |
BIN
loader/resources/reload.png
Normal file
BIN
loader/resources/reload.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 4.7 KiB |
|
@ -238,15 +238,41 @@ size_t CCNode::getEventListenerCount() {
|
|||
}
|
||||
|
||||
void CCNode::addChildAtPosition(CCNode* child, Anchor anchor, CCPoint const& offset, bool useAnchorLayout) {
|
||||
return this->addChildAtPosition(child, anchor, offset, child->getAnchorPoint(), useAnchorLayout);
|
||||
}
|
||||
|
||||
void CCNode::addChildAtPosition(CCNode* child, Anchor anchor, CCPoint const& offset, CCPoint const& nodeAnchor, bool useAnchorLayout) {
|
||||
auto layout = this->getLayout();
|
||||
if (!layout && useAnchorLayout) {
|
||||
this->setLayout(AnchorLayout::create());
|
||||
}
|
||||
// Set the position
|
||||
child->setPosition(AnchorLayout::getAnchoredPosition(this, anchor, offset));
|
||||
child->setAnchorPoint(nodeAnchor);
|
||||
// Set dynamic positioning
|
||||
if (useAnchorLayout) {
|
||||
child->setLayoutOptions(AnchorLayoutOptions::create()->setAnchor(anchor)->setOffset(offset));
|
||||
}
|
||||
this->addChild(child);
|
||||
}
|
||||
|
||||
void CCNode::updateAnchoredPosition(Anchor anchor, CCPoint const& offset) {
|
||||
return this->updateAnchoredPosition(anchor, offset, this->getAnchorPoint());
|
||||
}
|
||||
|
||||
void CCNode::updateAnchoredPosition(Anchor anchor, CCPoint const& offset, CCPoint const& nodeAnchor) {
|
||||
// Always require a parent
|
||||
if (!m_pParent) {
|
||||
return;
|
||||
}
|
||||
// Set the position
|
||||
this->setPosition(AnchorLayout::getAnchoredPosition(m_pParent, anchor, offset));
|
||||
this->setAnchorPoint(nodeAnchor);
|
||||
// Update dynamic positioning
|
||||
if (auto opts = typeinfo_cast<AnchorLayoutOptions*>(this->getLayoutOptions())) {
|
||||
opts->setAnchor(anchor);
|
||||
opts->setOffset(offset);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning(pop)
|
||||
|
|
|
@ -5,10 +5,6 @@ bool BaseModItem::init() {
|
|||
if (!CCNode::init())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void BaseModItem::setupCommonInfo() {
|
||||
auto meta = this->getMetadata();
|
||||
|
||||
m_logo = this->createModLogo();
|
||||
|
@ -29,38 +25,70 @@ void BaseModItem::setupCommonInfo() {
|
|||
m_developers->addChildAtPosition(developersBtn, Anchor::Center);
|
||||
m_developers->setAnchorPoint({ .0f, .5f });
|
||||
this->addChild(m_developers);
|
||||
|
||||
m_viewMenu = CCMenu::create();
|
||||
m_viewMenu->setAnchorPoint({ 1.f, .5f });
|
||||
m_viewMenu->setLayout(
|
||||
RowLayout::create()
|
||||
->setAxisReverse(true)
|
||||
->setAxisAlignment(AxisAlignment::End)
|
||||
);
|
||||
this->addChildAtPosition(m_viewMenu, Anchor::Right, ccp(-10, 0));
|
||||
|
||||
this->updateState();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void BaseModItem::updateState() {
|
||||
m_viewMenu->removeAllChildren();
|
||||
if (this->wantsRestart()) {
|
||||
auto restartSpr = ButtonSprite::create("Restart", "bigFont.fnt", "GE_button_02.png"_spr, .8f);
|
||||
restartSpr->setScale(.5f);
|
||||
auto restartBtn = CCMenuItemSpriteExtra::create(
|
||||
restartSpr, this, nullptr
|
||||
);
|
||||
m_viewMenu->addChild(restartBtn);
|
||||
}
|
||||
else {
|
||||
auto viewSpr = ButtonSprite::create("View", "bigFont.fnt", "GE_button_05.png"_spr, .8f);
|
||||
viewSpr->setScale(.5f);
|
||||
auto viewBtn = CCMenuItemSpriteExtra::create(
|
||||
viewSpr, this, nullptr
|
||||
);
|
||||
m_viewMenu->addChild(viewBtn);
|
||||
}
|
||||
m_viewMenu->updateLayout();
|
||||
}
|
||||
|
||||
void BaseModItem::updateSize(float width, bool big) {
|
||||
this->setContentSize({ width, big ? 40.f : 25.f });
|
||||
|
||||
if (m_logo) {
|
||||
auto logoSize = m_obContentSize.height - 5;
|
||||
limitNodeSize(m_logo, { logoSize, logoSize }, 999, .1f);
|
||||
m_logo->setPosition(m_obContentSize.height / 2 + 5, m_obContentSize.height / 2);
|
||||
}
|
||||
auto logoSize = m_obContentSize.height - 5;
|
||||
limitNodeSize(m_logo, { logoSize, logoSize }, 999, .1f);
|
||||
m_logo->setPosition(m_obContentSize.height / 2 + 5, m_obContentSize.height / 2);
|
||||
|
||||
CCSize titleSpace {
|
||||
m_obContentSize.width / 2 - m_obContentSize.height,
|
||||
m_obContentSize.height / 2
|
||||
};
|
||||
if (m_title) {
|
||||
m_title->setPosition(m_obContentSize.height + 10, m_obContentSize.height * .7f);
|
||||
limitNodeSize(m_title, titleSpace, 1.f, .1f);
|
||||
}
|
||||
if (m_developers) {
|
||||
m_developers->setPosition(m_obContentSize.height + 10, m_obContentSize.height * .3f);
|
||||
limitNodeSize(m_developers, titleSpace, .6f, .1f);
|
||||
}
|
||||
m_title->setPosition(m_obContentSize.height + 10, m_obContentSize.height * .7f);
|
||||
limitNodeSize(m_title, titleSpace, 1.f, .1f);
|
||||
m_developers->setPosition(m_obContentSize.height + 10, m_obContentSize.height * .3f);
|
||||
limitNodeSize(m_developers, titleSpace, .4f, .1f);
|
||||
|
||||
m_viewMenu->setContentWidth(m_obContentSize.width / 2 - 20);
|
||||
m_viewMenu->updateLayout();
|
||||
|
||||
this->updateLayout();
|
||||
}
|
||||
|
||||
bool InstalledModItem::init(Mod* mod) {
|
||||
m_mod = mod;
|
||||
|
||||
if (!BaseModItem::init())
|
||||
return false;
|
||||
|
||||
m_mod = mod;
|
||||
|
||||
this->setupCommonInfo();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -81,3 +109,7 @@ ModMetadata InstalledModItem::getMetadata() const {
|
|||
CCNode* InstalledModItem::createModLogo() const {
|
||||
return geode::createModLogo(m_mod);
|
||||
}
|
||||
|
||||
bool InstalledModItem::wantsRestart() const {
|
||||
return m_mod->getRequestedAction() != ModRequestedAction::None;
|
||||
}
|
||||
|
|
|
@ -9,16 +9,21 @@ protected:
|
|||
CCNode* m_logo = nullptr;
|
||||
CCNode* m_title = nullptr;
|
||||
CCNode* m_developers = nullptr;
|
||||
CCMenu* m_viewMenu;
|
||||
|
||||
/**
|
||||
* @warning Make sure `getMetadata` and `createModLogo` are callable
|
||||
* before calling `init`!
|
||||
*/
|
||||
bool init();
|
||||
|
||||
void setupCommonInfo();
|
||||
|
||||
public:
|
||||
virtual ModMetadata getMetadata() const = 0;
|
||||
virtual CCNode* createModLogo() const = 0;
|
||||
virtual bool wantsRestart() const = 0;
|
||||
|
||||
virtual void updateSize(float width, bool big);
|
||||
virtual void updateState();
|
||||
};
|
||||
|
||||
class InstalledModItem : public BaseModItem {
|
||||
|
@ -28,8 +33,12 @@ protected:
|
|||
bool init(Mod* mod);
|
||||
|
||||
public:
|
||||
/**
|
||||
* @note Make sure to call `updateSize` afterwards
|
||||
*/
|
||||
static InstalledModItem* create(Mod* mod);
|
||||
|
||||
ModMetadata getMetadata() const override;
|
||||
CCNode* createModLogo() const override;
|
||||
bool wantsRestart() const override;
|
||||
};
|
||||
|
|
|
@ -20,13 +20,34 @@ bool ModsLayer::init() {
|
|||
backSpr, this, menu_selector(ModsLayer::onBack)
|
||||
);
|
||||
backMenu->addChild(backBtn);
|
||||
|
||||
backMenu->setLayout(
|
||||
RowLayout::create()
|
||||
->setAxisAlignment(AxisAlignment::Start)
|
||||
);
|
||||
|
||||
this->addChildAtPosition(backMenu, Anchor::TopLeft, ccp(12, -25), false);
|
||||
|
||||
auto actionsMenu = CCMenu::create();
|
||||
actionsMenu->setContentHeight(200.f);
|
||||
actionsMenu->setAnchorPoint({ .5f, .0f });
|
||||
|
||||
auto reloadSpr = CircleButtonSprite::create(
|
||||
CCSprite::createWithSpriteFrameName("reload.png"_spr),
|
||||
CircleBaseColor::DarkPurple,
|
||||
CircleBaseSize::Medium
|
||||
);
|
||||
reloadSpr->setScale(.8f);
|
||||
auto reloadBtn = CCMenuItemSpriteExtra::create(
|
||||
reloadSpr, this, menu_selector(ModsLayer::onRefreshList)
|
||||
);
|
||||
actionsMenu->addChild(reloadBtn);
|
||||
|
||||
actionsMenu->setLayout(
|
||||
ColumnLayout::create()
|
||||
->setAxisAlignment(AxisAlignment::Start)
|
||||
);
|
||||
this->addChildAtPosition(actionsMenu, Anchor::BottomLeft, ccp(35, 12), false);
|
||||
|
||||
auto frame = CCNode::create();
|
||||
frame->setAnchorPoint({ .5f, .5f });
|
||||
frame->setContentSize({ 380, 205 });
|
||||
|
@ -97,12 +118,12 @@ bool ModsLayer::init() {
|
|||
|
||||
auto icon = CCSprite::createWithSpriteFrameName(std::get<0>(item));
|
||||
limitNodeSize(icon, iconSize, 3.f, .1f);
|
||||
spr->addChildAtPosition(icon, Anchor::Left, ccp(iconSize.width / 2 + 5, 0), false);
|
||||
spr->addChildAtPosition(icon, Anchor::Left, ccp(itemSize.height / 2, 0), false);
|
||||
|
||||
auto title = CCLabelBMFont::create(std::get<1>(item), "bigFont.fnt");
|
||||
title->limitLabelWidth(spr->getContentWidth() - iconSize.width - 15, .55f, .1f);
|
||||
title->limitLabelWidth(spr->getContentWidth() - itemSize.height - 10, .55f, .1f);
|
||||
title->setAnchorPoint({ .0f, .5f });
|
||||
spr->addChildAtPosition(title, Anchor::Left, ccp((iconSize.width + 10), 0), false);
|
||||
spr->addChildAtPosition(title, Anchor::Left, ccp(itemSize.height, 0), false);
|
||||
|
||||
auto btn = CCMenuItemSpriteExtra::create(spr, this, menu_selector(ModsLayer::onTab));
|
||||
btn->setID(std::get<2>(item));
|
||||
|
@ -135,6 +156,7 @@ void ModsLayer::loadList(std::string const& id, bool update) {
|
|||
}
|
||||
} break;
|
||||
}
|
||||
cache.id = id;
|
||||
cache.scrollPosition = std::numeric_limits<float>::max();
|
||||
m_listItemsCache[id] = std::move(cache);
|
||||
}
|
||||
|
@ -170,6 +192,12 @@ void ModsLayer::keyBackClicked() {
|
|||
this->onBack(nullptr);
|
||||
}
|
||||
|
||||
void ModsLayer::onRefreshList(CCObject*) {
|
||||
if (m_currentList) {
|
||||
this->loadList(m_currentList->id, true);
|
||||
}
|
||||
}
|
||||
|
||||
void ModsLayer::onBack(CCObject*) {
|
||||
CCDirector::get()->replaceScene(CCTransitionFade::create(.5f, MenuLayer::scene(false)));
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
using namespace geode::prelude;
|
||||
|
||||
struct ListCache {
|
||||
std::string id;
|
||||
std::vector<Ref<BaseModItem>> items;
|
||||
float scrollPosition;
|
||||
};
|
||||
|
@ -30,4 +31,5 @@ public:
|
|||
static ModsLayer* scene();
|
||||
|
||||
void onBack(CCObject*);
|
||||
void onRefreshList(CCObject*);
|
||||
};
|
||||
|
|
|
@ -25,7 +25,7 @@ const char* geode::baseEnumToString(CircleBaseColor value) {
|
|||
case CircleBaseColor::Gray: return "Gray";
|
||||
case CircleBaseColor::Blue: return "Blue";
|
||||
case CircleBaseColor::Cyan: return "Cyan";
|
||||
case CircleBaseColor::Geode: return "Geode";
|
||||
case CircleBaseColor::DarkPurple: return "DarkPurple";
|
||||
}
|
||||
return "Unknown";
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue