mirror of
https://github.com/geode-sdk/geode.git
synced 2025-04-01 07:40:18 -04:00
impl disabling / enabling mods through ModPopup
This commit is contained in:
parent
6edef6c61b
commit
062ab12c83
3 changed files with 130 additions and 26 deletions
loader/src/ui/mods
|
@ -162,7 +162,7 @@ void ModItem::updateState() {
|
|||
|
||||
// Highlight item via BG if it wants to restart for extra UI attention
|
||||
if (wantsRestart) {
|
||||
m_bg->setColor({ 153, 245, 245 });
|
||||
m_bg->setColor(ColorProvider::get()->define("mod-list-restart-required-label"_spr, ccc3(153, 245, 245)));
|
||||
m_bg->setOpacity(40);
|
||||
}
|
||||
|
||||
|
@ -225,7 +225,11 @@ ModItem* ModItem::create(ModSource&& source) {
|
|||
}
|
||||
|
||||
void ModItem::onView(CCObject*) {
|
||||
ModPopup::create(ModSource(m_source))->show();
|
||||
auto popup = ModPopup::create(ModSource(m_source));
|
||||
popup->onUpdateParentState([this]() {
|
||||
this->updateState();
|
||||
});
|
||||
popup->show();
|
||||
}
|
||||
|
||||
void ModItem::onEnable(CCObject*) {
|
||||
|
|
|
@ -193,50 +193,81 @@ bool ModPopup::setup(ModSource&& src) {
|
|||
|
||||
// Installing
|
||||
|
||||
auto manageContainer = CCNode::create();
|
||||
manageContainer->setContentSize({ leftColumn->getContentWidth(), 10 });
|
||||
|
||||
auto manageTitle = CCLabelBMFont::create("Manage", "bigFont.fnt");
|
||||
manageTitle->limitLabelWidth(leftColumn->getContentWidth(), .25f, .05f);
|
||||
manageTitle->setScale(.25f);
|
||||
manageTitle->setOpacity(195);
|
||||
leftColumn->addChild(manageTitle);
|
||||
manageContainer->addChildAtPosition(manageTitle, Anchor::Left, ccp(0, 0), ccp(0, .5f));
|
||||
|
||||
m_restartRequiredLabel = createGeodeTagLabel(
|
||||
"Restart Required",
|
||||
ColorProvider::get()->define("mod-list-restart-required-label"_spr, ccc3(153, 245, 245)),
|
||||
ColorProvider::get()->define("mod-list-restart-required-label-bg"_spr, ccc3(123, 156, 163))
|
||||
);
|
||||
m_restartRequiredLabel->setLayoutOptions(AxisLayoutOptions::create()->setMaxScale(.75f));
|
||||
m_restartRequiredLabel->setScale(.3f);
|
||||
manageContainer->addChildAtPosition(m_restartRequiredLabel, Anchor::Right, ccp(0, 0), ccp(1, .5f));
|
||||
|
||||
leftColumn->addChild(manageContainer);
|
||||
|
||||
auto installContainer = CCNode::create();
|
||||
installContainer->setContentSize({ leftColumn->getContentWidth(), 25 });
|
||||
installContainer->setAnchorPoint({ .5f, .5f });
|
||||
|
||||
auto installBG = CCScale9Sprite::create("square02b_001.png");
|
||||
installBG->setColor({ 0, 0, 0 });
|
||||
installBG->setOpacity(75);
|
||||
installBG->setScale(.3f);
|
||||
installBG->setContentSize(installContainer->getContentSize() / installBG->getScale());
|
||||
installContainer->addChildAtPosition(installBG, Anchor::Center);
|
||||
m_installBG = CCScale9Sprite::create("square02b_001.png");
|
||||
m_installBG->setScale(.3f);
|
||||
m_installBG->setContentSize(installContainer->getContentSize() / m_installBG->getScale());
|
||||
installContainer->addChildAtPosition(m_installBG, Anchor::Center);
|
||||
|
||||
auto installMenu = CCMenu::create();
|
||||
installMenu->ignoreAnchorPointForPosition(false);
|
||||
installMenu->setContentSize(installContainer->getContentSize() - ccp(10, 10));
|
||||
installMenu->setAnchorPoint({ .5f, .5f });
|
||||
m_installMenu = CCMenu::create();
|
||||
m_installMenu->ignoreAnchorPointForPosition(false);
|
||||
m_installMenu->setContentSize(installContainer->getContentSize() - ccp(10, 10));
|
||||
m_installMenu->setAnchorPoint({ .5f, .5f });
|
||||
|
||||
for (auto stat : std::initializer_list<std::tuple<
|
||||
const char*, const char*, SEL_MenuHandler
|
||||
CCMenuItemToggler**,
|
||||
const char*, const char*, const char*,
|
||||
const char*, const char*, const char*, SEL_MenuHandler
|
||||
>> {
|
||||
{ "GJ_deleteIcon_001.png", "Disable", nullptr },
|
||||
{ "edit_delBtn_001.png", "Uninstall", nullptr },
|
||||
{
|
||||
&m_enableBtn,
|
||||
"GJ_completesIcon_001.png", "Enable", "GJ_button_01.png",
|
||||
"GJ_deleteIcon_001.png", "Disable", "GJ_button_06.png",
|
||||
menu_selector(ModPopup::onEnable)
|
||||
},
|
||||
{
|
||||
&m_installBtn,
|
||||
"GJ_downloadsIcon_001.png", "Install", "GE_button_01.png"_spr,
|
||||
"edit_delBtn_001.png", "Uninstall", "GE_button_05.png"_spr,
|
||||
nullptr
|
||||
},
|
||||
}) {
|
||||
auto spr = createGeodeButton(
|
||||
CCSprite::createWithSpriteFrameName(std::get<0>(stat)),
|
||||
std::get<1>(stat)
|
||||
auto onSpr = createGeodeButton(
|
||||
CCSprite::createWithSpriteFrameName(std::get<1>(stat)),
|
||||
std::get<2>(stat),
|
||||
std::get<3>(stat)
|
||||
);
|
||||
spr->setScale(.5f);
|
||||
auto btn = CCMenuItemSpriteExtra::create(
|
||||
spr, this, std::get<2>(stat)
|
||||
onSpr->setScale(.48f);
|
||||
auto offSpr = createGeodeButton(
|
||||
CCSprite::createWithSpriteFrameName(std::get<4>(stat)),
|
||||
std::get<5>(stat),
|
||||
std::get<6>(stat)
|
||||
);
|
||||
installMenu->addChild(btn);
|
||||
offSpr->setScale(.48f);
|
||||
auto toggle = CCMenuItemToggler::create(offSpr, onSpr, this, std::get<7>(stat));
|
||||
toggle->m_notClickable = true;
|
||||
m_installMenu->addChild(toggle);
|
||||
*std::get<0>(stat) = toggle;
|
||||
}
|
||||
|
||||
installMenu->setLayout(
|
||||
m_installMenu->setLayout(
|
||||
RowLayout::create()
|
||||
->setDefaultScaleLimits(.1f, 1)
|
||||
->setAxisAlignment(AxisAlignment::Center)
|
||||
);
|
||||
installContainer->addChildAtPosition(installMenu, Anchor::Center);
|
||||
installContainer->addChildAtPosition(m_installMenu, Anchor::Center);
|
||||
|
||||
leftColumn->addChild(installContainer);
|
||||
|
||||
|
@ -364,6 +395,9 @@ bool ModPopup::setup(ModSource&& src) {
|
|||
// Select details tab
|
||||
this->loadTab(Tab::Details);
|
||||
|
||||
// Update enabling and installing buttons
|
||||
this->updateState();
|
||||
|
||||
// Load stats from server (or just from the source if it already has them)
|
||||
m_statsListener.bind(this, &ModPopup::onLoadServerInfo);
|
||||
m_statsListener.setFilter(m_source.fetchServerInfo().listen());
|
||||
|
@ -373,6 +407,44 @@ bool ModPopup::setup(ModSource&& src) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void ModPopup::updateState() {
|
||||
if (auto mod = m_source.asMod()) {
|
||||
m_enableBtn->toggle(mod->isOrWillBeEnabled());
|
||||
m_enableBtn->setEnabled(true);
|
||||
m_enableBtn->m_offButton->setOpacity(255);
|
||||
m_enableBtn->m_onButton->setOpacity(255);
|
||||
}
|
||||
else {
|
||||
m_enableBtn->setEnabled(false);
|
||||
m_enableBtn->m_offButton->setOpacity(150);
|
||||
m_enableBtn->m_onButton->setOpacity(150);
|
||||
}
|
||||
|
||||
if (m_source.wantsRestart()) {
|
||||
m_installBG->setColor(ColorProvider::get()->define("mod-list-restart-required-label"_spr, ccc3(153, 245, 245)));
|
||||
m_installBG->setOpacity(40);
|
||||
m_restartRequiredLabel->setVisible(true);
|
||||
}
|
||||
else {
|
||||
m_installBG->setColor({ 0, 0, 0 });
|
||||
m_installBG->setOpacity(75);
|
||||
m_restartRequiredLabel->setVisible(false);
|
||||
}
|
||||
|
||||
// todo: uninstall just installed server mods
|
||||
if (m_source.asMod() /* || m_source.asServer()->isInstalled() */) {
|
||||
m_installBtn->toggle(
|
||||
m_source.asMod()->getRequestedAction() == ModRequestedAction::Uninstall ||
|
||||
m_source.asMod()->getRequestedAction() == ModRequestedAction::UninstallWithSaveData
|
||||
);
|
||||
}
|
||||
|
||||
// Propagate update up the chain
|
||||
if (m_updateParentState) {
|
||||
m_updateParentState();
|
||||
}
|
||||
}
|
||||
|
||||
void ModPopup::setStatIcon(CCNode* stat, const char* spr) {
|
||||
// Remove old icon
|
||||
stat->removeChildByID("icon");
|
||||
|
@ -545,6 +617,20 @@ void ModPopup::onTab(CCObject* sender) {
|
|||
this->loadTab(static_cast<Tab>(sender->getTag()));
|
||||
}
|
||||
|
||||
void ModPopup::onEnable(CCObject*) {
|
||||
if (auto mod = m_source.asMod()) {
|
||||
// Toggle the mod state
|
||||
auto res = mod->isOrWillBeEnabled() ? mod->disable() : mod->enable();
|
||||
if (!res) {
|
||||
FLAlertLayer::create("Error Toggling Mod", res.unwrapErr(), "OK")->show();
|
||||
}
|
||||
}
|
||||
else {
|
||||
FLAlertLayer::create("Error Toggling Mod", "This mod can not be toggled!", "OK")->show();
|
||||
}
|
||||
this->updateState();
|
||||
}
|
||||
|
||||
void ModPopup::onLink(CCObject* sender) {
|
||||
auto url = static_cast<CCString*>(static_cast<CCNode*>(sender)->getUserObject("url"));
|
||||
web::openLinkInBrowser(url->getCString());
|
||||
|
@ -563,3 +649,7 @@ ModPopup* ModPopup::create(ModSource&& src) {
|
|||
CC_SAFE_DELETE(ret);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ModPopup::onUpdateParentState(MiniFunction<void()> listener) {
|
||||
m_updateParentState = listener;
|
||||
}
|
||||
|
|
|
@ -18,13 +18,20 @@ protected:
|
|||
ModSource m_source;
|
||||
CCNode* m_stats;
|
||||
CCNode* m_tags;
|
||||
CCMenu* m_installMenu;
|
||||
CCMenuItemToggler* m_enableBtn;
|
||||
CCMenuItemToggler* m_installBtn;
|
||||
CCScale9Sprite* m_installBG;
|
||||
ButtonSprite* m_restartRequiredLabel;
|
||||
CCNode* m_rightColumn;
|
||||
CCNode* m_currentTabPage = nullptr;
|
||||
std::unordered_map<Tab, std::pair<GeodeTabSprite*, Ref<CCNode>>> m_tabs;
|
||||
EventListener<PromiseEventFilter<server::ServerModMetadata, server::ServerError>> m_statsListener;
|
||||
EventListener<PromiseEventFilter<std::unordered_set<std::string>, server::ServerError>> m_tagsListener;
|
||||
MiniFunction<void()> m_updateParentState = nullptr;
|
||||
|
||||
bool setup(ModSource&& src) override;
|
||||
void updateState();
|
||||
|
||||
void setStatIcon(CCNode* stat, const char* spr);
|
||||
void setStatLabel(CCNode* stat, std::string const& value, bool noValue = false, ccColor3B color = ccWHITE);
|
||||
|
@ -34,10 +41,13 @@ protected:
|
|||
void onLoadTags(PromiseEvent<std::unordered_set<std::string>, server::ServerError>* event);
|
||||
void loadTab(Tab tab);
|
||||
void onTab(CCObject* sender);
|
||||
void onEnable(CCObject*);
|
||||
|
||||
void onLink(CCObject*);
|
||||
void onSupport(CCObject*);
|
||||
|
||||
public:
|
||||
static ModPopup* create(ModSource&& src);
|
||||
|
||||
void onUpdateParentState(MiniFunction<void()> listener);
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue