mirror of
https://github.com/geode-sdk/geode.git
synced 2025-04-01 07:40:18 -04:00
add installation confirm popup
This commit is contained in:
parent
cdc41a5c10
commit
9c7c87fb17
12 changed files with 122 additions and 379 deletions
|
@ -17,7 +17,7 @@ class ModDownload::Impl final {
|
|||
public:
|
||||
std::string m_id;
|
||||
std::optional<VersionInfo> m_version;
|
||||
std::optional<std::string> m_dependencyFor;
|
||||
std::optional<DependencyFor> m_dependencyFor;
|
||||
DownloadStatus m_status;
|
||||
EventListener<ServerRequest<ServerModVersion>> m_infoListener;
|
||||
EventListener<web::WebTask> m_downloadListener;
|
||||
|
@ -25,7 +25,7 @@ public:
|
|||
Impl(
|
||||
std::string const& id,
|
||||
std::optional<VersionInfo> const& version,
|
||||
std::optional<std::string> const& dependencyFor
|
||||
std::optional<DependencyFor> const& dependencyFor
|
||||
)
|
||||
: m_id(id),
|
||||
m_version(version),
|
||||
|
@ -40,11 +40,12 @@ public:
|
|||
auto data = result->unwrap();
|
||||
m_version = data.metadata.getVersion();
|
||||
|
||||
// Start downloads for any missing dependencies
|
||||
// Start downloads for any missing required dependencies
|
||||
for (auto dep : data.metadata.getDependencies()) {
|
||||
if (!dep.mod) {
|
||||
if (!dep.mod && dep.importance != ModMetadata::Dependency::Importance::Suggested) {
|
||||
ModDownloadManager::get()->startDownload(
|
||||
dep.id, dep.version.getUnderlyingVersion(), m_id
|
||||
dep.id, dep.version.getUnderlyingVersion(),
|
||||
std::make_pair(m_id, dep.importance)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -145,14 +146,14 @@ public:
|
|||
ModDownload::ModDownload(
|
||||
std::string const& id,
|
||||
std::optional<VersionInfo> const& version,
|
||||
std::optional<std::string> const& dependencyFor
|
||||
std::optional<DependencyFor> const& dependencyFor
|
||||
) : m_impl(std::make_shared<Impl>(id, version, dependencyFor)) {}
|
||||
|
||||
void ModDownload::confirm() {
|
||||
m_impl->confirm();
|
||||
}
|
||||
|
||||
std::optional<std::string> ModDownload::getDependencyFor() const {
|
||||
std::optional<DependencyFor> ModDownload::getDependencyFor() const {
|
||||
return m_impl->m_dependencyFor;
|
||||
}
|
||||
bool ModDownload::isDone() const {
|
||||
|
@ -193,8 +194,8 @@ public:
|
|||
for (auto& [_, d] : m_downloads) {
|
||||
if (auto depFor = d.m_impl->m_dependencyFor) {
|
||||
if (
|
||||
!m_downloads.contains(*depFor) ||
|
||||
!(m_downloads.at(*depFor).isActive() || m_downloads.at(*depFor).isDone())
|
||||
!m_downloads.contains(depFor->first) ||
|
||||
!(m_downloads.at(depFor->first).isActive() || m_downloads.at(depFor->first).isDone())
|
||||
) {
|
||||
// d.cancel() will cause cancelOrphanedDependencies() to be called again
|
||||
// We want that anyway because cancelling one dependency might cause
|
||||
|
@ -222,7 +223,7 @@ void ModDownload::cancel() {
|
|||
std::optional<ModDownload> ModDownloadManager::startDownload(
|
||||
std::string const& id,
|
||||
std::optional<VersionInfo> const& version,
|
||||
std::optional<std::string> const& dependencyFor
|
||||
std::optional<DependencyFor> const& dependencyFor
|
||||
) {
|
||||
// If this mod has already been succesfully downloaded or is currently
|
||||
// being downloaded, return as you can't download multiple versions of the
|
||||
|
@ -277,13 +278,6 @@ bool ModDownloadManager::checkAutoConfirm() {
|
|||
for (auto& [_, download] : m_impl->m_downloads) {
|
||||
auto status = download.getStatus();
|
||||
if (auto confirm = std::get_if<server::DownloadStatusConfirm>(&status)) {
|
||||
for (auto dep : confirm->version.metadata.getDependencies()) {
|
||||
// If some mod has an optional dependency that isn't installed,
|
||||
// we need to ask for confirmation
|
||||
if (!dep.mod && dep.importance != ModMetadata::Dependency::Importance::Required) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (auto inc : confirm->version.metadata.getIncompatibilities()) {
|
||||
// If some mod has an incompatability that is installed,
|
||||
// we need to ask for confirmation
|
||||
|
|
|
@ -54,6 +54,8 @@ namespace server {
|
|||
ModDownloadFilter(std::string const& id);
|
||||
};
|
||||
|
||||
using DependencyFor = std::pair<std::string, ModMetadata::Dependency::Importance>;
|
||||
|
||||
class ModDownload final {
|
||||
private:
|
||||
class Impl;
|
||||
|
@ -63,7 +65,7 @@ namespace server {
|
|||
ModDownload(
|
||||
std::string const& id,
|
||||
std::optional<VersionInfo> const& version,
|
||||
std::optional<std::string> const& dependencyFor
|
||||
std::optional<DependencyFor> const& dependencyFor
|
||||
);
|
||||
|
||||
friend class ModDownloadManager;
|
||||
|
@ -75,7 +77,7 @@ namespace server {
|
|||
bool isDone() const;
|
||||
bool isActive() const;
|
||||
bool canRetry() const;
|
||||
std::optional<std::string> getDependencyFor() const;
|
||||
std::optional<DependencyFor> getDependencyFor() const;
|
||||
std::string getID() const;
|
||||
DownloadStatus getStatus() const;
|
||||
std::optional<VersionInfo> getVersion() const;
|
||||
|
@ -98,7 +100,7 @@ namespace server {
|
|||
std::optional<ModDownload> startDownload(
|
||||
std::string const& id,
|
||||
std::optional<VersionInfo> const& version,
|
||||
std::optional<std::string> const& dependencyFor = std::nullopt
|
||||
std::optional<DependencyFor> const& dependencyFor = std::nullopt
|
||||
);
|
||||
void startUpdateAll();
|
||||
void confirmAll();
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#include <Geode/ui/TextInput.hpp>
|
||||
#include <Geode/utils/ColorProvider.hpp>
|
||||
#include <Geode/ui/GeodeUI.hpp>
|
||||
#include "popups/ConfirmInstallPopup.hpp"
|
||||
#include "popups/ConfirmInstall.hpp"
|
||||
#include "GeodeStyle.hpp"
|
||||
|
||||
bool ModsStatusNode::init() {
|
||||
|
@ -245,7 +245,7 @@ void ModsStatusNode::onViewErrors(CCObject*) {
|
|||
);
|
||||
}
|
||||
void ModsStatusNode::onConfirm(CCObject*) {
|
||||
ConfirmInstallPopup::askForCustomize();
|
||||
askConfirmModInstalls();
|
||||
}
|
||||
void ModsStatusNode::onCancel(CCObject*) {
|
||||
server::ModDownloadManager::get()->cancelAll();
|
||||
|
|
|
@ -1,97 +0,0 @@
|
|||
#include "ModProblemItem.hpp"
|
||||
#include <Geode/utils/ColorProvider.hpp>
|
||||
#include <Geode/ui/GeodeUI.hpp>
|
||||
|
||||
bool ModProblemItem::init() {
|
||||
if (!CCNode::init())
|
||||
return false;
|
||||
|
||||
this->setContentSize({ 250, 28 });
|
||||
|
||||
auto bg = CCScale9Sprite::create("square02b_small.png");
|
||||
bg->setOpacity(20);
|
||||
bg->ignoreAnchorPointForPosition(false);
|
||||
bg->setAnchorPoint({ .5f, .5f });
|
||||
bg->setScale(.7f);
|
||||
bg->setContentSize(m_obContentSize / bg->getScale());
|
||||
this->addChildAtPosition(bg, Anchor::Center);
|
||||
|
||||
m_menu = CCMenu::create();
|
||||
m_menu->setContentWidth(m_obContentSize.width / 2 - 10);
|
||||
m_menu->setLayout(
|
||||
RowLayout::create()
|
||||
->setDefaultScaleLimits(.1f, .35f)
|
||||
->setAxisAlignment(AxisAlignment::End)
|
||||
);
|
||||
this->addChildAtPosition(m_menu, Anchor::Right, ccp(-5, 0), ccp(1, .5f));
|
||||
|
||||
this->setLoading();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ModProblemItem::clearState() {
|
||||
this->removeChildByID("loading-spinner");
|
||||
this->removeChildByID("error-label");
|
||||
}
|
||||
void ModProblemItem::setLoading() {
|
||||
this->clearState();
|
||||
|
||||
auto loadingCircle = createLoadingCircle(20);
|
||||
this->addChildAtPosition(loadingCircle, Anchor::Center);
|
||||
}
|
||||
void ModProblemItem::setError(std::string const& error) {
|
||||
this->clearState();
|
||||
|
||||
auto label = CCLabelBMFont::create(error.c_str(), "bigFont.fnt");
|
||||
label->setColor("mod-list-errors-found"_cc3b);
|
||||
label->limitLabelWidth(m_obContentSize.width, .5f, .1f);
|
||||
label->setID("error-label");
|
||||
this->addChildAtPosition(label, Anchor::Center);
|
||||
}
|
||||
void ModProblemItem::setMod(ModMetadata const& metadata) {
|
||||
this->clearState();
|
||||
|
||||
auto h = m_obContentSize.height;
|
||||
|
||||
auto logo = createServerModLogo(metadata.getID());
|
||||
limitNodeSize(logo, { h / 1.4f, h / 1.4f }, 5.f, .1f);
|
||||
this->addChildAtPosition(logo, Anchor::Left, ccp(h / 2, 0));
|
||||
|
||||
auto title = CCLabelBMFont::create(metadata.getName().c_str(), "bigFont.fnt");
|
||||
title->limitLabelWidth(m_obContentSize.width / 2, .35f, .1f);
|
||||
this->addChildAtPosition(title, Anchor::Left, ccp(h, h / 5), ccp(0, .5f));
|
||||
|
||||
auto versionLabel = CCLabelBMFont::create(
|
||||
metadata.getVersion().toVString().c_str(),
|
||||
"bigFont.fnt"
|
||||
);
|
||||
versionLabel->setColor("mod-list-version-label"_cc3b);
|
||||
versionLabel->limitLabelWidth(m_obContentSize.width / 2, .25f, .1f);
|
||||
this->addChildAtPosition(
|
||||
versionLabel, Anchor::Left,
|
||||
ccp(h + title->getScaledContentWidth() + 3, h / 5), ccp(0, .5f)
|
||||
);
|
||||
|
||||
auto developer = CCLabelBMFont::create(
|
||||
fmt::format("By {}", metadata.getDeveloper()).c_str(),
|
||||
"goldFont.fnt"
|
||||
);
|
||||
developer->limitLabelWidth(m_obContentSize.width / 2, .35f, .1f);
|
||||
this->addChildAtPosition(developer, Anchor::Left, ccp(h, -h / 5), ccp(0, .5f));
|
||||
}
|
||||
|
||||
ModProblemItem* ModProblemItem::create() {
|
||||
auto ret = new ModProblemItem();
|
||||
if (ret && ret->init()) {
|
||||
ret->setError("Unknown Type");
|
||||
ret->autorelease();
|
||||
return ret;
|
||||
}
|
||||
CC_SAFE_DELETE(ret);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ModProblemItem* ModProblemItem::parse(LoadProblem const& problem) {
|
||||
return ModProblemItem::create();
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <Geode/DefaultInclude.hpp>
|
||||
#include <Geode/loader/Loader.hpp>
|
||||
#include <server/Server.hpp>
|
||||
#include "../GeodeStyle.hpp"
|
||||
|
||||
using namespace geode::prelude;
|
||||
using VersionDownload = server::ServerRequest<server::ServerModVersion>;
|
||||
|
||||
class ModProblemItem : public CCNode {
|
||||
protected:
|
||||
CCMenu* m_menu;
|
||||
|
||||
bool init();
|
||||
|
||||
void clearState();
|
||||
void setLoading();
|
||||
void setError(std::string const& error);
|
||||
void setMod(ModMetadata const& metadata);
|
||||
|
||||
public:
|
||||
static ModProblemItem* create();
|
||||
static ModProblemItem* parse(LoadProblem const& problem);
|
||||
};
|
|
@ -1,33 +0,0 @@
|
|||
#include "ModProblemItemList.hpp"
|
||||
#include "ModProblemItem.hpp"
|
||||
|
||||
bool ModProblemItemList::init(float height) {
|
||||
if (!CCNode::init())
|
||||
return false;
|
||||
|
||||
this->setContentSize({ 250, height });
|
||||
|
||||
m_scrollLayer = ScrollLayer::create({ m_obContentSize.width, height });
|
||||
for (auto problem : Loader::get()->getProblems()) {
|
||||
m_scrollLayer->m_contentLayer->addChild(ModProblemItem::parse(problem));
|
||||
}
|
||||
m_scrollLayer->m_contentLayer->setLayout(
|
||||
ColumnLayout::create()
|
||||
->setAutoGrowAxis(height)
|
||||
->setAxisReverse(true)
|
||||
->setAxisAlignment(AxisAlignment::End)
|
||||
);
|
||||
this->addChildAtPosition(m_scrollLayer, Anchor::BottomLeft);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
ModProblemItemList* ModProblemItemList::create(float height) {
|
||||
auto ret = new ModProblemItemList();
|
||||
if (ret && ret->init(height)) {
|
||||
ret->autorelease();
|
||||
return ret;
|
||||
}
|
||||
CC_SAFE_DELETE(ret);
|
||||
return nullptr;
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <Geode/DefaultInclude.hpp>
|
||||
#include <Geode/ui/ScrollLayer.hpp>
|
||||
|
||||
using namespace geode::prelude;
|
||||
|
||||
class ModProblemItemList : public CCNode {
|
||||
protected:
|
||||
ScrollLayer* m_scrollLayer;
|
||||
|
||||
bool init(float height);
|
||||
|
||||
public:
|
||||
static ModProblemItemList* create(float height);
|
||||
};
|
94
loader/src/ui/mods/popups/ConfirmInstall.cpp
Normal file
94
loader/src/ui/mods/popups/ConfirmInstall.cpp
Normal file
|
@ -0,0 +1,94 @@
|
|||
#include "ConfirmInstall.hpp"
|
||||
#include <server/DownloadManager.hpp>
|
||||
|
||||
using namespace geode::prelude;
|
||||
using namespace server;
|
||||
|
||||
void askConfirmModInstalls() {
|
||||
struct ToConfirm final {
|
||||
size_t modCount = 0;
|
||||
size_t dependencyCount = 0;
|
||||
std::unordered_set<Mod*> toDisable;
|
||||
std::unordered_set<Mod*> toEnable;
|
||||
};
|
||||
|
||||
auto toConfirm = ToConfirm();
|
||||
|
||||
// Collect all things we need to ask confirmation for
|
||||
for (auto download : ModDownloadManager::get()->getDownloads()) {
|
||||
auto status = download.getStatus();
|
||||
if (auto conf = std::get_if<DownloadStatusConfirm>(&status)) {
|
||||
if (auto dep = download.getDependencyFor()) {
|
||||
toConfirm.dependencyCount += 1;
|
||||
}
|
||||
else {
|
||||
toConfirm.modCount += 1;
|
||||
|
||||
// Since the user has already explicitly chosen to download these mods, we
|
||||
// are going to assume they want these mods enabled over already installed
|
||||
// ones
|
||||
|
||||
// If this mod has incompatabilities that are installed, disable them
|
||||
for (auto inc : conf->version.metadata.getIncompatibilities()) {
|
||||
if (inc.mod && inc.mod->isOrWillBeEnabled()) {
|
||||
toConfirm.toDisable.insert(inc.mod);
|
||||
}
|
||||
}
|
||||
// If some installed mods are incompatible with this one, disable them
|
||||
for (auto mod : Loader::get()->getAllMods()) {
|
||||
for (auto inc : mod->getMetadata().getIncompatibilities()) {
|
||||
if (inc.id == conf->version.metadata.getID() && mod->isOrWillBeEnabled()) {
|
||||
toConfirm.toDisable.insert(mod);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If this mod has required dependencies that are disabled, enable them
|
||||
for (auto dep : conf->version.metadata.getDependencies()) {
|
||||
if (
|
||||
dep.importance == ModMetadata::Dependency::Importance::Required &&
|
||||
dep.mod && !dep.mod->isOrWillBeEnabled()
|
||||
) {
|
||||
toConfirm.toEnable.insert(dep.mod);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto joinModsToIDs = [](std::unordered_set<Mod*> const& mods) {
|
||||
return ranges::join(
|
||||
ranges::map<std::vector<std::string>>(
|
||||
mods, [](Mod* mod) { return fmt::format("<cp>{}</c>", mod->getID()); }
|
||||
),
|
||||
", "
|
||||
);
|
||||
};
|
||||
|
||||
createQuickPopup(
|
||||
"Confirm Install",
|
||||
fmt::format(
|
||||
"<cj>{}</c> mods will be installed, of which <cy>{}</c> are <cy>dependencies</c>.\n"
|
||||
"<cr>{} mods will be force-disabled, as they are incompatible</c>: {}\n"
|
||||
"<cg>{} mods will be force-enabled</c>: {}",
|
||||
toConfirm.modCount, toConfirm.dependencyCount,
|
||||
toConfirm.toDisable.size(), joinModsToIDs(toConfirm.toDisable),
|
||||
toConfirm.toEnable.size(), joinModsToIDs(toConfirm.toEnable)
|
||||
),
|
||||
"Cancel", "Continue",
|
||||
[toConfirm = std::move(toConfirm)](auto*, bool btn2) {
|
||||
if (btn2) {
|
||||
for (auto mod : toConfirm.toDisable) {
|
||||
(void)mod->disable();
|
||||
}
|
||||
for (auto mod : toConfirm.toEnable) {
|
||||
(void)mod->enable();
|
||||
}
|
||||
ModDownloadManager::get()->confirmAll();
|
||||
}
|
||||
else {
|
||||
ModDownloadManager::get()->cancelAll();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
10
loader/src/ui/mods/popups/ConfirmInstall.hpp
Normal file
10
loader/src/ui/mods/popups/ConfirmInstall.hpp
Normal file
|
@ -0,0 +1,10 @@
|
|||
#pragma once
|
||||
|
||||
class ConfirmInstall final {
|
||||
protected:
|
||||
|
||||
public:
|
||||
static void startConfirming();
|
||||
};
|
||||
void askConfirmModInstalls();
|
||||
|
|
@ -1,162 +0,0 @@
|
|||
#include "ConfirmInstallPopup.hpp"
|
||||
#include <Geode/ui/GeodeUI.hpp>
|
||||
|
||||
class SmallModItem : public CCNode {
|
||||
protected:
|
||||
bool init(ModMetadata const& metadata) {
|
||||
if (!CCNode::init())
|
||||
return false;
|
||||
|
||||
this->setContentSize({ 60, 80 });
|
||||
|
||||
auto logo = createServerModLogo(metadata.getID());
|
||||
limitNodeSize(logo, { 45, 45 }, 5.f, .1f);
|
||||
this->addChildAtPosition(logo, Anchor::Center, ccp(0, 10));
|
||||
|
||||
auto title = CCLabelBMFont::create(metadata.getName().c_str(), "bigFont.fnt");
|
||||
title->limitLabelWidth(m_obContentSize.width, .3f, .1f);
|
||||
this->addChildAtPosition(title, Anchor::Center, ccp(0, -20));
|
||||
|
||||
auto developer = CCLabelBMFont::create(fmt::format("by {}", metadata.getDeveloper()).c_str(), "goldFont.fnt");
|
||||
developer->limitLabelWidth(m_obContentSize.width, .3f, .1f);
|
||||
this->addChildAtPosition(developer, Anchor::Center, ccp(0, -30));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public:
|
||||
static SmallModItem* create(ModMetadata const& metadata) {
|
||||
auto ret = new SmallModItem();
|
||||
if (ret && ret->init(metadata)) {
|
||||
ret->autorelease();
|
||||
return ret;
|
||||
}
|
||||
CC_SAFE_DELETE(ret);
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
bool ConfirmInstallPopup::setup() {
|
||||
m_noElasticity = true;
|
||||
|
||||
this->setTitle("Customize Installation");
|
||||
|
||||
auto installationsTitle = CCLabelBMFont::create("You are Installing:", "bigFont.fnt");
|
||||
installationsTitle->setScale(.5f);
|
||||
m_mainLayer->addChildAtPosition(installationsTitle, Anchor::Center, ccp(0, 100));
|
||||
|
||||
m_installations = CCNode::create();
|
||||
m_installations->setAnchorPoint({ .5f, .5f });
|
||||
m_installations->setContentSize({ m_size.width, 60 });
|
||||
m_installations->setLayout(
|
||||
RowLayout::create()
|
||||
->setDefaultScaleLimits(.1f, .65f)
|
||||
->setGrowCrossAxis(true)
|
||||
->setCrossAxisOverflow(false)
|
||||
);
|
||||
m_mainLayer->addChildAtPosition(m_installations, Anchor::Center, ccp(0, 60));
|
||||
|
||||
auto dependenciesTitle = CCLabelBMFont::create("Which Depend(s) on:", "bigFont.fnt");
|
||||
dependenciesTitle->setScale(.5f);
|
||||
m_mainLayer->addChildAtPosition(dependenciesTitle, Anchor::Center, ccp(0, 20));
|
||||
|
||||
m_dependencies = CCNode::create();
|
||||
m_dependencies->setAnchorPoint({ .5f, .5f });
|
||||
m_dependencies->setContentSize({ m_size.width, 60 });
|
||||
m_dependencies->setLayout(
|
||||
RowLayout::create()
|
||||
->setDefaultScaleLimits(.1f, .65f)
|
||||
->setGrowCrossAxis(true)
|
||||
->setCrossAxisOverflow(false)
|
||||
);
|
||||
m_mainLayer->addChildAtPosition(m_dependencies, Anchor::Center, ccp(0, -20));
|
||||
|
||||
auto incompatablitiesTitle = CCLabelBMFont::create("But is/are Incompatible with:", "bigFont.fnt");
|
||||
incompatablitiesTitle->setScale(.5f);
|
||||
m_mainLayer->addChildAtPosition(incompatablitiesTitle, Anchor::Center, ccp(0, -60));
|
||||
|
||||
m_incompatabilities = CCNode::create();
|
||||
m_incompatabilities->setAnchorPoint({ .5f, .5f });
|
||||
m_incompatabilities->setContentSize({ m_size.width, 60 });
|
||||
m_incompatabilities->setLayout(
|
||||
RowLayout::create()
|
||||
->setDefaultScaleLimits(.1f, .65f)
|
||||
->setGrowCrossAxis(true)
|
||||
->setCrossAxisOverflow(false)
|
||||
);
|
||||
m_mainLayer->addChildAtPosition(m_incompatabilities, Anchor::Center, ccp(0, -100));
|
||||
|
||||
m_downloadListener.bind([this](auto) { this->updateState(); });
|
||||
|
||||
this->updateState();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ConfirmInstallPopup::updateState() {
|
||||
m_installations->removeAllChildren();
|
||||
m_dependencies->removeAllChildren();
|
||||
m_incompatabilities->removeAllChildren();
|
||||
|
||||
for (auto& download : server::ModDownloadManager::get()->getDownloads()) {
|
||||
auto status = download.getStatus();
|
||||
if (auto confirm = std::get_if<server::DownloadStatusConfirm>(&status)) {
|
||||
if (download.getDependencyFor()) {
|
||||
m_dependencies->addChild(SmallModItem::create(confirm->version.metadata));
|
||||
}
|
||||
else {
|
||||
m_installations->addChild(SmallModItem::create(confirm->version.metadata));
|
||||
}
|
||||
for (auto& inc : confirm->version.metadata.getIncompatibilities()) {
|
||||
if (inc.mod) {
|
||||
m_installations->addChild(SmallModItem::create(inc.mod->getMetadata()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_installations->updateLayout();
|
||||
m_dependencies->updateLayout();
|
||||
m_incompatabilities->updateLayout();
|
||||
}
|
||||
|
||||
ConfirmInstallPopup* ConfirmInstallPopup::create() {
|
||||
auto ret = new ConfirmInstallPopup();
|
||||
if (ret && ret->init(350, 280)) {
|
||||
ret->autorelease();
|
||||
return ret;
|
||||
}
|
||||
CC_SAFE_DELETE(ret);
|
||||
return nullptr;
|
||||
}
|
||||
void ConfirmInstallPopup::askForCustomize() {
|
||||
size_t confirmCount = 0;
|
||||
size_t dependencyCount = 0;
|
||||
for (auto& download : server::ModDownloadManager::get()->getDownloads()) {
|
||||
auto status = download.getStatus();
|
||||
if (auto confirm = std::get_if<server::DownloadStatusConfirm>(&status)) {
|
||||
confirmCount += 1;
|
||||
if (download.getDependencyFor()) {
|
||||
dependencyCount += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
createQuickPopup(
|
||||
"Confirm Install",
|
||||
fmt::format(
|
||||
"<cy>{} mods</c> will be installed, out of which <cr>{}</c> are <cr>dependencies</c>. "
|
||||
"Do you want to <cb>customize</c> the installation, or continue with default options?",
|
||||
confirmCount, dependencyCount
|
||||
),
|
||||
"Customize", "Continue",
|
||||
[](auto*, bool btn2) {
|
||||
if (btn2) {
|
||||
server::ModDownloadManager::get()->confirmAll();
|
||||
}
|
||||
else {
|
||||
ConfirmInstallPopup::create()->show();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <Geode/ui/Popup.hpp>
|
||||
#include <server/DownloadManager.hpp>
|
||||
#include "../GeodeStyle.hpp"
|
||||
|
||||
using namespace geode::prelude;
|
||||
|
||||
class ConfirmInstallPopup : public GeodePopup<> {
|
||||
protected:
|
||||
CCNode* m_installations;
|
||||
CCNode* m_dependencies;
|
||||
CCNode* m_incompatabilities;
|
||||
EventListener<server::ModDownloadFilter> m_downloadListener;
|
||||
|
||||
bool setup() override;
|
||||
|
||||
void updateState();
|
||||
|
||||
public:
|
||||
static ConfirmInstallPopup* create();
|
||||
static void askForCustomize();
|
||||
};
|
|
@ -9,7 +9,6 @@ class ConfirmUninstallPopup : public Popup<Mod*> {
|
|||
protected:
|
||||
Mod* m_mod;
|
||||
CCMenuItemToggler* m_deleteDataToggle;
|
||||
EventListener<UpdateModListStateFilter> m_updateStateListener;
|
||||
|
||||
bool setup(Mod* mod) override;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue