From 571d33fa9b8ed7866b7a698ca003d2cfbdb45434 Mon Sep 17 00:00:00 2001 From: HJfod <60038575+HJfod@users.noreply.github.com> Date: Mon, 12 Dec 2022 00:36:26 +0200 Subject: [PATCH] add filtering by developer (will rework later) - rn how it works is that it just filters the list when you click the dev name, although honestly this is kinda neat too --- loader/include/Geode/loader/Index.hpp | 6 ++++ loader/src/loader/Index.cpp | 14 ++++++++ loader/src/ui/internal/list/ModListCell.cpp | 36 +++++++++++++++---- loader/src/ui/internal/list/ModListCell.hpp | 5 +++ loader/src/ui/internal/list/ModListLayer.cpp | 11 +++++- loader/src/ui/internal/list/ModListLayer.hpp | 3 +- .../ui/internal/list/SearchFilterPopup.cpp | 16 ++++----- 7 files changed, 74 insertions(+), 17 deletions(-) diff --git a/loader/include/Geode/loader/Index.hpp b/loader/include/Geode/loader/Index.hpp index af703780..7ab3a995 100644 --- a/loader/include/Geode/loader/Index.hpp +++ b/loader/include/Geode/loader/Index.hpp @@ -128,6 +128,12 @@ namespace geode { * Get all featured index items */ std::vector<IndexItemHandle> getFeaturedItems() const; + /** + * Get all index items by a developer + */ + std::vector<IndexItemHandle> getItemsByDeveloper( + std::string const& name + ) const; /** * Check if an item with this ID is found on the index, and optionally * provide the version sought after diff --git a/loader/src/loader/Index.cpp b/loader/src/loader/Index.cpp index 609d418c..03a074c5 100644 --- a/loader/src/loader/Index.cpp +++ b/loader/src/loader/Index.cpp @@ -478,6 +478,20 @@ std::vector<IndexItemHandle> Index::getFeaturedItems() const { return res; } +std::vector<IndexItemHandle> Index::getItemsByDeveloper( + std::string const& name +) const { + std::vector<IndexItemHandle> res; + for (auto& items : map::values(m_items)) { + if (items.size()) { + if (items.rbegin()->second->info.developer == name) { + res.push_back(items.rbegin()->second); + } + } + } + return res; +} + bool Index::isKnownItem( std::string const& id, std::optional<VersionInfo> version diff --git a/loader/src/ui/internal/list/ModListCell.cpp b/loader/src/ui/internal/list/ModListCell.cpp index 8c98963a..0206b1b6 100644 --- a/loader/src/ui/internal/list/ModListCell.cpp +++ b/loader/src/ui/internal/list/ModListCell.cpp @@ -71,19 +71,26 @@ void ModListCell::setupInfo(ModInfo const& info, bool spaceForTags) { auto creatorStr = "by " + info.developer; auto creatorLabel = CCLabelBMFont::create(creatorStr.c_str(), "goldFont.fnt"); - creatorLabel->setAnchorPoint({ .0f, .5f }); creatorLabel->setScale(.43f); - creatorLabel->setPositionX(m_height / 2 + logoSize / 2 + 13.f); + + auto creatorBtn = CCMenuItemSpriteExtra::create( + creatorLabel, this, menu_selector(ModListCell::onViewDev) + ); + creatorBtn->setPositionX( + m_height / 2 + logoSize / 2 + 13.f + + creatorLabel->getScaledContentSize().width / 2 + - m_menu->getPositionX() + ); if (hasDesc && spaceForTags) { - creatorLabel->setPositionY(m_height / 2 + 7.5f); + creatorBtn->setPositionY(+7.5f); } else if (hasDesc || spaceForTags) { - creatorLabel->setPositionY(m_height / 2); + creatorBtn->setPositionY(0.f); } else { - creatorLabel->setPositionY(m_height / 2 - 7.f); + creatorBtn->setPositionY(-7.f); } - this->addChild(creatorLabel); + m_menu->addChild(creatorBtn); if (hasDesc) { auto descBG = CCScale9Sprite::create("square02b_001.png", { 0.0f, 0.0f, 80.0f, 80.0f }); @@ -109,6 +116,11 @@ void ModListCell::setupInfo(ModInfo const& info, bool spaceForTags) { } } +void ModListCell::onViewDev(CCObject*) { + m_layer->getQuery().developer = this->getDeveloper(); + m_layer->reloadList(); +} + bool ModListCell::init(ModListLayer* list, CCSize const& size) { m_width = size.width; m_height = size.height; @@ -244,6 +256,10 @@ bool ModCell::init( return true; } +std::string ModCell::getDeveloper() const { + return m_mod->getDeveloper(); +} + CCNode* ModCell::createLogo(CCSize const& size) { return geode::createModLogo(m_mod, size); } @@ -315,6 +331,10 @@ bool IndexItemCell::init( void IndexItemCell::updateState() {} +std::string IndexItemCell::getDeveloper() const { + return m_item->info.developer; +} + CCNode* IndexItemCell::createLogo(CCSize const& size) { return geode::createIndexItemLogo(m_item, size); } @@ -416,6 +436,10 @@ InvalidGeodeFileCell* InvalidGeodeFileCell::create( void InvalidGeodeFileCell::updateState() {} +std::string InvalidGeodeFileCell::getDeveloper() const { + return ""; +} + CCNode* InvalidGeodeFileCell::createLogo(CCSize const& size) { return nullptr; } diff --git a/loader/src/ui/internal/list/ModListCell.hpp b/loader/src/ui/internal/list/ModListCell.hpp index e96d06ba..bf521651 100644 --- a/loader/src/ui/internal/list/ModListCell.hpp +++ b/loader/src/ui/internal/list/ModListCell.hpp @@ -29,10 +29,12 @@ protected: void draw() override; float getLogoSize() const; + void onViewDev(CCObject*); public: virtual void updateState() = 0; virtual CCNode* createLogo(CCSize const& size) = 0; + virtual std::string getDeveloper() const = 0; }; /** @@ -61,6 +63,7 @@ public: void updateState() override; CCNode* createLogo(CCSize const& size) override; + std::string getDeveloper() const override; }; /** @@ -87,6 +90,7 @@ public: void updateState() override; CCNode* createLogo(CCSize const& size) override; + std::string getDeveloper() const override; }; /** @@ -114,4 +118,5 @@ public: void updateState() override; CCNode* createLogo(CCSize const& size) override; + std::string getDeveloper() const override; }; diff --git a/loader/src/ui/internal/list/ModListLayer.cpp b/loader/src/ui/internal/list/ModListLayer.cpp index 76619043..8fd2a642 100644 --- a/loader/src/ui/internal/list/ModListLayer.cpp +++ b/loader/src/ui/internal/list/ModListLayer.cpp @@ -487,7 +487,10 @@ void ModListLayer::reloadList(std::optional<ModListQuery> const& query) { // check if the user has searched something, // and show visual indicator if so - auto hasQuery = m_searchInput->getString() && strlen(m_searchInput->getString()); + auto hasQuery = + (m_searchInput->getString() && + strlen(m_searchInput->getString())) || + m_query.developer; m_searchBtn->setVisible(!hasQuery); m_searchClearBtn->setVisible(hasQuery); @@ -545,6 +548,10 @@ ModListDisplay ModListLayer::getDisplay() const { return m_display; } +ModListQuery& ModListLayer::getQuery() { + return m_query; +} + // Callbacks & Vtable impls void ModListLayer::onCheckForUpdates(CCObject*) { @@ -599,6 +606,8 @@ void ModListLayer::onOpenFolder(CCObject*) { } void ModListLayer::onResetSearch(CCObject*) { + // todo: remove when implementing more reasonable developer view + m_query.developer = std::nullopt; m_searchInput->setString(""); } diff --git a/loader/src/ui/internal/list/ModListLayer.hpp b/loader/src/ui/internal/list/ModListLayer.hpp index 505829c7..323ea6a3 100644 --- a/loader/src/ui/internal/list/ModListLayer.hpp +++ b/loader/src/ui/internal/list/ModListLayer.hpp @@ -82,14 +82,13 @@ protected: CCSize getCellSize() const; CCSize getListSize() const; - friend class SearchFilterPopup; - public: static ModListLayer* create(); static ModListLayer* scene(); void updateAllStates(ModListCell* except = nullptr); ModListDisplay getDisplay() const; + ModListQuery& getQuery(); void reloadList(std::optional<ModListQuery> const& query = std::nullopt); }; diff --git a/loader/src/ui/internal/list/SearchFilterPopup.cpp b/loader/src/ui/internal/list/SearchFilterPopup.cpp index 7000620a..4ca332be 100644 --- a/loader/src/ui/internal/list/SearchFilterPopup.cpp +++ b/loader/src/ui/internal/list/SearchFilterPopup.cpp @@ -55,7 +55,7 @@ bool SearchFilterPopup::setup(ModListLayer* layer, ModListType type) { this->addToggle( "Show Installed", menu_selector(SearchFilterPopup::onShowInstalled), - m_modLayer->m_query.forceVisibility, 0, pos + m_modLayer->getQuery().forceVisibility, 0, pos ); // tags @@ -79,7 +79,7 @@ bool SearchFilterPopup::setup(ModListLayer* layer, ModListType type) { auto toggle = CCMenuItemToggler::createWithStandardSprites( this, menu_selector(SearchFilterPopup::onTag), .5f ); - toggle->toggle(m_modLayer->m_query.tags.count(tag)); + toggle->toggle(m_modLayer->getQuery().tags.count(tag)); toggle->setPosition(pos - winSize / 2); toggle->setUserObject(CCString::create(tag)); m_buttonMenu->addChild(toggle); @@ -101,10 +101,10 @@ void SearchFilterPopup::onTag(CCObject* sender) { auto toggle = static_cast<CCMenuItemToggler*>(sender); auto tag = static_cast<CCString*>(toggle->getUserObject())->getCString(); if (!toggle->isToggled()) { - m_modLayer->m_query.tags.insert(tag); + m_modLayer->getQuery().tags.insert(tag); } else { - m_modLayer->m_query.tags.erase(tag); + m_modLayer->getQuery().tags.erase(tag); } } catch (...) { @@ -113,7 +113,7 @@ void SearchFilterPopup::onTag(CCObject* sender) { void SearchFilterPopup::onShowInstalled(CCObject* sender) { auto toggle = static_cast<CCMenuItemToggler*>(sender); - m_modLayer->m_query.forceVisibility = !toggle->isToggled(); + m_modLayer->getQuery().forceVisibility = !toggle->isToggled(); } void SearchFilterPopup::enable(CCMenuItemToggler* toggle, ModListType type) { @@ -141,17 +141,17 @@ CCMenuItemToggler* SearchFilterPopup::addPlatformToggle( ) { return this->addToggle( title, menu_selector(SearchFilterPopup::onPlatformToggle), - m_modLayer->m_query.platforms.count(id), id.to<int>(), pos + m_modLayer->getQuery().platforms.count(id), id.to<int>(), pos ); return nullptr; } void SearchFilterPopup::onPlatformToggle(CCObject* sender) { if (static_cast<CCMenuItemToggler*>(sender)->isToggled()) { - m_modLayer->m_query.platforms.erase(PlatformID::from(sender->getTag())); + m_modLayer->getQuery().platforms.erase(PlatformID::from(sender->getTag())); } else { - m_modLayer->m_query.platforms.insert(PlatformID::from(sender->getTag())); + m_modLayer->getQuery().platforms.insert(PlatformID::from(sender->getTag())); } }