add mod developer list popup

This commit is contained in:
HJfod 2024-05-06 12:50:54 +03:00
parent 991fce0d72
commit 0160249db3
7 changed files with 148 additions and 40 deletions

View file

@ -440,9 +440,21 @@ bool ModsLayer::init() {
this->updateState();
// The overall mods layer only cares about page number updates
m_updateStateListener.setFilter(UpdateModListStateFilter(UpdatePageNumberState()));
m_updateStateListener.bind([this](auto) { this->updateState(); });
// Listen for state changes
m_updateStateListener.setFilter(UpdateModListStateFilter(UpdateWholeState()));
m_updateStateListener.bind([this](UpdateModListStateEvent* event) {
if (auto whole = std::get_if<UpdateWholeState>(&event->target)) {
if (whole->searchByDeveloper) {
auto src = ServerModListSource::get(ServerModListType::Download);
src->getQueryMut()->developer = *whole->searchByDeveloper;
this->gotoTab(src);
m_showSearch = true;
m_lists.at(src)->activateSearch(m_showSearch);
}
}
this->updateState();
});
return true;
}

View file

@ -9,6 +9,9 @@ struct UpdatePageNumberState final {
bool operator==(UpdatePageNumberState const&) const = default;
};
struct UpdateWholeState final {
std::optional<std::string> searchByDeveloper;
UpdateWholeState() = default;
inline explicit UpdateWholeState(std::optional<std::string> const& dev) : searchByDeveloper(dev) {}
bool operator==(UpdateWholeState const&) const = default;
};
struct UpdateModState final {

View file

@ -3,6 +3,7 @@
#include <Geode/utils/ColorProvider.hpp>
#include "../GeodeStyle.hpp"
#include "../popups/ModPopup.hpp"
#include "../popups/DevPopup.hpp"
bool ModItem::init(ModSource&& source) {
if (!CCNode::init())
@ -56,7 +57,7 @@ bool ModItem::init(ModSource&& source) {
auto by = "By " + ModMetadata::formatDeveloperDisplayString(m_source.getMetadata().getDevelopers());
m_developerLabel = CCLabelBMFont::create(by.c_str(), "goldFont.fnt");
auto developersBtn = CCMenuItemSpriteExtra::create(
m_developerLabel, this, nullptr
m_developerLabel, this, menu_selector(ModItem::onDevelopers)
);
m_developers->addChild(developersBtn);
@ -390,7 +391,6 @@ void ModItem::onView(CCObject*) {
// Always open up the popup for the installed mod page if that is possible
ModPopup::create(m_source.convertForPopup())->show();
}
void ModItem::onViewError(CCObject*) {
if (auto mod = m_source.asMod()) {
std::vector<std::string> problems;
@ -404,7 +404,6 @@ void ModItem::onViewError(CCObject*) {
)->show();
}
}
void ModItem::onEnable(CCObject*) {
if (auto mod = m_source.asMod()) {
// Toggle the mod state
@ -421,10 +420,12 @@ void ModItem::onEnable(CCObject*) {
// Update state of the mod item
UpdateModListStateEvent(UpdateModState(m_source.getID())).post();
}
void ModItem::onInstall(CCObject*) {
server::ModDownloadManager::get()->startDownload(m_source.getID(), std::nullopt);
}
void ModItem::onDevelopers(CCObject*) {
DevListPopup::create(m_source.getMetadata())->show();
}
ModItem* ModItem::create(ModSource&& source) {
auto ret = new ModItem();

View file

@ -46,6 +46,7 @@ protected:
void onView(CCObject*);
void onViewError(CCObject*);
void onInstall(CCObject*);
void onDevelopers(CCObject*);
public:
static ModItem* create(ModSource&& source);

View file

@ -0,0 +1,64 @@
#include "DevPopup.hpp"
#include "../UpdateModListState.hpp"
bool DevListPopup::setup(ModMetadata const& meta) {
this->setTitle(fmt::format("Developers for {}", meta.getName()));
auto container = CCNode::create();
container->setAnchorPoint({ .5f, .5f });
container->setContentHeight(150);
for (auto dev : meta.getDevelopers()) {
auto menu = CCMenu::create();
menu->setContentWidth(90);
auto label = CCLabelBMFont::create(dev.c_str(), "bigFont.fnt");
label->setLayoutOptions(AxisLayoutOptions::create()->setScalePriority(1));
menu->addChild(label);
auto plus = CCSprite::createWithSpriteFrameName("GJ_plus2Btn_001.png");
plus->setScale(1.f);
auto btn = CCMenuItemSpriteExtra::create(
plus, this, menu_selector(DevListPopup::onMoreByThisDev)
);
btn->setUserObject(CCString::create(dev));
menu->addChild(btn);
menu->setLayout(
RowLayout::create()
->setDefaultScaleLimits(.1f, .5f)
);
container->addChild(menu);
}
container->setLayout(
ColumnLayout::create()
->setDefaultScaleLimits(.1f, 1.f)
);
m_mainLayer->addChildAtPosition(container, Anchor::Center, ccp(0, 0), ccp(.5f, .5f));
auto okSpr = createGeodeButton("OK");
okSpr->setScale(.7f);
auto okBtn = CCMenuItemSpriteExtra::create(
okSpr, this, menu_selector(DevListPopup::onClose)
);
m_buttonMenu->addChildAtPosition(okBtn, Anchor::Bottom, ccp(0, 20));
return true;
}
void DevListPopup::onMoreByThisDev(CCObject* sender) {
auto str = static_cast<CCString*>(static_cast<CCNode*>(sender)->getUserObject());
UpdateModListStateEvent(UpdateWholeState(str->getCString())).post();
this->onClose(nullptr);
}
DevListPopup* DevListPopup::create(ModMetadata const& meta) {
auto ret = new DevListPopup();
if (ret && ret->init(200, 180, meta)) {
ret->autorelease();
return ret;
}
CC_SAFE_DELETE(ret);
return nullptr;
}

View file

@ -0,0 +1,15 @@
#pragma once
#include "../GeodeStyle.hpp"
#include "../sources/ModSource.hpp"
#include <server/Server.hpp>
class DevListPopup : public GeodePopup<ModMetadata const&> {
protected:
bool setup(ModMetadata const& src);
void onMoreByThisDev(CCObject* sender);
public:
static DevListPopup* create(ModMetadata const& src);
};

View file

@ -1,4 +1,5 @@
#include "FiltersPopup.hpp"
#include <Geode/ui/TextInput.hpp>
bool FiltersPopup::setup(ModListSource* src) {
m_noElasticity = true;
@ -54,21 +55,22 @@ bool FiltersPopup::setup(ModListSource* src) {
m_mainLayer->addChildAtPosition(tagsContainer, Anchor::Top, ccp(0, -85));
auto optionsContainer = CCNode::create();
optionsContainer->setContentSize(ccp(160, 35));
optionsContainer->setAnchorPoint({ .5f, .5f });
optionsContainer->setVisible(false);
auto optionsBG = CCScale9Sprite::create("square02b_001.png");
optionsBG->setColor({ 0, 0, 0 });
optionsBG->setOpacity(75);
optionsBG->setScale(.3f);
optionsBG->setContentSize(optionsContainer->getContentSize() / optionsBG->getScale());
optionsContainer->addChildAtPosition(optionsBG, Anchor::Center);
auto optionsMenu = CCMenu::create();
optionsMenu->setContentSize(optionsContainer->getContentSize() - ccp(10, 10));
if (typeinfo_cast<InstalledModListSource*>(m_source)) {
auto optionsContainer = CCNode::create();
optionsContainer->setContentSize(ccp(160, 35));
optionsContainer->setAnchorPoint({ .5f, .5f });
auto optionsBG = CCScale9Sprite::create("square02b_001.png");
optionsBG->setColor({ 0, 0, 0 });
optionsBG->setOpacity(75);
optionsBG->setScale(.3f);
optionsBG->setContentSize(optionsContainer->getContentSize() / optionsBG->getScale());
optionsContainer->addChildAtPosition(optionsBG, Anchor::Center);
auto optionsMenu = CCMenu::create();
optionsMenu->setContentSize(optionsContainer->getContentSize() - ccp(10, 10));
auto enabledOnlyToggle = CCMenuItemToggler::createWithStandardSprites(
this, menu_selector(FiltersPopup::onToggle), .6f
);
@ -85,25 +87,35 @@ bool FiltersPopup::setup(ModListSource* src) {
enabledOnlyLabel->setScale(.35f);
optionsMenu->addChildAtPosition(enabledOnlyLabel, Anchor::Left, ccp(30, 0), ccp(0, .5f));
optionsContainer->addChildAtPosition(optionsMenu, Anchor::Center);
auto optionsTitleMenu = CCMenu::create();
optionsTitleMenu->setAnchorPoint({ .5f, 0 });
optionsTitleMenu->setContentWidth(optionsContainer->getContentWidth());
auto optionsTitle = CCLabelBMFont::create("Options", "bigFont.fnt");
optionsTitleMenu->addChild(optionsTitle);
optionsTitleMenu->addChild(SpacerNode::create());
optionsTitleMenu->setLayout(
RowLayout::create()
->setDefaultScaleLimits(.1f, .4f)
);
optionsContainer->addChildAtPosition(optionsTitleMenu, Anchor::Top, ccp(0, 4));
m_mainLayer->addChildAtPosition(optionsContainer, Anchor::Bottom, ccp(0, 60), ccp(.5f, .5f));
optionsContainer->setVisible(true);
}
else if (typeinfo_cast<ServerModListSource*>(m_source)) {
auto input = TextInput::create(100, "Developer");
input->setTextAlign(TextInputAlign::Left);
input->setLabel("Developer Name");
optionsMenu->addChildAtPosition(input, Anchor::Left, ccp(15, 0));
optionsContainer->setVisible(true);
}
optionsContainer->addChildAtPosition(optionsMenu, Anchor::Center);
auto optionsTitleMenu = CCMenu::create();
optionsTitleMenu->setAnchorPoint({ .5f, 0 });
optionsTitleMenu->setContentWidth(optionsContainer->getContentWidth());
auto optionsTitle = CCLabelBMFont::create("Options", "bigFont.fnt");
optionsTitleMenu->addChild(optionsTitle);
optionsTitleMenu->addChild(SpacerNode::create());
optionsTitleMenu->setLayout(
RowLayout::create()
->setDefaultScaleLimits(.1f, .4f)
);
optionsContainer->addChildAtPosition(optionsTitleMenu, Anchor::Top, ccp(0, 4));
m_mainLayer->addChildAtPosition(optionsContainer, Anchor::Bottom, ccp(0, 60), ccp(.5f, .5f));
auto okSpr = createGeodeButton("OK");
okSpr->setScale(.7f);
@ -182,7 +194,7 @@ void FiltersPopup::onClose(CCObject* sender) {
FiltersPopup* FiltersPopup::create(ModListSource* src) {
auto ret = new FiltersPopup();
float height = 170;
if (typeinfo_cast<InstalledModListSource*>(src)) {
if (typeinfo_cast<InstalledModListSource*>(src) || typeinfo_cast<ServerModListSource*>(src)) {
height = 230;
}
if (ret && ret->init(350, height, src)) {