implement uninstalling in new ui :3

This commit is contained in:
HJfod 2024-03-25 01:05:48 +02:00
parent 13842b0fce
commit bdd8698e54
5 changed files with 215 additions and 60 deletions

View file

@ -169,6 +169,17 @@ void ModItem::updateState() {
// Update enable toggle state
if (m_enableToggle && m_source.asMod()) {
m_enableToggle->toggle(m_source.asMod()->isOrWillBeEnabled());
// Disable the toggle if the mod has been uninstalled
if (modRequestedActionIsUninstall(m_source.asMod()->getRequestedAction())) {
m_enableToggle->setEnabled(false);
auto off = typeinfo_cast<CCRGBAProtocol*>(m_enableToggle->m_offButton->getNormalImage());
auto on = typeinfo_cast<CCRGBAProtocol*>(m_enableToggle->m_onButton->getNormalImage());
off->setColor(ccGRAY);
off->setOpacity(105);
on->setColor(ccGRAY);
on->setOpacity(105);
}
}
}

View file

@ -0,0 +1,77 @@
#include "ConfirmUninstallPopup.hpp"
bool ConfirmUninstallPopup::setup(Mod* mod) {
m_mod = mod;
this->setTitle("Uninstall " + mod->getName());
auto text = TextArea::create(
fmt::format("Are you sure you want to \n<cr>uninstall {}</c>?", mod->getName()),
"chatFont.fnt",
1.f, m_size.width - 35,
ccp(.5f, .5f), 20.f, false
);
m_mainLayer->addChildAtPosition(text, Anchor::Center, ccp(0, 20));
auto deleteDataLabel = CCLabelBMFont::create("Delete the Mod's save data", "bigFont.fnt");
deleteDataLabel->setScale(.35f);
m_buttonMenu->addChildAtPosition(deleteDataLabel, Anchor::Center, ccp(-70, -15), ccp(0, .5f));
m_deleteDataToggle = CCMenuItemToggler::createWithStandardSprites(this, nullptr, .6f);
m_buttonMenu->addChildAtPosition(m_deleteDataToggle, Anchor::Center, ccp(-88, -15));
auto cancelSpr = ButtonSprite::create("Cancel", "goldFont.fnt", "GJ_button_01.png", .8f);
cancelSpr->setScale(.85f);
auto cancelBtn = CCMenuItemSpriteExtra::create(
cancelSpr, this, menu_selector(ConfirmUninstallPopup::onClose)
);
m_buttonMenu->addChildAtPosition(cancelBtn, Anchor::Bottom, ccp(-52, 28));
auto uninstallSpr = ButtonSprite::create("Uninstall", "goldFont.fnt", "GJ_button_01.png", .8f);
uninstallSpr->setScale(.85f);
auto uninstallBtn = CCMenuItemSpriteExtra::create(
uninstallSpr, this, menu_selector(ConfirmUninstallPopup::onUninstall)
);
m_buttonMenu->addChildAtPosition(uninstallBtn, Anchor::Bottom, ccp(42, 28));
return true;
}
void ConfirmUninstallPopup::onUninstall(CCObject*) {
auto res = m_mod->uninstall(m_deleteDataToggle->isToggled());
if (res) {
FLAlertLayer::create(
"Mod Uninstalled",
m_mod->getName() + " has been uninstalled!",
"OK"
)->show();
}
else {
FLAlertLayer::create(
"Error Uninstalling",
"Error uninstalling " + m_mod->getName() + ": " + res.unwrapErr(),
"OK"
)->show();
}
if (m_updateParentState) {
m_updateParentState();
}
this->onClose(nullptr);
}
ConfirmUninstallPopup* ConfirmUninstallPopup::create(Mod* mod) {
auto ret = new ConfirmUninstallPopup();
if (ret && ret->initAnchored(300, 150, mod, "square01_001.png", { 0, 0, 94, 94 })) {
ret->autorelease();
return ret;
}
CC_SAFE_DELETE(ret);
return nullptr;
}
void ConfirmUninstallPopup::onUpdateParentState(MiniFunction<void()> listener) {
m_updateParentState = listener;
}

View file

@ -0,0 +1,22 @@
#pragma once
#include <Geode/ui/Popup.hpp>
using namespace geode::prelude;
class ConfirmUninstallPopup : public Popup<Mod*> {
protected:
Mod* m_mod;
CCMenuItemToggler* m_deleteDataToggle;
MiniFunction<void()> m_updateParentState = nullptr;
bool setup(Mod* mod) override;
void onUninstall(CCObject*);
public:
static ConfirmUninstallPopup* create(Mod* mod);
// todo: replace all of these with a single event
void onUpdateParentState(MiniFunction<void()> listener);
};

View file

@ -3,6 +3,7 @@
#include <Geode/utils/web.hpp>
#include <Geode/ui/GeodeUI.hpp>
#include <Geode/utils/ColorProvider.hpp>
#include "ConfirmUninstallPopup.hpp"
bool ModPopup::setup(ModSource&& src) {
m_source = std::move(src);
@ -226,47 +227,76 @@ bool ModPopup::setup(ModSource&& src) {
m_installMenu->setContentSize(installContainer->getContentSize() - ccp(10, 10));
m_installMenu->setAnchorPoint({ .5f, .5f });
for (auto stat : std::initializer_list<std::tuple<
CCMenuItemToggler**,
const char*, const char*, const char*,
const char*, const char*, const char*, SEL_MenuHandler
>> {
{
&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 onSpr = createGeodeButton(
CCSprite::createWithSpriteFrameName(std::get<1>(stat)),
std::get<2>(stat),
std::get<3>(stat)
auto enableModOffSpr = createGeodeButton(
CCSprite::createWithSpriteFrameName("GJ_completesIcon_001.png"),
"Enable",
"GJ_button_01.png"
);
onSpr->setScale(.5f);
auto offSpr = createGeodeButton(
CCSprite::createWithSpriteFrameName(std::get<4>(stat)),
std::get<5>(stat),
std::get<6>(stat)
enableModOffSpr->setScale(.5f);
auto enableModOnSpr = createGeodeButton(
CCSprite::createWithSpriteFrameName("GJ_deleteIcon_001.png"),
"Disable",
"GJ_button_06.png"
);
offSpr->setScale(.5f);
auto toggle = CCMenuItemToggler::create(offSpr, onSpr, this, std::get<7>(stat));
toggle->m_notClickable = true;
m_installMenu->addChild(toggle);
*std::get<0>(stat) = toggle;
}
enableModOnSpr->setScale(.5f);
m_enableBtn = CCMenuItemToggler::create(
enableModOffSpr, enableModOnSpr,
this, menu_selector(ModPopup::onEnable)
);
m_enableBtn->m_notClickable = true;
m_installMenu->addChild(m_enableBtn);
auto reenableModOffSpr = createGeodeButton(
CCSprite::createWithSpriteFrameName("reset.png"_spr),
"Re-Enable",
"GE_button_05.png"_spr
);
reenableModOffSpr->setScale(.5f);
auto reenableModOnSpr = createGeodeButton(
CCSprite::createWithSpriteFrameName("reset.png"_spr),
"Re-Disable",
"GE_button_05.png"_spr
);
reenableModOnSpr->setScale(.5f);
m_reenableBtn = CCMenuItemToggler::create(
reenableModOffSpr, reenableModOnSpr,
this, menu_selector(ModPopup::onEnable)
);
m_reenableBtn->m_notClickable = true;
m_installMenu->addChild(m_reenableBtn);
auto installModSpr = createGeodeButton(
CCSprite::createWithSpriteFrameName("GJ_downloadsIcon_001.png"),
"Install",
"GE_button_01.png"_spr
);
installModSpr->setScale(.5f);
m_installBtn = CCMenuItemSpriteExtra::create(
installModSpr, this, nullptr
);
m_installMenu->addChild(m_installBtn);
auto uninstallModSpr = createGeodeButton(
CCSprite::createWithSpriteFrameName("delete-white.png"_spr),
"Uninstall",
"GE_button_05.png"_spr
);
uninstallModSpr->setScale(.5f);
m_uninstallBtn = CCMenuItemSpriteExtra::create(
uninstallModSpr, this, menu_selector(ModPopup::onUninstall)
);
m_installMenu->addChild(m_uninstallBtn);
m_installStatusLabel = CCLabelBMFont::create("", "bigFont.fnt");
m_installStatusLabel->setOpacity(120);
m_installMenu->addChild(m_installStatusLabel);
m_installMenu->setLayout(
RowLayout::create()
->setDefaultScaleLimits(.1f, 1)
->setAxisAlignment(AxisAlignment::Center)
);
m_installMenu->getLayout()->ignoreInvisibleChildren(true);
installContainer->addChildAtPosition(m_installMenu, Anchor::Center);
leftColumn->addChild(installContainer);
@ -408,39 +438,32 @@ bool ModPopup::setup(ModSource&& src) {
}
void ModPopup::updateState() {
auto shouldEnableEnableBtn =
m_source.asMod() &&
!modRequestedActionIsUninstall(m_source.asMod()->getRequestedAction());
auto shouldEnableInstallBtn =
!modRequestedActionIsToggle(m_source.asMod()->getRequestedAction());
auto asMod = m_source.asMod();
auto asServer = m_source.asServer();
auto wantsRestart = m_source.wantsRestart();
auto enableBtnOff = static_cast<IconButtonSprite*>(m_enableBtn->m_offButton->getNormalImage());
auto enableBtnOn = static_cast<IconButtonSprite*>(m_enableBtn->m_onButton->getNormalImage());
auto installBtnOff = static_cast<IconButtonSprite*>(m_installBtn->m_offButton->getNormalImage());
auto installBtnOn = static_cast<IconButtonSprite*>(m_installBtn->m_onButton->getNormalImage());
m_enableBtn->toggle(asMod && asMod->isOrWillBeEnabled());
m_enableBtn->setVisible(asMod && asMod->getRequestedAction() == ModRequestedAction::None);
m_enableBtn->toggle(m_source.asMod() && m_source.asMod()->isOrWillBeEnabled());
m_enableBtn->setEnabled(shouldEnableEnableBtn);
enableBtnOff->setOpacity(shouldEnableEnableBtn ? 255 : 105);
enableBtnOff->setColor(shouldEnableEnableBtn ? ccc3(255, 255, 255) : ccc3(155, 155, 155));
enableBtnOn->setOpacity(shouldEnableEnableBtn ? 255 : 105);
enableBtnOn->setColor(shouldEnableEnableBtn ? ccc3(255, 255, 255) : ccc3(155, 155, 155));
m_reenableBtn->toggle(m_enableBtn->isToggled());
m_reenableBtn->setVisible(asMod && modRequestedActionIsToggle(asMod->getRequestedAction()));
// todo: uninstall just installed server mods
m_installBtn->toggle(m_source.asMod() && modRequestedActionIsUninstall(m_source.asMod()->getRequestedAction()));
m_installBtn->setEnabled(shouldEnableInstallBtn);
installBtnOff->setOpacity(shouldEnableInstallBtn ? 255 : 105);
installBtnOff->setColor(shouldEnableInstallBtn ? ccc3(255, 255, 255) : ccc3(155, 155, 155));
installBtnOn->setOpacity(shouldEnableInstallBtn ? 255 : 105);
installBtnOn->setColor(shouldEnableInstallBtn ? ccc3(255, 255, 255) : ccc3(155, 155, 155));
m_installBtn->setVisible(asServer);
m_uninstallBtn->setVisible(asMod && asMod->getRequestedAction() == ModRequestedAction::None);
m_installBG->setColor(wantsRestart ? to3B(ColorProvider::get()->color("mod-list-restart-required-label"_spr)) : ccc3(0, 0, 0));
m_installBG->setOpacity(wantsRestart ? 40 : 75);
m_restartRequiredLabel->setVisible(wantsRestart);
if (asMod && modRequestedActionIsUninstall(asMod->getRequestedAction())) {
m_installStatusLabel->setString("Mod has been uninstalled");
}
else {
m_installStatusLabel->setString("");
}
m_installMenu->updateLayout();
// Propagate update up the chain
if (m_updateParentState) {
m_updateParentState();
@ -633,6 +656,24 @@ void ModPopup::onEnable(CCObject*) {
this->updateState();
}
void ModPopup::onUninstall(CCObject*) {
if (auto mod = m_source.asMod()) {
auto popup = ConfirmUninstallPopup::create(mod);
popup->onUpdateParentState([this] {
this->updateState();
this->onClose(nullptr);
});
popup->show();
}
else {
FLAlertLayer::create(
"Error Uninstalling Mod",
"This mod can not be uninstalled! (It is not installed at all)",
"OK"
)->show();
}
}
void ModPopup::onLink(CCObject* sender) {
auto url = static_cast<CCString*>(static_cast<CCNode*>(sender)->getUserObject("url"));
web::openLinkInBrowser(url->getCString());

View file

@ -20,7 +20,10 @@ protected:
CCNode* m_tags;
CCMenu* m_installMenu;
CCMenuItemToggler* m_enableBtn;
CCMenuItemToggler* m_installBtn;
CCMenuItemToggler* m_reenableBtn;
CCMenuItemSpriteExtra* m_uninstallBtn;
CCMenuItemSpriteExtra* m_installBtn;
CCLabelBMFont* m_installStatusLabel;
CCScale9Sprite* m_installBG;
ButtonSprite* m_restartRequiredLabel;
CCNode* m_rightColumn;
@ -42,6 +45,7 @@ protected:
void loadTab(Tab tab);
void onTab(CCObject* sender);
void onEnable(CCObject*);
void onUninstall(CCObject*);
void onLink(CCObject*);
void onSupport(CCObject*);